我想使用 dotnet CLI 创建一个可以针对以下框架的 nuget 包:
net462
、net48
、net8.0
。我的库没有依赖项(即它不需要任何其他 NuGet 包或项目)。
我编写了一个 powershell 构建脚本来构建我的库,以便创建三个 DLL。 构建脚本的相关部分如下:
dotnet build TestCI.sln -c "net462" -f "net462" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
dotnet build TestCI.sln -c "net48" -f "net48" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
dotnet build TestCI.sln -c "net8.0" -f "net8.0" -p:Platform=x64 -p:Version=$($MAJOR_MINOR_PATCH) --no-restore --disable-build-servers
这会产生以下文件夹结构:
bin
|-- net8.0-x64
|-- |-- TestCI.dll
|-- net48-x64
|-- |-- TestCI.dll
|-- net462-x64
|-- |-- TestCI.dll
当用DotPeek反编译时,我可以看到每个DLL包含:
到目前为止,一切都很好。
我想将这三个 DLL 打包到一个 nuget 包中,该包可以仅使用我的 SDK 样式
net462
文件和 CLI 部署到 net48
、net8.0
和 .csproj
运行时。
我的长期目标是使用 GitHub 操作自动构建和打包这个库(以及其他库)——因此是脚本。但是,ehcin 我运行以下 dotnet pack 命令:
dotnet pack TestCI\TestCI.csproj -p:PackageVersion=$($MAJOR_MINOR_PATCH) --no-restore --no-build
生成的 NuGet 包包含全部指定
net8.0
作为目标框架的 DLL。 f
TestCI.nupkg
|-- lib
|-- |-- net462
|-- |-- |-- TestCI.dll
|-- |-- net48
|-- |-- |-- TestCI.dll
|-- |-- net8.0
|-- |-- |-- TestCI.dll
但是,在检查每个 DLL 时,无论 lib 子目录如何,它们都包含以下行:
[assembly: TargetFramework(".NETCoreApp,Version=v8.0", FrameworkDisplayName = ".NET 8.0")]
即尽管我知道每个 DLL 都是针对不同的目标框架构建的,并且已在
bin
目录中的每个 DLL 上确认了这一点,但打包的 DLL 之间似乎没有区别。
到目前为止,我已经尝试了 dotnet pack 命令的几种变体,甚至包括一个基本的 nuspec 文件:
dotnet pack TestCI\TestCI.csproj -p:PackageVersion=$($MAJOR_MINOR_PATCH) -p:NuspecFile=.nuspec --no-restore --no-build
(有关多目标 nuget 包,请参阅这篇文章)
这可行,但是我不喜欢这个解决方案,原因如下:
.csproj
文件中包含的所有内容,以保持我的存储库更干净、更简单。我还确保我的
.csproj
文件包含以下元素:
<TargetFrameworks>net462;net48;net8.0</TargetFrameworks>
.nuspec
文件吗?.csproj
文件和 CLI 来实现我所描述的目标?[2024-07-26]
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>TestCI</RootNamespace>
<Company>XYZ</Company>
<Copyright>XYZ (c) 2024</Copyright>
<Version>0.0.1</Version>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>net462;net48;net8.0-windows</TargetFrameworks>
<Configurations>net48;net462;net8.0-windows</Configurations>
<Platforms>x64</Platforms>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\$(Configuration)-$(Platform)\</OutputPath>
</PropertyGroup>
<PropertyGroup>
<ProductName>$(RootNamesapce)</ProductName>
<OutputType>Library</OutputType>
<IsTestProject>False</IsTestProject>
</PropertyGroup>
<PropertyGroup>
<PackageID>$(RootNamespace)</PackageID>
<PackageVersion>$(Version)</PackageVersion>
<IsPackable>True</IsPackable>
<IncludeBuildOutput>True</IncludeBuildOutput>
<GeneratePackageOnBuild>False</GeneratePackageOnBuild>
<PackageOutputPath>..\nupkg</PackageOutputPath>
<PackageDescription>XYZ</PackageDescription>
<RepositoryUrl>XYZ</RepositoryUrl>
</PropertyGroup>
<PropertyGroup>
<DefineConstants>TRACE;DEBUG</DefineConstants>
<DebugType>embedded</DebugType>
<OutDir>bin\$(Configuration)-$(Platform)</OutDir>
</PropertyGroup>
<PropertyGroup>
<GenerateAssemblyInfo>True</GenerateAssemblyInfo>
<AssemblyName>$(RootNamespace)</AssemblyName>
<AssemblyVersion>$(Version).0</AssemblyVersion>
<FileVersion>$(Version).0</FileVersion>
</PropertyGroup>
<ItemGroup>
<Compile Remove=".github\**" />
<EmbeddedResource Remove=".github\**" />
<None Remove=".github\**" />
</ItemGroup>
</Project>
经过几个月的研究、尝试和错误,我找到了解决这个问题的方法。 关键是删除以下元素:
<Configurations>net48;net462;net8.0-windows</Configurations>
<PlatformTarget>x64</PlatformTarget>
<OutputPath>bin\$(Configuration)-$(Platform)\</OutputPath>
<OutDir>bin\$(Configuration)-$(Platform)</OutDir>
删除这些元素允许
dotnet build
为每个目标框架创建二进制文件,并允许 dotnet pack
正确打包 DLL 以供一般使用。
<Configurations>
是不必要的并且引起了问题。 MSBuuild 默认值 Debug
和 Release
效果最佳。
<PlatformTarget>
事实证明是不必要的。
<OutputPath>
更改二进制文件的放置位置。 删除它允许 MSBuild 使用其默认文件夹结构进行操作,从而解决了构建并发问题。
<OutDir>
引起的问题与 <OutputPath>
引起的问题类似。当仅使用 MSBuild 默认值时,两者都被证明是不必要的。
这里学到的最大教训是少即是多。 MSBuild 和 dotnet CLI 是很好的工具。 别挡道,让他们做饭!