我有一个增量build设置,如下所示:
<ItemGroup>
<MyInput Include="$(MyInput)" />
<UpToDateCheckInput Include="@(MyInput)" />
<UpToDateCheckBuilt Include="$(MyOutput)" />
</ItemGroup>
<Target Name="MyCodeGen"
BeforeTargets="PreBuildEvent"
DependsOnTargets="ResolveReferences"
Inputs="@(MyInput);$(MSBuildThisFileFullPath);$(MyCodegenExe)"
Outputs="$(MyOutput)">
<Exec Command="$(MyCodegenExe) $(MyCodegenParams)" />
<ItemGroup>
<Compile Remove="$(MyOutput)" />
<Compile Include="$(MyOutput)" />
</ItemGroup>
</Target>
目标生成单个 .cs 文件 $(MyOutput)
需要在当前项目中包含和编译。请注意在目标中我首先删除然后包含此文件。$(MyOutput)
“自上次最新检查以来已被修改”。 如何在第二次构建中获得“一切都是最新的”结果?
最佳答案
无条件地包含文件应该可以工作。例如,在 Microsoft.CSharp.targets 导入之后的默认 C# 项目模板中使用这些行:
<ItemGroup>
<MyInput Include="in.txt" />
</ItemGroup>
<PropertyGroup>
<MyOutput>Generated.cs</MyOutput>
</PropertyGroup>
<Target Name="MyCodeGen" BeforeTargets="PreBuildEvent" DependsOnTargets="ResolveReferences"
Inputs="@(MyInput);$(MSBuildThisFileFullPath)"
Outputs="$(MyOutput)">
<ReadLinesFromFile File="@(MyInput)">
<Output TaskParameter="Lines" ItemName="MyInputlines"/>
</ReadLinesFromFile>
<Message Text="CODEGEN lines @(MyInputlines)" />
<WriteLinesToFile File="$(MyOutput)" Lines="@(MyInputlines)" Overwrite="True" />
</Target>
<ItemGroup>
<Compile Include="$(MyOutput)"/>
</ItemGroup>
在命令行上运行 msbuild/v:d 的结果是(仅显示 MyCodeGen Target 的输出):第一次运行的输出(Generated.cs 还不存在):
Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Building target "MyCodeGen" completely.
Output file "Generated.cs" does not exist.
Using "ReadLinesFromFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "ReadLinesFromFile"
Done executing task "ReadLinesFromFile".
Task "Message"
CODEGEN lines using System;
Done executing task "Message".
Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "WriteLinesToFile"
Done executing task "WriteLinesToFile".
Done building target "MyCodeGen" in project "my.csproj".
第二/第三/...运行的输出:Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Skipping target "MyCodeGen" because all output files are up-to-date with respect to the input files.
Input files: in.txt;my.csproj
Output files: Generated.cs
Done building target "MyCodeGen" in project "my.csproj".
修改in.txt后build的输出:Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Building target "MyCodeGen" completely.
Input file "in.txt" is newer than output file "Generated.cs".
Using "ReadLinesFromFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "ReadLinesFromFile"
Done executing task "ReadLinesFromFile".
Task "Message"
CODEGEN lines using System.Linq;
Done executing task "Message".
Using "WriteLinesToFile" task from assembly "Microsoft.Build.Tasks.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a".
Task "WriteLinesToFile"
Done executing task "WriteLinesToFile".
Done building target "MyCodeGen" in project "my.csproj".
在此之后运行的输出:Target "MyCodeGen" in project "my.csproj" (target "PreBuildEvent" depends on it):
Skipping target "MyCodeGen" because all output files are up-to-date with respect to the input files.
Input files: in.txt;my.csproj
Output files: Generated.cs
Done building target "MyCodeGen" in project "my.csproj".
如果这对您不起作用,则可能是例如您用来生成文件的过程与 msbuild 不能很好地配合,因为它没有正确更新时间戳。例如。仅复制比项目文件旧的现有文件将导致 Generated.cs 的时间戳比 $(MSBuildThisFileFullPath) 输入旧,因此目标将始终运行。
关于visual-studio - 包含编译文件(增量构建),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69397117/