案例 1
一個專案有多個目標框架別名,且這些別名解析為同一個有效框架,而 pack 無法判斷哪些別名應該貢獻建置輸出、相依關係或框架參考給套件。
Issue
像以下這樣的專案有兩個別名(apple 和 banana),兩者都解析為 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為 和 falseSuppressDependenciesWhenPacking 。true 這會告訴 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.0 和 linuxios 為次要別名。 三者皆以同一個有效框架為基礎:
<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/ 建置輸出與相依,而 linux 和 ios 分別將組裝檔置於 runtimes/linux/lib/net10.0/ 和 runtimes/ios/lib/net10.0/ 下。