执行摘要:我想根据仅在构建管道中后期存在的条件在属性组中设置属性,并且正在寻找一种更早解决此问题的方法。
我有一个相当简单的Directory.build.props
文件
<Project>
<PropertyGroup>
<MyMode>Default</MyMode>
</PropertyGroup>
<!-- This one overrides the default group above -->
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<MyMode>Changed to Debug</MyMode>
</PropertyGroup>
<!-- This one is not applied -->
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<MyMode>Framework</MyMode>
</PropertyGroup>
<Target Name="Stats" AfterTargets="Build">
<Message Importance="High" Text="::::: Mode set to $(MyMode)" />
<Message Importance="High" Text="::::: Target Framework set to $(TargetFrameworkVersion)" />
</Target>
</Project>
和一个简单的项目结构
E:.
│ Directory.build.props
│ MSBuild_Test.sln
│
├───ConsoleAppNet
│ App.config
│ ConsoleAppNet.csproj
│ Program.cs
│
└───MSBuild_Test
Class1.cs
LibStandard.csproj
LibStandard
是一个.NET标准库,ConsoleAppNet
是一个.NET框架项目,该项目也具有对LibStandard
的构建依赖
关系当我执行上面的 msbuild 脚本时,我得到这个输出
LibStandard -> E:tempMSBuild_TestMSBuild_TestbinDebugnetstandard2.0LibStandard.dll
::::: Mode set to Changed to Debug
::::: Target Framework set to v2.0
ConsoleAppNet -> E:tempMSBuild_TestConsoleAppNetbinDebugConsoleAppNet.exe
::::: Mode set to Changed to Debug
::::: Target Framework set to v4.7.2
如您所见,控制台输出应该触发了属性组,条件导致MyMode
Framework
,但没有成功。这个从未匹配过:
<PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<MyMode>Framework</MyMode>
</PropertyGroup>
根据上述条件,有没有在负载期间应用PropertyGroups
的好方法?
我知道我可以在目标中放置属性组覆盖,例如:
<Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" '$(TargetFrameworkVersion' == 'v4.7.2' ">
<PropertyGroup >
<MyMode>Framework</MyMode>
</PropertyGroup>
</Target>
它也可以正确执行,但此时我无法设置重要的其他变量。
我的目的是根据不同的条件重定向输出目录。当我在目标中设置$(OutputPath)
时,已经太晚了。项目将忽略此项目的整个生成的此输出:
<Target Name="TooLate" BeforeTargets="BeforeBuild" Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
<PropertyGroup >
<OutputPath>New_Output_Directory</OutputPath>
</PropertyGroup>
</Target>
我什至可以回显OutputPath
变量,它指向正确的值,但构建使用旧值而不是重定向输出。
高五我,我找到了所有即将到来的塞缪尔斯询问同一问题的解决方案。
快速回答
在导入Directory.build.props
时,没有其他属性(例如 TargetFramework(已导入,并且默认为空。这就是对它们的检查失败的原因。请改用Directory.build.targets
!
Directory.build.props
很早就导入了,允许您在开始时设置属性Directory.build.targets
很晚才导入,允许您自定义构建链
资源
这里有一些关于msbuild的非常有用的页面
- 可用目标的说明
- 如何自定义构建
解释
这是自定义页面上段落的引用(只要当前文档还活着......
导入订单
Directory.Build.props很早就导入了 Microsoft.Common.props 和稍后定义的属性不可用 到它。因此,请避免引用尚未定义的属性(和 将计算为空(。
Directory.Build.targets 是从 Microsoft.Common.targets导入的 从 NuGet 包导入 .targets 文件后。所以,它可以 重写大多数生成逻辑中定义的属性和目标, 但有时您可能需要在 最终导入。
通过阅读本文,对目标的含义有些模糊,但Directory.Build.targets
是覆盖属性和使用条件检查的最佳位置。