MSBuild 道具文件在由 nuget 包导入时未得到评估,但在手动导入时有效

MSBuild props file does not get evaluated when imported by a nuget package, but works when manually imported

我创建了许多带有 msbuild 目标的 nuget 包,它们帮助我处理 .NET 项目中的常见样板。这里我正在处理一个简单的 .props 文件,目的是使编译后的程序集和 nuget 包中的版权信息保持一致。

目前我正在努力解决这个 props 文件在目标项目的所有构建阶段都没有得到尊重的事实。

道具文件大致如下所示(github 中提供了完整的源代码):

<PropertyGroup>
  <CopyrightYearCurrent Condition=" '$(CopyrightYearCurrent)' == '' ">$([System.DateTime]::get_UtcNow().get_Year())</CopyrightYearCurrent>
  <CopyrightYear>$(CopyrightYearCurrent)</CopyrightYear>
  <!-- CopyrightYearSince may be defined externally in the consuming project and is non-mandatory -->
  <CopyrightYear Condition=" '$(Authors)' != '' AND '$(CopyrightYearSince)' != '' ">$(CopyrightYearSince)-$(CopyrightYearCurrent)</CopyrightYear>
</PropertyGroup>

<PropertyGroup>
  <Copyright Condition=" '$(Authors)' != '' AND '$(Copyright)' == '' ">Copyright © $(Authors) $(CopyrightYear)</Copyright>
</PropertyGroup>

<PropertyGroup>
  <AssemblyCompany Condition=" '$(AssemblyCompany)' == '' AND '$(Authors)' != '' ">$(Authors)</AssemblyCompany>
  <AssemblyCopyright Condition=" '$(AssemblyCopyright)' == '' AND '$(Copyright)' != '' ">$(Copyright)</AssemblyCopyright>
</PropertyGroup>

在目标项目中,我有一个DirectoryBuild.props放在我的根目录下,我需要在其中激活props文件。

我的目标是,当我从命令行 运行 dotnet builddotnet pack 时,将来自 msbuild 的版权相关信息传播到程序集属性,以及nuget 包。

最初,在道具开发过程中,我只是使用 MSBuild Import 指令将道具文件导入我的 DirectoryBuild.props,一切都按预期工作。

因为道具看起来很普通,所以我决定从中创建一个 nuget package,这样我就可以在多个项目中重复使用它,并从一个中心位置维护它。然后我用 PackageReference 指令替换了 DirectoryBuild 中道具文件的 Import

现在,当我执行 dotnet pack 时,生成的 nuget 包(以及在 obj 文件夹中自动生成的相应 nuspec 文件)不再包含 copyright 字段。同时编译后的dll文件正确应用了版权信息。

我已经检查了两种情况下的完整 msbuild 输出(使用命令 dotnet build -pp:msbuild.xml),从包中导入 props 文件的顺序与从 [= 中手动导入文件的顺序没有显着差异23=],所以我坚持理解观察到的行为。

这里是 dotnet --info 的输出,如果它对某人有用的话:

.NET SDK (reflecting any global.json): Version: 5.0.202 Commit: db7cc87d51

Runtime Environment: OS Name: Windows OS Version: 10.0.19042 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk.0.202\

Host (useful for support): Version: 5.0.5 Commit: 2f740adc14

更新

只是为了消除任何怀疑,nuget 包已正确构建(包的名称及其导入的目标相同)并且我的 IDE (JetBrains Rider) 正确检测到 .props 已加载 nuget 包中的文件。

此外,CopyrightYearSinceAuthorsPackageReference 指令之前在我的 Directory.Build.props 中定义。

更新 2

似乎只有在生成自动生成的 nuspec 文件时才会出现此问题。 属性 的 props 文件中应该参与 nuspec 的每个覆盖都被忽略,但是,它在其他构建任务中被适当使用。如果直接引用 props 文件而不是从 nuget 包中使用,问题就会消失。

看起来这个问题比较复杂,因为它发生在涉及交叉目标项目时。

感谢 a github issue 我对 GenerateNuspec 任务如何与导入的 msbuild 任务、道具和目标一起工作有了更多的了解,所以我找到了解决我自己问题的方法。详情如下:

观察到问题行为的用例是因为:

  1. 我包含道具和目标的 nuget 包只包含在 build 下,而不是 buildCrossTargeting 文件夹下。
  2. 上面链接的问题告诉我,当项目是交叉目标时,GenerateNuspec 流程将只包含 buildCrossTargeting 文件夹中的自定义 props/targets,因此我的目标被忽略
  3. 当我生成一个新的 nuget 包时,我同时使用了 buildbuildCrossTargeting,问题就消失了。

结论——在创建自己的 msbuild 目标作为 nuget 包时要非常小心——交叉目标项目等场景需要特殊处理!