Dot-Net

在 Linux 上建構面向 .NET Framework 的 NuGet 包

  • June 27, 2017

我想創建一個 NuGet 包,它可以同時明確地針對*.NET* Framework 4.6.2 和 .Net Standard 1.5。這是來自 VS 2017 的縮寫 .csproj 文件:

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

 <PropertyGroup>
   <TargetFrameworks>net462;netstandard1.5</TargetFrameworks>
   ...
 </PropertyGroup>

</Project>

當我從本地 Windows 機器執行 dotnet build 和 pack 命令時,NuGet 包的創建完全符合預期。

但是,當我嘗試在 Linux 上執行相同的 dotnet 命令時,我收到以下錯誤:

/opt/dotnet/sdk/1.0.4/Microsoft.Common.CurrentVersion.targets(1111,5):錯誤 MSB3644:找不到框架“.NETFramework,Version=v4.6.2”的參考程序集。要解決此問題,請為此框架版本安裝 SDK 或 Targeting Pack,或者將您的應用程序重新定位到已安裝 SDK 或 Targeting Pack 的框架版本。請注意,程序集將從全域程序集記憶體 (GAC) 中解析,並將用於代替引用程序集。因此,您的程序集可能無法正確定位於您想要的框架。

然後我恍然大悟,Linux 機器上沒有任何正常的 .NET Framework 程序集(更不用說。因此,我似乎無法使用 Linux 來建構我的 NuGet 包。我四處搜尋“ Targeting Pack”,但它僅適用於 Windows。

冒著聽起來幼稚的風險,是否有人在 Linux 上成功建構了可以針對 .NET Framework 的 NuGet 包?

.NET CLI 的分發不包含任何 .NET Framework 的參考程序集,因此其 MSBuild 版本無法解析所需的編譯時資產。這種情況在 GitHub 上進行了跟踪,並且在遷移到 MSBuild 之前已經有效(CLI 可以使用 mono 的參考程序集)。

雖然有一些替代方案可用於在非 Windows 機器上建構庫:

1.使用mono 5+建庫。

這可能是最穩定的路徑。

Mono 5 及更高版本包含建構 .NET Standard 和 .NET Core 應用程序所需的建構邏輯。在 linux 上,mono 的 msbuild 可能需要作為單獨的包安裝。所以代替下面常用的命令

dotnet restore
dotnet build
dotnet publish -c Release

您將使用 mono 的 msbuild 來執行以下操作:

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

單聲道 < 5.2 的打包解決方法:

唯一的限制是單聲道(< 5.2)無法立即生成 NuGet 包,但有一種解決方法涉及在項目中使用NuGet.Build.Tasks.PackNuGet 包,它允許您msbuild /t:Pack /p:Configuration=Release通過像這樣修改項目文件來完成(特別注意刪除的Sdk="..."屬性&lt;Project&gt;元素):

&lt;Project&gt;
 &lt;PropertyGroup&gt;
   &lt;NuGetBuildTasksPackTargets&gt;junk-value-to-avoid-conflicts&lt;/NuGetBuildTasksPackTargets&gt;
 &lt;/PropertyGroup&gt;
 &lt;Import Project="Sdk.props" Sdk="Microsoft.NET.Sdk" /&gt;

 &lt;!-- All your project's other content here --&gt;

 &lt;ItemGroup&gt;
   &lt;PackageReference Include="NuGet.Build.Tasks.Pack" Version="4.0.0" PrivateAssets="All" /&gt;
 &lt;/ItemGroup&gt;
 &lt;Import Project="Sdk.targets" Sdk="Microsoft.NET.Sdk" /&gt;
&lt;/Project&gt;

2. 使用 .NET CLI 並告訴 MSBuild 使用 mono 的參考程序集。

在為net*目標框架建構時,您可以將FrameworkPathOverride屬性設置為環境變數或 csproj 文件中的屬性。它需要指向一組參考程序集——這裡可以使用mono的參考程序集。但有些包含一個特殊文件(redist 列表),其中包含對 .NET CLI 中的 MSBuild 版本無法遵循的其他目錄的引用。但它確實適用於很多場景:

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

F# 團隊使用並記錄了這一點。

3. 使用包含參考程序集的 NuGet 包。

在某些 MyGet 源上,Microsoft 發布了包含參考程序集的 NuGet 包。雖然它們沒有發布或“官方”,但這個過程可能會在某個時間點失敗。不過他們確實計劃調查使這條路徑正式化

首先在您的解決方案目錄中創建一個 NuGet.Config 文件,其中包含以下內容以添加提要:

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

然後,您可以添加一個項目組以將其添加PackageReference到目標包和一個PropertyGroup以設置引用程序集的路徑,如下所示:

&lt;Project Sdk="Microsoft.NET.Sdk"&gt;

 &lt;PropertyGroup&gt;
   &lt;OutputType&gt;Exe&lt;/OutputType&gt;
   &lt;TargetFrameworks&gt;netcoreapp1.1;net461&lt;/TargetFrameworks&gt;
 &lt;/PropertyGroup&gt;

 &lt;PropertyGroup Condition=" '$(TargetFramework)' == 'net461' "&gt;
   &lt;RuntimeIdentifier&gt;win7-x64&lt;/RuntimeIdentifier&gt;
   &lt;FrameworkPathOverride&gt;$(NuGetPackageFolders)microsoft.targetingpack.netframework.v4.6.1\1.0.1\lib\net461\&lt;/FrameworkPathOverride&gt;
 &lt;/PropertyGroup&gt;

 &lt;ItemGroup Condition=" '$(TargetFramework)' == 'net461' "&gt;
   &lt;PackageReference Include="Microsoft.TargetingPack.NETFramework.v4.6.1" Version="1.0.1" ExcludeAssets="All" PrivateAssets="All" /&gt;
 &lt;/ItemGroup&gt;

&lt;/Project&gt;

RuntimeIdentifier如果您使用本機資產(例如獲取.solinux 文件)或在建構庫時將其完全刪除,您可以針對不同的平台進行更改。

引用自:https://stackoverflow.com/questions/44770702