在自定义目标中计算的编译器附加选项

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:

  1. 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.
  2. Evaluate properties and process imports as encountered
  3. Evaluate item definitions
  4. Evaluate items
  5. Evaluate using tasks
  6. Start build and reading targets

因此,在您的情况下,在执行 GetBranchName_TARGET 之前,已对 ClCompileItemDefinitionGroup 进行了评估。所以,它是设计为空的。

为了实现所需的行为,您应该添加以下内容:

<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.

的功能