为.NET 4和.NET 4.5构建-引用的NuGet包如何? [英] Build for .NET 4 and .NET 4.5 - what about referenced NuGet packages?

查看:91
本文介绍了为.NET 4和.NET 4.5构建-引用的NuGet包如何?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个脚本来构建项目,输出.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屋!

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