MSBuild multiple dll in a single NuGet package

Viewed 8633

I have a Visual Studio 2017 solution that contains two projects:

Foo.csproj
Foo.Core.csproj

Both of these projects target multiple frameworks: net452;netstandard1.2

Foo.csproj includes a project reference to Foo.Core.csproj:

<ItemGroup>
    <ProjectReference Include="..\Foo.Core\Foo.Core.csproj" />
</ItemGroup>

When I generate a NuGet package for Foo.csproj, I want the nupkg file to include both of these assemblies.

What is currently happening is that the NuGet package that gets created has Foo.dll and then a NuGet dependency on Foo.Core (which doesn't exist).

How can I generate a single NuGet package using msbuild that will include both assemblies?

For reference this is the command I am currently using (which is not working how I want it to):

msbuild /p:restore,pack Foo.csproj
4 Answers

The second option that Martin Ullrich mentioned is the only one that works out of the box with .NET Standard that allows to "Generate NuGet package on build" as an integral part of the build.

However like he mentions it has a "hard coded" dependency on a dll with an exact name that you expect to be there (on the output folder) which might bite you in the future. I've found a better alternative which worked for me in .NET Standard without the need of any other modification on this post.

I'll quote it here for completeness. First you edit your csproj and define the PrivateAssets tag for the reference that you'd like to include:

<ItemGroup>
  <ProjectReference Include="..\ClassLibrary1\ClassLibrary1.csproj">
    <PrivateAssets>all</PrivateAssets>
  </ProjectReference>
</ItemGroup>

Then you add this to your csproj:

<PropertyGroup>
<TargetsForTfmSpecificBuildOutput>$(TargetsForTfmSpecificBuildOutput);CopyProjectReferencesToPackage</TargetsForTfmSpecificBuildOutput>
</PropertyGroup>

<Target Name="CopyProjectReferencesToPackage" DependsOnTargets="ResolveReferences">
    <ItemGroup>
        <BuildOutputInPackage Include="@(ReferenceCopyLocalPaths->WithMetadataValue('ReferenceSourceTarget', 'ProjectReference')->WithMetadataValue('PrivateAssets', 'all'))" />
    </ItemGroup>
</Target>

That post also shows how to include the PDBs in the NuGet package option if necessary (which I omitted here).

Been struggling with the same issue and none of the suggested workarounds worked (https://github.com/NuGet/Home/issues/3891) and I couldn't change the csproj to use the new SDK coming with .netcore.

Luckily the nuget pack command comes with the -IncludeReferencedProjects option (ref: https://docs.microsoft.com/en-us/nuget/tools/cli-ref-pack) which does exactly that: "Indicates that the built package should include referenced projects either as dependencies or as part of the package. If a referenced project has a corresponding .nuspec file that has the same name as the project, then that referenced project is added as a dependency. Otherwise, the referenced project is added as part of the package."

Regardless of the *.nuspec file (not needed here) , add -IncludeReferencedProjects to the pack command and the referenced project dlls will be included along with the nuget dll.

nuget.exe pack yourProject.csproj -IncludeReferencedProjects

I have recently discovered that you CANNOT set defaults for the Nuspec Properties you want to replace in the msbuild command line e.g. if a metadata value is set in the .csproj file of "<Version>2.0.0</Version>" and you run:

msbuild myproject.csproj -t:pack -p:Configuration=Release -p:NuspecProperties=Configuration=Release;PackageVersion=1.2.3

Your .nupgk file will have the version 2.0.0 still. Annoyingly the MS documentation is not clear on this and no error is displayed.

Related