Reputation: 1
I would like to use the dotnet CLI to create a nuget package that can target the following frameworks: net462
, net48
, net8.0
. My library has no dependencies (i.e. it doesn't require any other NuGet packages or projects).
I have written a powershell build script that builds my library such that three DLLs are created. The relevant part of the build script is included below:
dotnet build TestCI.sln -c "net462" -f "net462" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
dotnet build TestCI.sln -c "net48" -f "net48" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
dotnet build TestCI.sln -c "net8.0" -f "net8.0" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
This results in the following folder structure:
bin
|-- net8.0-x64
|-- |-- TestCI.dll
|-- net48-x64
|-- |-- TestCI.dll
|-- net462-x64
|-- |-- TestCI.dll
When decompiled with DotPeek, I can see that each DLL contains:
So far, so good.
I would like to package these three DLLs into a single nuget package that can be deployed to net462
, net48
, and net8.0
runtimes, using only my SDK-style .csproj
file and the CLI.
My long-term goal is to automate the building and packaging of this library (and others) using GitHub actions - hence the scripting. However, ehcin I run the following dotnet pack command:
dotnet pack TestCI\TestCI.csproj -p:PackageVersion=$($MAJOR_MINOR_PATCH) --no-restore --no-build
The resulting NuGet package contains DLLs that all specify net8.0
as the target framework. The f
TestCI.nupkg
|-- lib
|-- |-- net462
|-- |-- |-- TestCI.dll
|-- |-- net48
|-- |-- |-- TestCI.dll
|-- |-- net8.0
|-- |-- |-- TestCI.dll
However when inspecting each DLL, they all contain the following line, regardless of the lib subdirecotry:
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
I.e. there doesn't appear to be a difference between the DLLs packged despite the fact that I know that each DLL was built to a different target framework, and have confirmed this on each DLL in the bin
directory.
So far, I've tried several variations of the dotnet pack command, even including a rudimentary nuspec file:
dotnet pack TestCI\TestCI.csproj -p:PackageVersion=$($MAJOR_MINOR_PATCH) -p:NuspecFile=.nuspec --no-restore --no-build
(see this post on multi-targeted nuget packages)
This works, however I don't like this soltuion for the following reasons:
.csproj
file to keep my repository cleaner and simpler.I've also ensured that my .csproj
file contains the following element:
<TargetFrameworks>net462;net48;net8.0</TargetFrameworks>
.nuspec
file?.csproj
file and the CLI?[2024-07-26]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>TestCI</RootNamespace>
<Company>XYZ</Company>
<Copyright>XYZ (c) 2024</Copyright>
<Version>0.0.1</Version>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>net462;net48;net8.0-windows</TargetFrameworks>
<Configurations>net48;net462;net8.0-windows</Configurations>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\$(Configuration)-$(Platform)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<ProductName>$(RootNamesapce)</ProductName>
<OutputType>Library</OutputType>
<IsTestProject>False</IsTestProject>
</PropertyGroup>
<PropertyGroup>
<PackageID>$(RootNamespace)</PackageID>
<PackageVersion>$(Version)</PackageVersion>
<IsPackable>True</IsPackable>
<IncludeBuildOutput>True</IncludeBuildOutput>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<PackageOutputPath>..\nupkg</PackageOutputPath>
<PackageDescription>XYZ</PackageDescription>
<RepositoryUrl>XYZ</RepositoryUrl>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugType>embedded</DebugType>
<OutDir>bin\$(Configuration)-$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup>
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
<AssemblyName>$(RootNamespace)</AssemblyName>
<AssemblyVersion>$(Version).0</AssemblyVersion>
<FileVersion>$(Version).0</FileVersion>
</PropertyGroup>
<ItemGroup>
<Compile Remove=".github\**" />
<EmbeddedResource Remove=".github\**" />
<None Remove=".github\**" />
</ItemGroup>
</Project>
Upvotes: 0
Views: 121
Reputation: 1
After several months of research, trial, and error, I was able to find a solution to this problem. The key was to remove the following elements:
<Configurations>net48;net462;net8.0-windows</Configurations>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\$(Configuration)-$(Platform)\</OutputPath>
<OutDir>bin\$(Configuration)-$(Platform)</OutDir>
Removing these elements allows dotnet build
to create binaries for each of the target frameworks and allowed dotnet pack
to correctly package the DLLs for general consumption.
<Configurations>
was unecessary and caused problems. The MSBuuild defaults, Debug
and Release
, work best.
<PlatformTarget>
proved unecessary.
<OutputPath>
changes where the binaries are placed. Removing this allowed MSBuild to operate using its default folder structure, which solved the build concurrency issues.
<OutDir>
caused similar issues to those caused by <OutputPath>
. Both proved unecessary when simply using the MSBuild defaults.
The biggest lesson learned here has been that less is more. MSBuild and the dotnet CLI are good tools. Stay out of the way and let them cook!
Upvotes: 0