Build for .NET 4 and .NET 4.5 - what about referenced NuGet packages?

安稳与你 提交于 2019-12-23 10:46:17

问题


I've got a script that build a project, outputting .NET 4.0 assemblies.

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>

And my packages.config looks like this:

<packages>
  <package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>

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.

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.

How can I have it build using the correct version of NuGet dependencies for the framework being targetted?


回答1:


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.

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.

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>

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.

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.



来源:https://stackoverflow.com/questions/18000930/build-for-net-4-and-net-4-5-what-about-referenced-nuget-packages

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!