也许我在这里推动信封,但我迫切希望利用NuGet来缓解我发现自己的DLL地狱。
我们有4个主要产品都存在于相互关联的Mercurial存储库中。所有这些都“共享”了3个核心组件,然后其他一切都是针对特定产品的。现在管理变得非常困难,因为一个产品已升级到.NET 4.0并且正在使用需要.NET 4.0的外部依赖项,而另一个产品因为我甚至不想进入的原因而陷入.NET 3.5。 / p>
因此,我们失去了合并产品差异的能力。
要修复它,我想取出3个主要程序集,并将它们转换为自己的项目,并使用自己的发布周期,并注意确保它们可以针对.NET 3.5和4.0进行编译,然后将它们转换为包含多个框架版本的NuGet包。
但是,我也希望开发人员能够浏览这些项目的来源。
所以我设置了private NuGet server和private SymbolSource server。然后我仔细地将所有存储库中的所有更改合并在一起,并丢弃除核心程序集之外的所有内容。然后我精心手工编辑.csproj文件,以便代替AnyCPU平台,每个项目都有3.5和4.0的平台目标,它指定条件常量(控制System.Dynamic等特定于平台的功能)并设置框架版本。
然后我为“3.5 Debug”,“3.5 Release”,“4.0 Debug”和“4.0 Release”设置了解决方案配置。每个目标都适用于相应的配置(调试或发布)和平台(3.5或4.0)。
我可以在Visual Studio中为任何平台构建一切。现在我遇到NuGet的问题,因为有两种方法可以创建一个包,两者都有一个弱点,除非我遗漏了一些东西:
按项目文件打包
nuget pack MyProject.csproj -Build -Symbols -Version <insert-from-build-server> -Properties "Configuration=Release;Platform=3.5;"
问题是:
lib\net40
下,这是错误的。按Nuspec文件打包
使用这种方法,我必须自己完成所有msbuilding,然后进行一堆文件复制以设置文件夹结构,如
* MyProject.nuspec
* net40
* MyProject.dll
* MyProject.pdb
* net35
* MyProject.dll
* MyProject.pdb
然后我可以运行nuget pack MyProject.nuspec
但是没有源代码可以使用这些符号,因为没有.csproj文件,NuGet无法确定从哪里获取所有源文件,而且我不知道请参阅使用目录约定的任何文档。
所以我的问题是:
任何想法都会非常感激。
答案 0 :(得分:15)
Xavier的回答让我朝着正确的方向前进,并通知了我的Google搜索。我并不完全了解文件声明,在搜索这些行时,我找到了Joshua Flanagan的帖子Tips for building NuGet packages,这非常好。泽维尔和约书亚一起教我一些事情:
.csproj
文件上使用它时,确定,它是如何计算如何打包所有源文件的。但您也可以在包含源文件元素的-Symbols
文件上使用.nuspec
。普通的NuGet包不包含src目录,但符号包将包含。现在,让我描述我在CI服务器上发生的构建过程:
bin\Release-3.5\merged
所以我不必将目标程序集重命名为temp.dll,然后才在合并中使用它。.nuspec
构建软件包。 这是包命令:
nuget pack src\MyProject\MyProject.nuspec -OutputDirectory .\output -Build -Symbols -Version $Version
请注意,$ Version是从构建服务器传入的,因此我可以使用其构建号作为版本的最后一部分。
这是.nuspec文件:
<?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中删除了许多信息量较大的元素,因为这对于像这样的内部项目无关紧要。
结果是我的私有NuGet服务器的包,其中包含用于.NET 3.5和4.0的程序集的DLL,PDB和XML文档,然后是我的私有SymbolServer的单独符号包,其中包含以上所有内容来源。使用{<3}}非常容易查看,我高度建议您下载。
最后,我测试了所有内容并使用NuGet Package Explorer(除了我自己的私有符号服务器)我能够调试代码并轻松进入源代码。
再次感谢Xavier带领我走正确的道路!
答案 1 :(得分:8)
你知道有一个第三个选项吗? 在定位csproj文件时,它还会查找与项目文件同名的nuspec文件(myProject.csproj - &gt; myProject.nuspec)。这意味着您可以通过将结果包定义到nuspec文件中,将额外的元数据添加到生成的包中,同时仍然以csproj文件为目标。从本质上讲,您最终会得到一个包含csproj文件和nuspec文件中合并元数据的包。
在您的特定场景中,如果您想要打包同一项目的多个平台版本,那么在使用nuspec打包之前,您确实必须先构建这些项目。
我建议您创建两个项目,一个针对NET35,另一个针对NET40,并将这些文件作为链接添加到其中一个项目中。因此,您可以构建两个项目,并使用nuspec文件 将所有输出打包到一个NuGet包中。
现在对于符号,我认为你可以有第二个nuspec文件(例如myProject.symbols.nuspec),你可以使用通配符添加项目的所有内容(源等),类似于下面所示。
<file src="myProject35\**\*.cs" target="src" />
<file src="myProject40\bin\Release\*.dll" target="lib\net40" />
<file src="myProject40\bin\Release\*.pdb" target="lib\net40" />
<file src="myProject35\bin\Release\*.dll" target="lib\net35" />
<file src="myProject35\bin\Release\*.pdb" target="lib\net35" />
希望这有助于或至少为您提供一些信息以找到解决方法:)
干杯, 泽维尔
答案 2 :(得分:0)
查看NuGet 2.5中与框架版本相关的参考资料的新功能:http://docs.nuget.org/docs/release-notes/nuget-2.5
您可以选择在csproj文件中使用带有条件引用元素的构建配置(在TargetFrameworkVersion上有条件),然后在所有配置中运行构建,并为net35和net40生成输出,并可选择定位引用你的nupkg。