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?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With