msbuild Directory.build.props 每个项目级联?

Sam*_*uel 3 msbuild

执行摘要:我想根据仅在构建管道后期出现的条件来设置属性组中的属性,并且正在寻找一种方法来更早地解决此问题。

\n\n

我有一个相当简单的Directory.build.props文件

\n\n
<Project>\n\n  <PropertyGroup>\n    <MyMode>Default</MyMode>\n  </PropertyGroup>\n\n  <!-- This one overrides the default group above -->\n  <PropertyGroup Condition=" \'$(Configuration)\' == \'Debug\' ">\n    <MyMode>Changed to Debug</MyMode>\n  </PropertyGroup>\n\n  <!-- This one is not applied -->\n  <PropertyGroup Condition=" \'$(TargetFrameworkVersion)\' == \'v4.7.2\' ">\n    <MyMode>Framework</MyMode>\n  </PropertyGroup>\n\n\n  <Target Name="Stats" AfterTargets="Build">\n    <Message Importance="High" Text="::::: Mode set to $(MyMode)" />\n    <Message Importance="High" Text="::::: Target Framework set to $(TargetFrameworkVersion)" />\n  </Target>\n\n</Project>\n
Run Code Online (Sandbox Code Playgroud)\n\n

和一个简单的项目结构

\n\n
E:.\n\xe2\x94\x82   Directory.build.props\n\xe2\x94\x82   MSBuild_Test.sln\n\xe2\x94\x82\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80ConsoleAppNet\n\xe2\x94\x82       App.config\n\xe2\x94\x82       ConsoleAppNet.csproj\n\xe2\x94\x82       Program.cs\n\xe2\x94\x82\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80MSBuild_Test\n        Class1.cs\n        LibStandard.csproj\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

LibStandard是一个 .net 标准库,ConsoleAppNet是一个 .net 框架项目,它还具有构建依赖性LibStandard

\n\n

当我执行上面的 msbuild 脚本时,我得到这个输出

\n\n
  LibStandard -> E:\\temp\\MSBuild_Test\\MSBuild_Test\\bin\\Debug\\netstandard2.0\\LibStandard.dll\n  ::::: Mode set to Changed to Debug\n  ::::: Target Framework set to v2.0\n  ConsoleAppNet -> E:\\temp\\MSBuild_Test\\ConsoleAppNet\\bin\\Debug\\ConsoleAppNet.exe\n  ::::: Mode set to Changed to Debug\n  ::::: Target Framework set to v4.7.2\n
Run Code Online (Sandbox Code Playgroud)\n\n

正如您所看到的,控制台输出应该触发属性组,其条件为MyModeis Framework,但它没有成功。这个从未匹配过:

\n\n
  <PropertyGroup Condition=" \'$(TargetFrameworkVersion)\' == \'v4.7.2\' ">\n    <MyMode>Framework</MyMode>\n  </PropertyGroup>\n
Run Code Online (Sandbox Code Playgroud)\n\n

PropertyGroups根据以上情况,有没有什么好的方法可以在负载时应用呢?

\n\n

我知道我可以将 PropertyGroup 覆盖放置在目标中,例如:

\n\n
  <Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" \'$(TargetFrameworkVersion\' == \'v4.7.2\' ">\n    <PropertyGroup >\n      <MyMode>Framework</MyMode>\n    </PropertyGroup>\n  </Target>\n
Run Code Online (Sandbox Code Playgroud)\n\n

它也能正确执行,但此时我无法设置重要的其他变量。

\n\n

我的目的是根据不同的条件重定向输出目录。当我设定$(OutputPath)目标时,已经太晚了。该项目在该项目的整个构建过程中忽略此输出:

\n\n
  <Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" \'$(TargetFrameworkVersion)\' == \'v4.7.2\' ">\n    <PropertyGroup >\n      <OutputPath>New_Output_Directory</OutputPath>\n    </PropertyGroup>\n  </Target>\n
Run Code Online (Sandbox Code Playgroud)\n\n

我什至可以回显该OutputPath变量,它指向正确的值,但构建使用旧值而不重定向输出。

\n

Sam*_*uel 5

高五我,我找到了所有即将到来的塞缪尔询问同一问题的解决方案。

快速回答

导入时,Directory.build.props尚未导入其他属性(例如 TargetFramework),并且默认。这就是对它们的检查失败的原因。Directory.build.targets代替使用!

  • Directory.build.props很早就导入,允许您在一开始就设置属性
  • Directory.build.targets导入得很,允许您自定义构建链

资源

以下是一些关于 msbuild 的非常有用的页面

解释

这是自定义页面上段落的引用(只要当前文档有效......)

进口订单

Directory.Build.props很早就导入到 Microsoft.Common.props 中,稍后定义的属性对其不可用。因此,请避免引用尚未定义的属性(并将评估为空)。

从 NuGet 包导入 .targets 文件后,从 Microsoft.Common.targets 导入Directory.Build.targets 。因此,它可以覆盖大多数构建逻辑中定义的属性和目标,但有时您可能需要在最终导入后自定义项目文件。

通过阅读本文,目标的含义有些模糊,但这Directory.Build.targets是覆盖属性和使用条件检查的最佳位置。