带有用于内部依赖管理的符号的多框架 NuGet 构建 [英] Multi-framework NuGet build with symbols for internal dependency management

查看:44
本文介绍了带有用于内部依赖管理的符号的多框架 NuGet 构建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我在这里突破了极限,但我迫切希望利用 NuGet 来缓解我发现自己陷入的 DLL 地狱.

Maybe I'm pushing the envelope here, but I'm desperate to leverage NuGet to ease the DLL Hell that I've found myself in.

我们有 4 种主要产品,它们都存在于相互关联的 Mercurial 存储库中.所有这些都共享" 3 个核心组件,然后其他所有内容几乎都是特定于产品的.现在管理变得非常困难,因为一个产品已升级到 .NET 4.0 并且正在使用需要 .NET 4.0 的外部依赖项,而另一个产品由于我什至不想进入的原因而停留在 .NET 3.5 中.

We have 4 main products that all live in interrelated Mercurial repositories. All of them "share" 3 core assemblies and then everything else is pretty much product-specific. It's become very difficult to manage now because one product has been upgraded to .NET 4.0 and is using external dependencies that require .NET 4.0, while another product is stuck in .NET 3.5 for reasons I don't even want to get into.

因此,我们已经失去了合并产品之间差异的能力.

So, we have lost our ability to merge differences between products.

为了修复它,我想取出 3 个主要程序集,并将它们转换为具有自己发布周期的自己的项目,并注意确保它们可以针对 .NET 3.5 和 4.0 进行编译,然后将它们转换为包含多个框架版本的 NuGet 包.

To fix it, I want to take out the 3 main assemblies, and turn them into their own project with their own release cycle, and take the care to make sure they can compile against both .NET 3.5 and 4.0, and then turn those into NuGet packages containing multiple framework versions.

但是,我也希望开发者能够浏览这些项目的源代码.

BUT, I also want developers to be able to browse the source of these projects.

所以我设置了一个私有 NuGet 服务器私有 SymbolSource 服务器.然后我小心地将所有存储库中的所有更改合并在一起,并丢弃了除核心程序集之外的所有内容.然后我煞费苦心地手工编辑了 .csproj 文件,这样每个项目的平台目标不是 AnyCPU 平台,而是 3.5 和 4.0,它们指定条件常量(控制特定于平台的功能,如 System.Dynamic)并设置框架版本.

So I set up a private NuGet server and a private SymbolSource server. Then I carefully merged all the changes from all repositories together, and threw out everything except my core assemblies. Then I painstakingly hand-edited the .csproj files so that instead of the AnyCPU platform, each project has platform targets of 3.5 and 4.0, which specifies conditional constants (to control platform-specific features like System.Dynamic) and sets the framework version.

然后我为3.5 Debug"、3.5 Release"、4.0 Debug"和4.0 Release"设置解决方案配置.每个都针对相应的配置(调试或发布)和平台(3.5 或 4.0).

Then I set up solution configurations for "3.5 Debug", "3.5 Release", "4.0 Debug", and "4.0 Release". Each one targets the appropriate Configuration (Debug or Release) and Platform (3.5 or 4.0).

我可以在 Visual Studio 中为任何平台很好地构建一切.现在我在 NuGet 方面遇到了问题,因为有两种方法可以创建包,并且都有一个弱点,除非我遗漏了什么:

I can build everything fine within Visual Studio for any platform. Now I have a problem when it comes to NuGet, because there are two ways to create a package, and both have a weakness, unless I'm missing something:

按项目文件打包

nuget pack MyProject.csproj -Build -Symbols -Version <insert-from-build-server> -Properties "Configuration=Release;Platform=3.5;"

问题在于:

  • 在构建和打包 3.5 版本时,输出显示正在为目标框架‘.NETFramework,Version=v4.0’构建项目."
  • 如果我解压生成的包,程序集位于 lib\net40 下,这是错误的.
  • 我认为没有任何方法可以以这种方式打包 2 个框架目标,您必须以另一种方式使用文件夹和约定.
  • 我愿意接受您无法将框架打包在一起并制作 2 个名为 MyProject(我会在 4.0 中这样做)和 MyProject.V35 的包......但是我不知道如何拥有相同的project 和 nuspec 并最终得到 2 个具有不同 ID 的不同结果.

按 Nuspec 文件打包

使用这种方法,我必须自己完成所有的msbuilding,然后进行一堆文件复制以设置像

With this method, I have to do all the msbuilding myself and then do a bunch of file copying to set up a folder structure like

* MyProject.nuspec
* net40
    * MyProject.dll
    * MyProject.pdb
* net35
    * MyProject.dll
    * MyProject.pdb

然后我可以运行 nuget pack MyProject.nuspec 但是没有符号的源代码,因为没有 .csproj 文件,NuGet 无法找出从哪里获取所有源文件,我也没有看到有关如何使用目录约定执行此操作的任何文档.

Then I can run nuget pack MyProject.nuspec but then there is no source to go with the symbols, because without the .csproj file, NuGet has no way to figure out where to get all the source files, and I don't see any documentation on how to do this using directory conventions either.

所以我的问题是:

  1. 有没有办法将源文件添加到基于约定的包中?
  2. 有没有办法用不同的 id 将基于项目的包打包两次?
  3. 还有其他可能我没有考虑过的途径吗?

如有任何想法,我们将不胜感激.

Any thoughts would be much appreciated.

推荐答案

Xavier 的回答将我引向了正确的方向,也为我的 Google 搜索提供了信息.我不完全了解文件声明,当沿着这些路线搜索时,我找到了 Joshua Flanagan 的帖子 构建 NuGet 包的技巧,非常棒.Xavier 和 Joshua 一起教会了我一些事情:

Xavier's answer led me in the proper direction, and also informed my Google searching. I was not fully aware of the file declarations, and when searching along those lines, I found Joshua Flanagan's post Tips for building NuGet packages, which is excellent. Xavier and Joshua together taught me a few things:

  1. 您不必为了构建包而组装符合约定的文件树.最好使用 file 元素来选择文件并将它们定位到组装的 NuGet 包中的目标目录.
  2. NuGet 的 -Symbols 标志不仅仅适用于在 .csproj 文件上打包.当您在 .csproj 文件上使用它时,当然,这就是它确定如何打包所有源文件的方式.但是您也可以在包含源文件元素的 .nuspec 文件上使用 -Symbols.普通的 NuGet 包不会包含 src 目录,但 Symbols 包会包含.
  1. You don't have to assemble a conventions-conforming file tree in order to build a package. It's much better to use the file element to select files and target them to a destination directory within the assembled NuGet package.
  2. NuGet's -Symbols flag doesn't just work for packaging on a .csproj file. When you do use it on a .csproj file, then sure, that's how it figures out how to package up all your source files. But you can also use -Symbols on a .nuspec file that includes the source via file elements. The normal NuGet package will not include the src directory, but the Symbols package will.

现在,让我描述一下在 CI 服务器上发生的构建过程:

So now, let me describe my build process as it occurs on my CI server:

  1. 使用3.5 Release"解决方案配置构建解决方案.
  2. 使用4.0 Release"解决方案配置构建解决方案.
  3. 使用 ILMerge.exe 来内部化一些程序集.我将这些输出发送到(例如)bin\Release-3.5\merged,所以我不必在合并中使用它之前将目标程序集重命名为 temp.dll.立>
  4. 根据 Powershell 中的 .nuspec 构建包.
  1. Build the solution using the "3.5 Release" solution configuration.
  2. Build the solution using the "4.0 Release" solution configuration.
  3. Use ILMerge.exe to internalize some assemblies. I have these output to (for example) bin\Release-3.5\merged so I don't have to monkey with renaming the target assembly to temp.dll before I use it in the merge.
  4. Build the package against the .nuspec in Powershell.

这里是打包命令:

nuget pack src\MyProject\MyProject.nuspec -OutputDirectory .\output -Build -Symbols -Version $Version

请注意,$Version 是从构建服务器传入的,因此我可以使用它的构建号作为版本的最后一部分.

Note that $Version is passed in from the build server so I can use its build number as the last part of the version.

这是 .nuspec 文件:

Here is the .nuspec file:

<?xml version="1.0"?>
<package>
    <metadata>
        <id>MyProject</id>
        <version>0.0.0</version>
        <title>MyProject</title>
        <authors>David Boike</authors>
        <owners>David Boike</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>MyProject</description>
        <releaseNotes></releaseNotes>
        <copyright>Copyright 2012</copyright>
        <tags>my tags</tags>
    </metadata>
    <files>
        <file src="bin\Release-4.0\merged\MyProject.dll" target="lib\net40" />
        <file src="bin\Release-4.0\merged\MyProject.pdb" target="lib\net40" />
        <file src="bin\Release-4.0\MyProject.xml" target="lib\net40" />
        <file src="bin\Release-3.5\merged\MyProject.dll" target="lib\net35" />
        <file src="bin\Release-3.5\merged\MyProject.pdb" target="lib\net35" />
        <file src="bin\Release-3.5\MyProject.xml" target="lib\net35" />
        <file src="**\*.cs" target="src" />
    </files>
</package>

请注意,我已经从我的 nuspec 中删除了很多信息量更大的元素,因为这对于像这样的内部项目来说并不重要.

Note that I have removed a lot of the more informative elements from my nuspec because it just doesn't matter for an internal project like this.

结果是我的私有 NuGet 服务器的包,其中包含 .NET 3.5 和 4.0 程序集的 DLL、PDB 和 XML 文档,然后是我的私有 SymbolServer 的单独符号包,其中包括上述所有内容以及来源.使用 NuGet Package Explorer 很容易查看,我高度 建议您下载.

The result is a package for my private NuGet server that contains DLL, PDB, and XML documentation for the assembly for both .NET 3.5 and 4.0, and then a separate symbols package for my private SymbolServer that includes all of the above plus the source. This is very easy to view with the NuGet Package Explorer which I highly recommend you download.

最后,我测试了所有内容并使用 Visual Studio 设置在symbolsource.org 上建议(除了我自己的私人符号服务器)我能够调试代码并轻松进入源代码.

Finally, I tested everything and with the Visual Studio setup suggested at symbolsource.org (except with my own private symbol server) I was able to debug the code and easily step into the source.

再次感谢 Xavier 带领我走上正确的道路!

Thanks again to Xavier for leading me down the right path!

这篇关于带有用于内部依赖管理的符号的多框架 NuGet 构建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆