NuGet 錯誤 NU5051

案例 1

一個專案有多個目標框架別名,且這些別名解析為同一個有效框架,而 pack 無法判斷哪些別名應該貢獻建置輸出、相依關係或框架參考給套件。

Issue

像以下這樣的專案有兩個別名(applebanana),兩者都解析為 net10.0

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>apple;banana</TargetFrameworks>
  </PropertyGroup>

  <PropertyGroup>
    <TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
    <TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
  </PropertyGroup>
</Project>

當你執行 dotnet pack時,NuGet 會提高 NU5051,因為它無法在同一套件中包含同一框架的重複建置輸出或依賴群組。

解決方案

每個有效框架中,除一個別名外,其他皆設IncludeBuildOutput為 和 falseSuppressDependenciesWhenPackingtrue 這會告訴 NuGet 哪個別名貢獻了建置輸出和依賴性。

  <!-- Let 'apple' contribute the build output and dependencies -->
  <PropertyGroup Condition="'$(TargetFramework)' == 'banana'">
    <IncludeBuildOutput>false</IncludeBuildOutput>
    <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
  </PropertyGroup>

如果別名有不同 FrameworkReference 項目,則在次要別名中使用 PrivateAssets="all" framework 參考來抑制這些別名。

案例 2

專案有執行時專用建置的別名,並希望將每個別名的建置輸出放入自訂的套件路徑中(例如, runtimes/<rid>/lib/<tfm>/)。

Issue

以下專案的主要別名為 net10.0linuxios 為次要別名。 三者皆以同一個有效框架為基礎:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net10.0;linux;ios</TargetFrameworks>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios' OR '$(TargetFramework)' == 'net10.0'">
    <TargetFrameworkIdentifier>.NETCoreApp</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v10.0</TargetFrameworkVersion>
    <TargetFrameworkMoniker>.NETCoreApp,Version=v10.0</TargetFrameworkMoniker>
  </PropertyGroup>
</Project>

執行 dotnet pack 會提高 NU5051,因為三個別名會產生同一框架的建置輸出和依賴關係。

解決方案

抑制次要別名的預設建置輸出與相依關係,並用 TargetsForTfmSpecificContentInPackage 來將次要別名的組件放入自訂套件路徑中:

  <PropertyGroup>
    <TargetsForTfmSpecificContentInPackage>$(TargetsForTfmSpecificContentInPackage);GetMyPackageFiles</TargetsForTfmSpecificContentInPackage>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios'">
    <IncludeBuildOutput>false</IncludeBuildOutput>
    <SuppressDependenciesWhenPacking>true</SuppressDependenciesWhenPacking>
  </PropertyGroup>

  <Target Name="GetMyPackageFiles">
    <ItemGroup Condition="'$(TargetFramework)' == 'linux' OR '$(TargetFramework)' == 'ios'">
      <TfmSpecificPackageFile Include="$(OutputPath)$(AssemblyName).dll">
        <PackagePath>runtimes/$(TargetFramework)/lib/net10.0</PackagePath>
      </TfmSpecificPackageFile>
    </ItemGroup>
  </Target>

在此配置中, net10.0 貢獻預設 lib/net10.0/ 建置輸出與相依,而 linuxios 分別將組裝檔置於 runtimes/linux/lib/net10.0/runtimes/ios/lib/net10.0/ 下。

欲了解更多關於重複框架多目標的資訊,請參閱 「多框架目標化」。 欲了解更多關於背包擴充性的資訊,請參見 背包目標