Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different NuGet package based on operating system

I have a test project in dotnet 2.1 that needs to work across multiple platforms (specifically, windows and linux-based systems) as well as access DB2 databases.

IBM provides separate NuGet packages for different operating systems:

  1. IBM.Data.DB2.Core
  2. IBM.Data.DB2.Core-lnx
  3. IBM.Data.DB2.Core-osx

How can I specify in my .csproj file that I want to use different packages based on the operating system?

Passing in the RuntimeIdentifier (dotnet publish ... -r linux-x64) is possible, but I am unsure how to leverage that information inside the csproj. I am also not opposed to using the Choose/When construct, but don't know how to infer what system is trying to build the project.

like image 610
Muttonchop Avatar asked Oct 02 '18 16:10

Muttonchop


3 Answers

Use IsOsPlatform(platform) MSBuild property function:

<PackageReference Include="NetVips.Native.linux-x64" Version="8.9.1" Condition="$([MSBuild]::IsOsPlatform('Linux'))" />
<PackageReference Include="NetVips.Native.osx-x64" Version="8.9.1" Condition="$([MSBuild]::IsOsPlatform('OSX'))" />
<PackageReference Include="NetVips.Native.win-x64" Version="8.9.1" Condition="$([MSBuild]::IsOsPlatform('Windows'))" />
like image 178
Oleg Gliznutsa Avatar answered Nov 18 '22 08:11

Oleg Gliznutsa


I ended up using Configuration and the Choose/When paradigm.

A simple example .csproj would be

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <Configurations>Debug;Release;Docker</Configurations>
    <Platforms>AnyCPU;x64</Platforms>
  </PropertyGroup>

  ... the rest of your .csproj and dependencies ...

  <Choose>
    <When Condition=" '$(Configuration)'=='Docker' ">
      <ItemGroup>
        <PackageReference Include="IBM.Data.DB2.Core-lnx" Version="1.2.2.100" />
      </ItemGroup>
    </When>
    <Otherwise>
      <ItemGroup>
        <PackageReference Include="IBM.Data.DB2.Core" Version="1.2.2.100" />
      </ItemGroup>
    </Otherwise>
  </Choose>

</Project>

On the command line I would run: dotnet build /your/project.csproj -c <yourConfigurationName>.

I found this site useful for helping set this up in visual studio 2017.

like image 30
Muttonchop Avatar answered Nov 18 '22 10:11

Muttonchop


I just had to do the same thing with IBM.EntityFrameworkCore libraries (which use IBM.Data.DB2.Core), here's how I got it to work.

Add RuntimeIdentifiers, otherwise the RuntimeIdentifier variable will be empty for dependent projects:

<RuntimeIdentifiers>win-x64;osx-x64;linux-x64</RuntimeIdentifiers>

If RuntimeIdentifier is set, use that to determine which package to install, otherwise just go based on the operating system. This way we can use dotnet build --runtime linux-x64 or Visual Studio to build.

<Choose>
  <When Condition="$(RuntimeIdentifier) != ''">
    <ItemGroup>
      <PackageReference Condition="$(RuntimeIdentifier.StartsWith('win'))" Include="IBM.EntityFrameworkCore" Version="3.1.0.300" />
      <PackageReference Condition="$(RuntimeIdentifier.StartsWith('osx'))" Include="IBM.EntityFrameworkCore-osx" Version="3.1.0.300" />
      <PackageReference Condition="$(RuntimeIdentifier.StartsWith('linux'))" Include="IBM.EntityFrameworkCore-lnx" Version="3.1.0.300" />
    </ItemGroup>
  </When>
  <Otherwise>
    <ItemGroup>
      <PackageReference Condition="$([MSBuild]::IsOSPlatform('Windows'))" Include="IBM.EntityFrameworkCore" Version="3.1.0.300" />
      <PackageReference Condition="$([MSBuild]::IsOSPlatform('OSX'))" Include="IBM.EntityFrameworkCore-osx" Version="3.1.0.300" />
      <PackageReference Condition="$([MSBuild]::IsOSPlatform('Linux'))" Include="IBM.EntityFrameworkCore-lnx" Version="3.1.0.300" />
    </ItemGroup>
  </Otherwise>
</Choose>

I also wanted to copy the license file from the project to the nuget directory:

<Target Condition="$([MSBuild]::IsOSPlatform('Windows'))" Name="PreBuildWin" BeforeTargets="BeforeBuild">
  <Copy Condition="$(RuntimeIdentifier) == ''" SourceFiles="db2consv_is.lic" DestinationFolder="$(USERPROFILE)\.nuget\packages\ibm.data.db2.core\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('win'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(USERPROFILE)\.nuget\packages\ibm.data.db2.core\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('osx'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(USERPROFILE)\.nuget\packages\ibm.data.db2.core-osx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('linux'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(USERPROFILE)\.nuget\packages\ibm.data.db2.core-lnx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
</Target>

<Target Condition="$([MSBuild]::IsOSPlatform('OSX')) Or $([MSBuild]::IsOSPlatform('Linux'))" Name="PreBuildUnix" BeforeTargets="BeforeBuild">
  <Copy Condition="$(RuntimeIdentifier) == '' And $([MSBuild]::IsOSPlatform('OSX'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(HOME)\.nuget\packages\ibm.data.db2.core-osx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier) == '' And $([MSBuild]::IsOSPlatform('Linux'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(HOME)\.nuget\packages\ibm.data.db2.core-lnx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('win'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(HOME)\.nuget\packages\ibm.data.db2.core\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('osx'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(HOME)\.nuget\packages\ibm.data.db2.core-osx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
  <Copy Condition="$(RuntimeIdentifier.StartsWith('linux'))" SourceFiles="db2consv_is.lic" DestinationFolder="$(HOME)\.nuget\packages\ibm.data.db2.core-lnx\3.1.0.300\buildTransitive\clidriver\license" SkipUnchangedFiles="true" />
</Target>

dotnet SDK used: 3.1.402

like image 35
Shahin Dohan Avatar answered Nov 18 '22 08:11

Shahin Dohan