MsBuild问题:如何在ClCompile中正确使用Exec任务的输出?
问题原因
你的props文件里,ItemDefinitionGroup中的预处理器定义是在项目初始化阶段就被解析的,而GetGitRevision目标要等到编译前才会执行并给GitRevision属性赋值。这就导致初始化阶段解析GIT_REVISION="$(GitRevision)"时,$(GitRevision)还没有值,最终C++代码里的宏就是空的。
解决方案
最直接可靠的修复方式是把修改预处理器定义的逻辑移到GetGitRevision目标内部,这样就能确保在GitRevision属性被赋值后,再去设置预处理器宏:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Target Name="GetGitRevision" BeforeTargets="ClCompile"> <Exec Command="git rev-parse --verify --short HEAD" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="GitRevision"/> </Exec> <!-- 在目标内部动态修改预处理器定义 --> <ItemGroup> <ClCompile> <PreprocessorDefinitions>GIT_REVISION="$(GitRevision)";%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> </ItemGroup> </Target> </Project>
另外还有一种可选方案是启用延迟属性扩展,让预处理器定义的解析延迟到GitRevision被赋值之后:
<?xml version="1.0" encoding="utf-8"?> <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <PropertyGroup> <!-- 开启延迟属性评估 --> <EnablePropertyEvaluation>true</EnablePropertyEvaluation> </PropertyGroup> <Target Name="GetGitRevision" BeforeTargets="ClCompile"> <Exec Command="git rev-parse --verify --short HEAD" ConsoleToMSBuild="true"> <Output TaskParameter="ConsoleOutput" PropertyName="GitRevision"/> </Exec> </Target> <ItemDefinitionGroup> <ClCompile> <!-- 使用Unescape确保值被正确解析 --> <PreprocessorDefinitions>GIT_REVISION="$([MSBuild]::Unescape($(GitRevision)))";%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> </ItemDefinitionGroup> </Project>
第一种方案更直观,也不容易出现其他潜在问题,推荐优先使用。
内容的提问来源于stack exchange,提问作者antonpp
相关产品推荐
相关产品推荐

