Recently started looking at publishing our C# libraries to nuget.org. This first post covers my experience with the actual packaging. In a later post I’ll do the signing and publishing.
In the Beginning
Google un-earthed several promising resources:
- Stackoverflow #1 and #2
- MS docs on using nuget to create native packages
- Blog by former SignalR/ASP.NET guy
But I struggled making a package that worked;
nanomsg.dll wasn’t in the output directory.
.targetsfile mentioned in several places seems to no longer be necessary (VS 15.7.4 and nuget.exe 4.7.0) unless your package will be consumed by c++ projects.
Native libraries need to get packaged in
/runtimes/RID/native/. Runtime ID Catalog not only has a complete list of all Runtime IDs (RIDs), but also gives a pretty detailed explanation.
- Familiarize yourself with nuget.exe
nuget pack -Properties Configuration=Releasewill build a release nupkg (default is debug) for the
.csprojin the current directory. The output assembly will automatically be included.
- Package version can be set by adding
- The NuGetPackageExplorer gives a nice visual look at your nupkg and its meta-data. Just make sure to File->Close otherwise nuget.exe and Visual Studio will have problems accessing your nupkg.
nuget.exe specwill generate a template nuspec from csproj in current directory
- A nuspec file with the same name as the csproj will automatically get included when using nuget.exe from the command line. For example,
- Replacement tokens usable in nuspec
- Using a nuspec together with a csproj is clumsy
- There’s only replacement tokens for some meta-data values
- Omitting a tag from the nuspec results in the value being undefined- even if it is set in the csproj
- Enabling generation of NuGet package on build (placed in output folder) doesn’t use the nuspec:
When using nuget.exe, a
<files>section of the nuspec seems to be the only way to include
<Content>in csproj places things in a
content/subfolder (nuget.exe ignores
<None>doesn’t include them at all.
- You can directly pack the nuspec (e.g.
nuget pack NNanomsg.NETStandard.nuspec)
- If you see the following warning:
WARNING: NU5100: The assembly 'bin\Release\netstandard2.0\NNanomsg.NETStandard.dll' is not inside the 'lib' folder and hence it won't be added as a reference when the package is installed into a project. Move it into the 'lib' folder if it needs to be referenced.
You likely need the following in your nuspec:
<files> <file src="bin\$configuration$\netstandard2.0\*.dll" target="lib\netstandard2.0\"/> <file src="runtimes\**" target="runtimes/"/> </files>
- If you get the following error:
Attempting to build package from 'NNanomsg.NETStandard.nuspec'. Value cannot be null or an empty string. Parameter name: value
The nuspec contains a replacement token (i.e.
$xxx$) that needs to be replaced with an actual value
- If you see the following warning:
NuGet as MSBuild targets
If your project doesn’t reference any external packages you might need to force the PackageReference format by adding to your csproj:
<PropertyGroup> <RestoreProjectStyle>PackageReference</RestoreProjectStyle> </PropertyGroup>
Not sure if it matters, but I use PackageReference by default (Tools->Options->NuGet Package Manager):
I include the native binaries with:
<ItemGroup> <Content Include="runtimes\**" PackagePath="runtimes" Visible="false" /> </ItemGroup>
And then right-click the project->Pack to generate the nupkg. Or in a VS Developer Command Prompt:
In Visual Studio, Tools->Options->NuGet Package Manager->Package Sources to add a local directory as source for nuget packages:
Visual Studio Package Manager (View->Other Windows->Package Manager Console) makes it easy to reload a local nupkg. Make sure Default project is set to the correct project and run:
Installing the package doesn’t cause the native binaries to get copied, you have to build the project.
Assuming your nupkg contains 32-bit and 64-bit native libraries,
runtimes/win-x64/native/nanomsg.dll, respectively. If Platform target (project Properties->Build) of the consuming project is
Any CPUneither native assembly will be copied to the output directory. You must select either
- Least frustrating to pick either nuspec or VS project for package definition- don’t use both
- Nuspec has diminished VS integration, but simpler command line use- just need nuget.exe
- Using VS project for package definition has best VS integration, but then stuck dealing with complexities of msbuild
Next I’ll go over signing our package and pushing it to nuget.org.