Directory.Build.targets 无法覆盖 OutputPath 属性
2024-04-20 23:19:40
在管理多个工程时,通常需要根据工程的属性并按照指定的规则来决定二进制文件的输出位置。第一直觉是在Directory.Build.targets
文件中设置OutputPath
属性。
然而实测发现Directory.Build.targets
文件中的OutputPath
并未生效。
Google 一番后找到两种解决办法。
BeforeTargetFrameworkInferenceTargets 属性
这个属性出现在 Microsoft.NET.TargetFrameworkInference.targets 文件中,并没有官方的文档。
我们可以在Directory.Build.props
中设置它:
1 | <BeforeTargetFrameworkInferenceTargets>$(MSBuildThisFileDirectory)OutputBuild.props</BeforeTargetFrameworkInferenceTargets> |
然后在OutputBuild.props
中覆盖OutputPath
,这里是可以使用自定义属性的。
1 | <Project> |
.props 和 .targets 文件之前和之后
比起没有文档的BeforeTargetFrameworkInferenceTargets
属性,MSBuild 提供了一系列”钩子”属性,可以在Microsoft.Common.Props
或Microsoft.Common.Targets
文件的前后执行。
- CustomBeforeMicrosoftCommonProps
- CustomBeforeMicrosoftCommonTargets
- CustomAfterMicrosoftCommonProps
- CustomAfterMicrosoftCommonTargets
- CustomBeforeMicrosoftCSharpTargets
- CustomBeforeMicrosoftVisualBasicTargets
- CustomAfterMicrosoftCSharpTargets
- CustomAfterMicrosoftVisualBasicTargets
从名字上看,我们只关心前面四个。测试一下:
1 | <Project> |
这四个文件的载入顺序是:
- CustomBeforeMicrosoftCommonProps。可覆盖
OutputPath
属性,但不可以使用工程的自定义属性。 - CustomAfterMicrosoftCommonProps。可覆盖
OutputPath
属性,但不可以使用工程的自定义属性。 - CustomBeforeMicrosoftCommonTargets。可使用工程的自定义属性。
- CustomAfterMicrosoftCommonTargets。无法覆盖
OutputPath
属性。
所以,我们有机会在CustomBeforeMicrosoftCommonTargets
中覆盖OutputPath
属性。
相关阅读
setting OutputPath in a Directory.Build.targets
Bending .NET - Improved Common Flat Build Output
自定义所有 .NET 生成
Document the import order of the common msbuild extension points.