0
votes

I'd like to create ONE NuGet package containing two builds with different platform (x86 and x64).

I've found a solution doing it by using "nuget.exe MyProject.nuspec". But since my project has many dependencies, writing the .nuspec manually is complex and prone to errors.

A much cleaner way is to use "dotnet pack MyProject.csproj". All dependencies are added automatically. My current approach looks like this:

msbuild MyProject.csproj -p:Configuration=Release -p:Platform="x86"
msbuild MyPeoject.csproj -p:Configuration=Release -p:Platform="x64"

dotnet pack MyProject.csproj -c Release -p:Platform="x86" --no-build -o ./
dotnet pack MyProject.csproj -c Release -p:Platform="x64" --no-build -o ./

The Result is one Package, containing the x64 build (I guess the x86 is overridden by the x64).

What I'm looking for is something like this:

msbuild MyProject.csproj -p:Configuration=Release -p:Platform="x86"
msbuild MyPeoject.csproj -p:Configuration=Release -p:Platform="x64"

dotnet pack MyProject.csproj -c Release -p:Platform="x86|x64" --no-build -o ./

Is there an argument to pack two builds into one package?

1

1 Answers

0
votes

In case of targeting multiple platforms you need to manually add a configuration to your csproj. This configuration contains the source path to the dll you want to add to your nuget package and the target folder in your nuget package.

Add this item group to your csproj:

<ItemGroup>
    <None Include="bin\x64\Release\net48\MyProject.dll" Pack="true" PackagePath="build\net48\x64\MyProject.dll" />
    <None Include="bin\x86\Release\net48\MyProject.dll" Pack="true" PackagePath="build\net48\x86\MyProject.dll" />
</ItemGroup>

Additionally you need to add a .target file to tell the nuget consuming project which dll needs to be copied from the nuget package to it's output folder. This .target file also includes a check to only work on x86 and x64 platforms. MSIL is not supported here.

Content of MyProject.targets:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="PlatformCheck_MyProject" BeforeTargets="InjectReference_MyProject" Condition="(('$(Platform)' != 'x86') and  ('$(Platform)' != 'x64'))">
        <Error  Text="$(MSBuildThisFileName) does not work correctly on '$(Platform)' platform. You need to specify platform 'x86' or 'x64'." />
    </Target>
    <Target Name="InjectReference_MyProject" BeforeTargets="ResolveAssemblyReferences">
        <ItemGroup>
            <Reference Include="MyProject">
                <HintPath>$(MSBuildThisFileDirectory)..\..\build\$(TargetFramework)\$(Platform)\MyProject.dll</HintPath>
            </Reference>
        </ItemGroup>
    </Target>
</Project>

Add these lines to your csproj to also add the .target file to the nuget package:

<ItemGroup>
    <Content Include="MyProject.targets" Pack="true" PackagePath="build\MyProject.targets" />
</ItemGroup>

After you added this configuration to your project you can build and pack with dotnet:

dotnet build MyProject.csproj -c=Release /p:Platform=x64 --no-incremental
dotnet build MyProject.csproj -c=Release /p:Platform=x86 --no-incremental
dotnet pack MyProject.csproj --no-build -c=Release -o=./