使用自定义任务覆盖项目属性

时间:2019-09-20 14:44:20

标签: visual-c++ msbuild

我们的C ++项目使用MSBuild在Windows上构建,并在* nix上构建GNU make。我正在尝试在MSBuild中重新创建以下GNU make单行的功能:

GENN_PATH:=$(abspath $(dir $(shell which genn-buildmodel.sh))../userproject/include)

本质上是将变量设置为相对于路径中的可执行文件的路径。但是,事实证明这是在MSBuild中实现的战斗...

以下是我vcxproj的(希望)相关部分。为了进行测试,我首先将要覆盖的变量设置为显而易见的值:

<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
  <PropertyGroup Label="Configuration">
    ...
    <GeNNUserProject>UNDEFINED</GeNNUserProject>
  </PropertyGroup>

然后,在我的ClCompile项目定义中,我将此属性的值添加到其他包含目录中

  <ItemDefinitionGroup>
    <ClCompile>
      ...
      <AdditionalIncludeDirectories>include;$(GeNNUserProject)</AdditionalIncludeDirectories>
    </ClCompile>
    ...
  </ItemDefinitionGroup>

为了找到此路径,我使用where命令并将其输出重定向到属性。然后,从这里,我找到include目录并将其打印出来-可行!

  <Target Name="FindUserProjects">
    <Exec Command="where genn-buildmodel.bat" ConsoleToMsBuild="true">
      <Output TaskParameter="ConsoleOutput" PropertyName="GeNNBuildModelPath" />
    </Exec>
    <PropertyGroup>
        <GeNNUserProject>$([System.IO.Path]::GetFullPath($([System.IO.Path]::GetDirectoryName($(GeNNBuildModelPath)))\..\userproject\include))</GeNNUserProject>
    </PropertyGroup>
    <Message Text="MAGIC GENN-FINDING! $(GeNNBuildModelPath) -> $(GeNNUserProject)"/>
  </Target>

我尝试了多种方法使其成为ClCompile的依赖项,包括将Target设置为BeforeTargets="PrepareForBuild"以及以下内容:

  <PropertyGroup>
    <BeforeClCompileTargets>
        FindUserProjects;
        $(BeforeClCompileTargets);
    </BeforeClCompileTargets>
  </PropertyGroup>  
</Project>

无论我做什么,我的自定义目标都会运行,但不会覆盖该属性。 Google建议,如果属性在优先级中被覆盖,则应该从目标以及挖掘到Microsoft.CPP * .targets中可见它们,这就是BeforeClCompileTargets的设置。

1 个答案:

答案 0 :(得分:0)

这里的问题不是目标没有设置属性,而是从原始值设置了AdditionalIncludeDirectories项目元数据。解决方案是直接从目标设置它:

<ItemGroup>
      <ClCompile>
       <AdditionalIncludeDirectories>%(AdditionalIncludeDirectories);$([System.IO.Path]::GetFullPath($([System.IO.Path]::GetDirectoryName($(GeNNBuildModelPath)))\..\userproject\include))</AdditionalIncludeDirectories>
      </ClCompile>
    </ItemGroup>