Build a NuGet package on Linux that is for the .NET Framework

I want to create a NuGet package that can simultaneously and explicitly point to the .NET Framework 4.6.2 and .Net Standard 1.5. Here is the abbreviated .csproj file from VS 2017:

<Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <TargetFrameworks>net462;netstandard1.5</TargetFrameworks> ... </PropertyGroup> </Project> 

When I execute the build and dotnet package commands from my local Windows machine, the NuGet package is created perfectly as expected.

However , when I try to execute the same dotnet commands on Linux, I get the following error:

/opt/dotnet/sdk/1.0.4/Microsoft.Common.CurrentVersion.targets(1111,5): MSB3644 error: reference assemblies for the ".NETFramework, Version = v4.6.2" framework were not found. To solve this problem, install the SDK or targeting package for this version of the framework or reconfigure your application to the version of the framework for which you install the SDK or Targeting Pack. Note that assemblies will be allowed from the Global Assembly Cache (GAC) and will be used at reference points. Therefore, your assembly cannot properly target the framework that you are planning.

Then it became clear to me that in the Linux box there are no regular assemblies of the .NET Framework (not to mention the fact that, it seems, I can not use Linux to build my NuGet. Package for the "Targeting Pack", but it is only available for windows.

With the threat of the highest sound, does anyone successfully create Linux NuGet packages that can target the .NET Framework?

+5
source share
1 answer

The .NET CLI distribution does not contain references to the .NET Framework, so its version of MSBuild cannot resolve the required compile-time resources. This script is tracked on GitHub , although it worked before switching to MSBuild (the CLI could use a mono link assembly).

There are several alternatives that you can use to create a library on computers other than Windows:

1. Use mono 5+ to create a library.

This is probably the most stable way.

Mono 5 and above contains the necessary build logic to create .NET Standar and .NET Core applications. On linux, mono msbuild may need to be installed as a separate package. Therefore, instead of the following commonly used commands

 dotnet restore dotnet build dotnet publish -c Release 

you must use mono msbuild to do the following:

 msbuild /t:Restore msbuild msbuild /t:Publish /p:Configuration=Release 

Package workaround for mono 5.2:

The only limitation is that mono (<5.2) cannot create NuGet packages out of the box, but there is a workaround using the NuGet.Build.Tasks.Pack NuGet package in a project that allows you to do msbuild /t:Pack /p:Configuration=Release , changing the project file in this way (especially pay attention to the deleted attribute Sdk="..." in the <Project> element):

 <Project> <PropertyGroup> <NuGetBuildTasksPackTargets>junk-value-to-avoid-conflicts</NuGetBuildTasksPackTargets> </PropertyGroup> <Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /> <!-- All your project other content here --> <ItemGroup> <PackageReference Include="NuGet.Build.Tasks.Pack" Version="4.0.0" PrivateAssets="All" /> </ItemGroup> <Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /> </Project> 

2. Use the .NET CLI and say MSBuild to use mono link assemblies.

When creating target net* frameworks, you can set the FrameworkPathOverride property as an environment variable as well as a property in the csproj file. It should point to a set of reference assemblies β€” monoreference assemblies can be used here. But some contain a special file (rename list) containing links to other directories that cannot follow the MSBuild version in the .NET CLI. However, it works in many scenarios:

 export FrameworkPathOverride=/usr/lib/mono/4.5/ dotnet build -f net45 

It was used, and documented by the F # team .

3. Use the NuGet package containing reference assemblies.

In some MyGet channels, Microsoft publishes NuGet packages containing referenced assemblies. They are not published or are not β€œofficial”, although this process may fail at a certain point in time. However, they plan to investigate this official path .

First create a NuGet.Config file in your solution directory for the following content to add a feed:

 <?xml version="1.0" encoding="utf-8"?> <configuration> <packageSources> <add key="dotnet-core" value="https://dotnet.myget.org/F/dotnet-core/api/v3/index.json" /> </packageSources> </configuration> 

You can then add a group of elements to add the PackageReference to the targeting package and PropertyGroup to set the path to the reference assemblies as follows:

 <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <OutputType>Exe</OutputType> <TargetFrameworks>netcoreapp1.1;net461</TargetFrameworks> </PropertyGroup> <PropertyGroup Condition=" '$(TargetFramework)' == 'net461' "> <RuntimeIdentifier>win7-x64</RuntimeIdentifier> <FrameworkPathOverride>$(NuGetPackageFolders)microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\</FrameworkPathOverride> </PropertyGroup> <ItemGroup Condition=" '$(TargetFramework)' == 'net461' "> <PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.6.1" Version="1.0.1" ExcludeAssets="All" PrivateAssets="All" /> </ItemGroup> </Project> 

You can change the RuntimeIdentifier for different platforms if you use your own resources (for example, to get .so files for Linux) or completely delete them when creating libraries.

+9
source

Source: https://habr.com/ru/post/1269241/


All Articles