【问题标题】:msbuild Directory.build.props cascade per project?每个项目的 msbuild Directory.build.props 级联?
【发布时间】:2020-02-13 07:38:19
【问题描述】:

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

我有一个相当简单的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:\temp\MSBuild_Test\MSBuild_Test\bin\Debug\netstandard2.0\LibStandard.dll
  ::::: Mode set to Changed to Debug
  ::::: Target Framework set to v2.0
  ConsoleAppNet -> E:\temp\MSBuild_Test\ConsoleAppNet\bin\Debug\ConsoleAppNet.exe
  ::::: Mode set to Changed to Debug
  ::::: Target Framework set to v4.7.2

如您所见,控制台输出应该触发了属性组,其条件导致MyModeFramework,但没有成功。这个从来没有匹配过:

  <PropertyGroup Condition=" '$(TargetFrameworkVersion)' == 'v4.7.2' ">
    <MyMode>Framework</MyMode>
  </PropertyGroup>

有没有根据上述条件在加载期间应用PropertyGroups 的好方法?

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

  <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 变量,它指向正确的值,但构建使用旧值而不是重定向输出。

【问题讨论】:

    标签: msbuild


    【解决方案1】:

    高五,我找到了解决所有即将到来的 Samuels 询问相同问题的方法。

    快速解答

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

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

    资源

    这里有一些关于 msbuild 的非常有用的页面

    说明

    这是来自paragraph on the customization page 的引用(只要当前文档还活着……)

    进口订单

    Directory.Build.props 很早就被导入了 Microsoft.Common.props 和后面定义的属性不可用 给它。因此,避免引用尚未定义的属性(和 将评估为空)。

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多