为.NET 4和.NET 4.5构建-引用的NuGet包如何? [英] Build for .NET 4 and .NET 4.5 - what about referenced NuGet packages?
问题描述
我有一个脚本来构建项目,输出.NET 4.0程序集.
I've got a script that build a project, outputting .NET 4.0 assemblies.
该项目包括来自NuGet的NLog.因此,项目文件中的引用如下所示:
The project includes NLog from NuGet. So the reference in the project file looks like this:
<Reference Include="NLog">
<HintPath>..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll</HintPath>
</Reference>
我的packages.config看起来像这样:
And my packages.config looks like this:
<packages>
<package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>
该项目将在NuGet上发布,现在我想更新构建脚本,以便它也可以构建.NET 4.5程序集.
This project is going to be published on NuGet, and now I want to update the build script so it also builds .NET 4.5 assemblies.
现在,我知道我可以将/p:TargetFrameworkVersion="4.5"
传递给msbuild
并将其定位为.NET 4.5-但这仍将再次构建.NET 4.0 NLog程序集.
Now, I know I can pass /p:TargetFrameworkVersion="4.5"
to msbuild
and have it target .NET 4.5 - but that is still going to build againt the .NET 4.0 NLog assembly.
如何针对目标框架使用正确版本的NuGet依赖项进行构建?
How can I have it build using the correct version of NuGet dependencies for the framework being targetted?
推荐答案
前一阵子有完全相同的要求,没有找到纯"的NuGet解决方案.我怀疑那里.唯一的选择似乎是维护不同的项目文件(或部分文件),对于大量的代码库而言绝对是不可行的.
Had the exact same requirement here a while ago and found no 'pure' NuGet solution. And I doubt there is. The only option seemed to be maintaining different project files (or parts of it) - definitely a no-go for massive code bases.
我所做的只是所有项目中的目标4.5,并且具有一个相当简单的msbuild脚本,该脚本可创建项目及其所有NuGet配置的副本,以将.Net的其他版本作为目标.基本上,它只枚举所有.csproj文件,从net45
-> net40
字符串中查找/替换字符串,并将它们保存为其他名称.包config/targets/solution文件的同上.
What I did instead was just target 4.5 in all projects, and have a rather simple msbuild script that creates copies of the projects and all their NuGet config for targetting other versions of .Net. Basically it just enumerates all .csproj files, does a find/replace from net45
-> net40
strings and saves them under a different name. Idem for the package config/targets/solution files.
这里几乎是完整的MSBuild目标:
Here's pretty much the complete MSBuild target:
<Target Name="MakeNet40Projects">
<ItemGroup>
<SourceProjs Include="$(MyProjectDir)*\*\*.csproj" Exclude="$(MyProjectDir)\*\*\*.Net40.csproj"/>
...
<SourceConfigs Include="$(MyProjectDir)*\*\packages.config"/>
...
<DestProjs Include="%(SourceProjs.RootDir)%(SourceProjs.Directory)%(SourceProjs.FileName).Net40.csproj"/>
<DestConfigs Include="%(SourceConfigs.RootDir)%(SourceConfigs.Directory)%(SourceConfigs.FileName).Net40.config"/>
</ItemGroup>
<PropertyGroup>
<OldPackages>packages.config</OldPackages>
<NewPackages>packages.Net40.config</NewPackages>
<OldTargets>NuGet.targets</OldTargets>
<NewTargets>NuGet.Net40.targets</NewTargets>
<OldProj>\.csproj</OldProj>
<NewProj>.Net40.csproj</NewProj>
</PropertyGroup>
<Copy SourceFiles="@(SourceProjs)" DestinationFiles="@(DestProjs)"/>
<FileUpdate Files="@(DestProjs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>
<FileUpdate Files="@(DestProjs)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>
<FileUpdate Files="@(DestProjs)" Regex="$(OldTargets)" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
<FileUpdate Files="@(DestProjs)" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>
<Copy SourceFiles="@(SourceConfigs)" DestinationFiles="@(DestConfigs)"/>
<FileUpdate Files="@(DestConfigs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>
<Copy SourceFiles="$(MsBuildThisFileDirectory)\.nuget\$(OldTargets)" DestinationFiles="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)"/>
<FileUpdate Files="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>
<Copy SourceFiles="$(MsBuildThisFileDirectory)\my.sln" DestinationFiles="$(MsBuildThisFileDirectory)\my.Net40.sln"/>
<FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>
<FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="NuGet\.targets" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
</Target>
运行此命令后,每个项目都有一个.Net40.csproj,一个.Net40.sln,一个用于解决方案的Nuget.Net40.targets和packages.Net40.config文件,所有文件都已准备好构建. 到目前为止,一切都很好.
After running this there's a .Net40.csproj for each project, a .Net40.sln, a Nuget.Net40.targets for the solution and packages.Net40.config files, all ready to be built. So far, so good.
小问题:packages.config
在Nuget.exe中被硬编码为字符串,因此它在命令行上不接受packages.net40.config
.这是确定传递给-install
算法的路径是实际的软件包配置还是软件包ID的算法"的一部分.哈哈.我对此提出了一个问题,但没有答案.无论如何,我都不打算让它变有趣,所以我在源代码中进行了单行调整,以使其接受以.config
结尾的任何内容,并对其进行了构建并立即使用该Nuget.exe.
Small problem though: packages.config
is hardcoded as a string in Nuget.exe so it won't accept packages.net40.config
on it's command line. It's part of it's 'algorithm' to decide whether or not the path passed to the -install
algorithm is an actual package config, or a package Id. Lol. I raised a question on this but no answer. Anyway I wasn't planning to let this spoil the fun so I made a single-line adjustment in the source to have it accept anything that ends with .config
, built it and use that Nuget.exe now.
这篇关于为.NET 4和.NET 4.5构建-引用的NuGet包如何?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!