栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

在制作多框架项目的 NuGet 包时应该注意的问题(buildMultiTargeting TargetFrameworks)

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在制作多框架项目的 NuGet 包时应该注意的问题(buildMultiTargeting TargetFrameworks)

制作一个 dll 引用的 NuGet 包简直是一键完成,无论是不是多框架项目;制作 dotnet-tools 也是如此。但如果需要自定义一些编译步骤,那么就需要在制作 NuGet 包时做很多的特殊处理了。

本文介绍制作适用于多框架项目的 NuGet 工具包时应该注意的问题。


本文内容
    • 背景知识
      • NuGet 包内的文件夹结构
      • 制作有自定义功能的 NuGet 包
    • 执行时机
      • 1. 仅含 `build` 文件夹的 NuGet 包装到单框架项目中
      • 2. 仅含 `build` 文件夹的 NuGet 包装到多框架项目中
      • 3. 包含 `build` 和 `buildMultiTargeting` 文件夹的 NuGet 包装到单框架项目中
      • 4. 包含 `build` 和 `buildMultiTargeting` 文件夹的 NuGet 包装到多框架项目中

背景知识 NuGet 包内的文件夹结构

回顾一下 NuGet 包的文件夹结构:

+ /
+ lib/
+ ref/
+ runtimes/
+ content/
+ build/
+ buildMultiTargeting/
+ buildTransitive
+ tools/

由于涉及到自定义 NuGet 包的代码都写在 build buildMultiTargeting 和 buildTransitive 中,其他都不涉及到 NuGet 包在编译期间会做的事情,另外,buildTransitive 是用来处理包传递过程中的编译过程的,所以我们本文只说也只需要说 build 和 buildMultiTargeting。

这里面的代码都是用 Target 写出来的,如果你对此不了解,建议阅读这些博客:

  • 理解 C# 项目 csproj 文件格式的本质和编译流程 - walterlv
  • 从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目) - walterlv
制作有自定义功能的 NuGet 包

我之前写过一些关于如何制作各种高级功能的 NuGet 包的博客:

  • 如何创建一个基于命令行工具的跨平台的 NuGet 工具包 - walterlv
  • 如何创建一个基于 MSBuild Task 的跨平台的 NuGet 工具包 - walterlv
  • 从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目) - walterlv

按照上面的博客制作出来的 NuGet 包其实是适用于单框架项目和多框架项目的,甚至也适用于传统的非 SDK 风格的项目。

关于单框架和多框架项目,就是项目文件中这里的差别:



  
    
    netcoreapp3.1
  




  
    
    netcoreapp3.1;net48
  


但是,有的小伙伴希望探索一些更高级的用法,所以可能会遇到在多框架项目中,NuGet 包自定义的功能不执行的问题。

接下来,我们了解一下在单框架和多框架下 NuGet 包执行上的不同。

执行时机

我们打出这样的两种 NuGet 包,一种是仅包含 build 文件夹而不包含 buildMultiTargeting 文件夹;一种是包含 build 文件夹和 buildMultiTargeting 文件夹。

我们的目标项目一种是单框架项目;一种是多框架项目。

于是我们可以得到这样的四种不同的组合情况:

  1. 仅含 build 文件夹的 NuGet 包装到单框架项目中
  2. 仅含 build 文件夹的 NuGet 包装到多框架项目中
  3. 包含 build 和 buildMultiTargeting 文件夹的 NuGet 包装到单框架项目中
  4. 包含 build 和 buildMultiTargeting 文件夹的 NuGet 包装到多框架项目中
1. 仅含 build 文件夹的 NuGet 包装到单框架项目中

在这种情况下,build 文件夹中的 .props 和 .targets 文件在目标项目编译时正常执行。

2. 仅含 build 文件夹的 NuGet 包装到多框架项目中

在这种情况下,build 文件夹中的 .props 和 .targets 文件,会分别在目标项目编译每个框架的时候执行一次。

例如这种项目:



  
    
    netcoreapp3.1;net48
  

  
    
  


那么,在编译 netcoreapp3.1 框架的时候会执行一次 Walterlv.NullableAttributes.Source 包中 build 文件夹中的编译任务;在编译 net48 框架的时候又会执行一次 Walterlv.NullableAttributes.Source 包中 build 文件夹中的编译任务。

3. 包含 build 和 buildMultiTargeting 文件夹的 NuGet 包装到单框架项目中

在这种情况下,buildMultiTargeting 中的任何编译任务相当于不存在。编译过程与情况 1 是完全一样的。

4. 包含 build 和 buildMultiTargeting 文件夹的 NuGet 包装到多框架项目中

从 NuGet 5.x 版本开始在这种情况下,build 中的内容和 buildMultiTargeting 中的编译任务会同时参与编译。

依然举例这样的目标项目(不过使用了含 buildMultiTargeting 的 NuGet 包):



  
    
    netcoreapp3.1;net48
  

  
    
  


编译一开始,会将 buildMultiTargeting 中的编译任务加入执行。在编译 netcoreapp3.1 框架的时候会执行一次 Walterlv.NullableAttributes.Source 包中 build 文件夹中的编译任务;在编译 net48 框架的时候又会执行一次 Walterlv.NullableAttributes.Source 包中 build 文件夹中的编译任务。而这两个单独框架的编译结束后,buildMultiTargeting 中的任务才会结束。

也就是说,这两个编译任务文件夹中的编译任务是都会执行的。但是:

两者参与编译的 Targets 不一样。

下表中列出了在你没有编写任何扩展的任务或者干预已有 Target 执行的情况下,默认可以依赖的 Target(指的是可以通过 BeforeTargets="xx" 或 AfterTargets="xx" 的方式扩展编译任务:

可依赖的 TargetbuildbuildMultiTargeting
BeforeCompile✔❌
Compile✔❌
CoreCompile✔❌
AfterCompile✔❌
BeforeBuild✔❌
Build✔✔
AfterBuild✔❌
BeforeRebuild❌❌
Rebuild❌✔(如果强行执行)
AfterRebuild❌❌
BeforeClean✔(如果强行执行)❌
Clean✔(如果强行执行)✔(如果强行执行)
AfterClean✔(如果强行执行)❌

注:强制执行说的是一般编译时不会执行,你需要在命令中指定执行这个 Target。也对应到 Visual Studio 里的“重新编译”和“清理”的功能。

为了更好理解上表,这里给出一个例子。下面的代码如果在 build 文件夹中则会在编译过程输出一堆星号,而如果在 buildMultiTargeting 文件夹中则不会执行。而无论目标项目是否是多框架的。但换成 AfterBuild 则会两个文件夹中都输出。


    

当然,不要被这个第 4 种情况带歪了!如果你的 NuGet 包依然只有一个 build 文件夹,那么上面的所有 Targets 都是会执行的。


参考资料

  • Create a NuGet package using nuget.exe CLI - Microsoft Docs
  • Allow package authors to define build assets transitive behavior · NuGet/Home Wiki

我的博客会首发于 https://blog.walterlv.com/,而 CSDN 会从其中精选发布,但是一旦发布了就很少更新。

如果在博客看到有任何不懂的内容,欢迎交流。我搭建了 dotnet 职业技术学院 欢迎大家加入。

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名吕毅(包含链接:https://walterlv.blog.csdn.net/),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/959995.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号