在自定义目标中计算的编译器附加选项
Compiler Additional Options computed in a custom Target
我有一个 msbuild 自定义目标和一个计算值的任务。
任务会将值输出为 属性。
这个 属性 我想用作编译器调用的附加选项。
但是 属性 用作附加选项时是空的。
我的 *.targets 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="GetBranchName_TASK" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<sPath ParameterType="System.String" Required="true" />
<sBranchName ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
... some Code ...
]]>
</Code>
</Task>
</UsingTask>
<Target Name="GetBranchName_TARGET">
<GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)">
<Output PropertyName="BranchName" TaskParameter="sBranchName" />
</GetBranchName_TASK>
<Message Importance="High" Text="BranchName = $(BranchName)" />
</Target>
<PropertyGroup>
<BuildDependsOn>
GetBranchName_TARGET;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
</Project>
我的*.props文件是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
... some Properties here ...
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="IRSGetBranchName.targets" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions>
<ClCompile>
<ItemDefinitionGroup>
</Project>
这个.props文件然后导入几个.vcxproj
在我的 GetBranchName_TARGET 中作为消息打印的值如预期的那样正确(显示正确的 TFS 分支名称)。
但是在查看 详细构建输出 时,值似乎是空的:
1>ClCompile
1> ..\FOO.cpp
1> AdditionalOptions = /DBRANCHNAME= /DMORE=BAR
我试了几个小时但没有找到解决办法,我真的希望有人能帮助这里出了什么问题...
a) 属性 BranchName 是否在全球范围内不可用?我尝试从其他自定义目标打印 属性,效果很好!
b) 还是我的Target执行前的ClCompile.AdditionalOptions evaluated/build?这种情况我该如何重新评估?
c) ...
非常感谢任何输入。
您应该熟悉 msbuild 评估过程,如所述here:
When the MSBuild engine begins to process a build file, it is evaluated in a top-down fashion in a multi-pass manner. These passes are described in order in the following list:
- Load all environment and global properties, and toolset properties. In Microsoft Visual Studio 2010, for example, C++ defines several properties in the MSBuild 4.0 toolset.
- Evaluate properties and process imports as encountered
- Evaluate item definitions
- Evaluate items
- Evaluate using tasks
- Start build and reading targets
因此,在您的情况下,在执行 GetBranchName_TARGET 之前,已对 ClCompile
的 ItemDefinitionGroup
进行了评估。所以,它是设计为空的。
为了实现所需的行为,您应该添加以下内容:
<Target Name="GetBranchName_TARGET">
<GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)">
<Output PropertyName="BranchName" TaskParameter="sBranchName" />
</GetBranchName_TASK>
<Message Importance="High" Text="BranchName = $(BranchName)" />
<ItemGroup>
<ClCompile>
<AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions>
</ClCompile>
</ItemGroup>
</Target>
例如,您可以在 ClCompile 中使用 Condition
属性以仅包含您的源代码。实际上,您正在寻找的是修改 item metadata after it was declared.
的功能
我有一个 msbuild 自定义目标和一个计算值的任务。 任务会将值输出为 属性。 这个 属性 我想用作编译器调用的附加选项。
但是 属性 用作附加选项时是空的。
我的 *.targets 文件如下所示:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask TaskName="GetBranchName_TASK" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
<ParameterGroup>
<sPath ParameterType="System.String" Required="true" />
<sBranchName ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
... some Code ...
]]>
</Code>
</Task>
</UsingTask>
<Target Name="GetBranchName_TARGET">
<GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)">
<Output PropertyName="BranchName" TaskParameter="sBranchName" />
</GetBranchName_TASK>
<Message Importance="High" Text="BranchName = $(BranchName)" />
</Target>
<PropertyGroup>
<BuildDependsOn>
GetBranchName_TARGET;
$(BuildDependsOn);
</BuildDependsOn>
</PropertyGroup>
</Project>
我的*.props文件是这样的:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Configuration">
... some Properties here ...
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="IRSGetBranchName.targets" />
<ItemDefinitionGroup>
<ClCompile>
<AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions>
<ClCompile>
<ItemDefinitionGroup>
</Project>
这个.props文件然后导入几个.vcxproj
在我的 GetBranchName_TARGET 中作为消息打印的值如预期的那样正确(显示正确的 TFS 分支名称)。 但是在查看 详细构建输出 时,值似乎是空的:
1>ClCompile
1> ..\FOO.cpp
1> AdditionalOptions = /DBRANCHNAME= /DMORE=BAR
我试了几个小时但没有找到解决办法,我真的希望有人能帮助这里出了什么问题...
a) 属性 BranchName 是否在全球范围内不可用?我尝试从其他自定义目标打印 属性,效果很好!
b) 还是我的Target执行前的ClCompile.AdditionalOptions evaluated/build?这种情况我该如何重新评估?
c) ...
非常感谢任何输入。
您应该熟悉 msbuild 评估过程,如所述here:
When the MSBuild engine begins to process a build file, it is evaluated in a top-down fashion in a multi-pass manner. These passes are described in order in the following list:
- Load all environment and global properties, and toolset properties. In Microsoft Visual Studio 2010, for example, C++ defines several properties in the MSBuild 4.0 toolset.
- Evaluate properties and process imports as encountered
- Evaluate item definitions
- Evaluate items
- Evaluate using tasks
- Start build and reading targets
因此,在您的情况下,在执行 GetBranchName_TARGET 之前,已对 ClCompile
的 ItemDefinitionGroup
进行了评估。所以,它是设计为空的。
为了实现所需的行为,您应该添加以下内容:
<Target Name="GetBranchName_TARGET">
<GetBranchName_TASK sPath="$(MSBuildThisFileDirectory)">
<Output PropertyName="BranchName" TaskParameter="sBranchName" />
</GetBranchName_TASK>
<Message Importance="High" Text="BranchName = $(BranchName)" />
<ItemGroup>
<ClCompile>
<AdditionalOptions>/DBRANCHNAME=$(BranchName) /DMORE=BAR</AdditionalOptions>
</ClCompile>
</ItemGroup>
</Target>
例如,您可以在 ClCompile 中使用 Condition
属性以仅包含您的源代码。实际上,您正在寻找的是修改 item metadata after it was declared.