基于导入属性的MSBuild条件

3

我有一个解决方案,其中包含多个项目,我希望它们都能够访问一组在解决方案级别上定义的共享属性。

使用下面的代码,这基本上可以正常工作,并且我可以在BeforeBuild目标中使用导入的属性,但是我的问题是我无法在条件中使用导入的属性。

所以我在解决方案文件夹中的CommonSettings.targets文件中有以下内容:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="CommonSettingsTarget">
        <PropertyGroup>
            <MyCustomProperty>Sample</MyCustomProperty>
        </PropertyGroup>
    </Target>
</Project>

在我的项目文件中,我有:

<Project ToolsVersion="14.0" DefaultTargets="Build" InitialTargets="CommonSettingsTarget" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Import Project="$(SolutionDir)CommonSettings.targets" />

  <ItemGroup>
    <EmbeddedResource Include="EmbeddedDocument.txt" Condition=" '$(MyCustomProperty)' == 'Sample' " />
  </ItemGroup>

  <Target Name="BeforeBuild">
    <Message Text="MyCustomProperty='$(MyCustomProperty)'" Importance="high" />
  </Target>
</Project>

在上述代码中,我可以看到“MyCustomProperty='Sample'”被显示在输出窗口中,这很好。但是,当它作为条件的一部分(用于可选地包含嵌入式资源)时,该条件从未得到满足。
有没有办法让导入的属性与条件一起使用?

1
另一个建议:如果您切换到VS 2017 / MSbuild 15,您可以简单地将导入的文件命名为“Directory.Build.props”,它将自动导入到该级别以下的所有项目中。 - Martin Ullrich
1个回答

3
由于您的ItemGroup不在目标之内,但PropertyGroup在目标之内,所以当评估条件时,CommonSettingsTarget尚未执行,因此MyCustomProperty尚未定义。 Message任务是从BeforeBuild目标中调用的,该目标依赖于CommonSettingsTarget,因此在创建消息时已经定义了MyCustomProperty
Import视为将导入的项目复制到您的项目文件中。 结果类似于:
<Project ToolsVersion="14.0" DefaultTargets="Build" InitialTargets="CommonSettingsTarget" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Target Name="CommonSettingsTarget">
     <PropertyGroup>
       <MyCustomProperty>Sample</MyCustomProperty>
     </PropertyGroup>
   </Target>

  <ItemGroup>
    <EmbeddedResource Include="EmbeddedDocument.txt" Condition=" '$(MyCustomProperty)' == 'Sample' " />
  </ItemGroup>

  <Target Name="BeforeBuild">
    <Message Text="MyCustomProperty='$(MyCustomProperty)'" Importance="high" />
  </Target>
</Project>

这是发生的事情:
1. 您定义了一个目标CommonSettingsTarget,当它被执行时将定义MyCustomProperty。现在还没有定义。
2. 您定义了ItemGroup并评估条件。它返回false,因为MyCustomProperty尚未定义。
3. 您定义了一个目标BeforeBuild
4. 您运行初始目标,即CommonSettingsTarget。现在MyCustomProperty已经被定义了。
5. 您运行默认目标,该目标依赖于BeforeBuild,因此运行BeforeBuild。在那里,您评估已在步骤4中定义的MyCustomProperty
作为解决方案,请删除CommonSettingsTarget目标,并将PropertyGroup定义为CommonSettings.targetsProject的子级:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <MyCustomProperty>Sample</MyCustomProperty>
    </PropertyGroup>
</Project>

在您的项目文件中,您应该删除 InitialTargets="CommonSettingsTarget"

感谢您提供的信息wkl。如果我在项目中明确定义属性,它确实可以工作,但是我的解决方案中有很多项目都需要访问这些属性,每次需要调整它们时都需要更改每个项目中的值。我认为项目本身的InitialTargets可能会做到这一点,但看起来条件总是在任何导入之前评估? - Daniel Smith
我现在明白你的意思了wkl。现在它完美地导入和使用我的公共属性。我肯定是用所有那些目标过于复杂化了它。非常感谢你 - 我会将其标记为答案 :-) - Daniel Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接