Max*_*oro 6 msbuild csproj visual-studio
我有一个增量构建设置,如下所示:
<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>
Run Code Online (Sandbox Code Playgroud)
目标生成一个$(MyOutput)需要在当前项目中包含和编译的单个 .cs 文件。请注意,在目标中我首先删除然后包含此文件。
$(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>
Run Code Online (Sandbox Code Playgroud)
在命令行上运行 msbuild /v:d 的结果是(仅显示 MyCodeGen Target 的输出):
第一次运行的输出(Generate.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".
Run Code Online (Sandbox Code Playgroud)
第二次/第三次/...运行的输出:
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".
Run Code Online (Sandbox Code Playgroud)
修改in.txt后构建的输出:
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".
Run Code Online (Sandbox Code Playgroud)
此后运行的输出:
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".
Run Code Online (Sandbox Code Playgroud)
如果这对您不起作用,则可能是您用来生成文件的进程无法与 msbuild 配合良好,因为它无法正确更新时间戳。例如,仅复制比项目文件更旧的现有文件将导致 generated.cs 的时间戳早于 $(MSBuildThisFileFullPath) 输入,因此目标将始终运行。
| 归档时间: |
|
| 查看次数: |
612 次 |
| 最近记录: |