NuGet 包的多框架目标

问题描述 投票:0回答:1

背景 - 我的构建脚本

我想使用 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包含:

  1. 我希望/期望看到的来自我的 .csproj 的信息
  2. 正确的目标框架版本和运行时标识符

到目前为止,一切都很好。

目标 - 用于多个框架目标的 NuGet 包

我想将这三个 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 包,请参阅这篇文章

这可行,但是我不喜欢这个解决方案,原因如下:

  1. 软件包版本未正确应用于此软件包(结果为 0.0.0),并且我需要能够出于 CICD 目的控制版本控制信息。
  2. 我更愿意保留 SDK 风格的
    .csproj
    文件中包含的所有内容,以保持我的存储库更干净、更简单。

我还确保我的

.csproj
文件包含以下元素:

<TargetFrameworks>net462;net48;net8.0</TargetFrameworks>    

询问

  1. 我是否误解了.NET 的工作原理?我是否不必要地使我的工作流程复杂化?
  2. 有人遇到过类似的情况吗?
  3. 我需要使用
    .nuspec
    文件吗?
  4. 是否可以仅使用 SDK
    .csproj
    文件和 CLI 来实现我所描述的目标?

编辑

[2024-07-26]

  • 我正在使用 JetBrains DotPeek 来检查 NuGet 包
  • 我正在使用的 csproj 文件包含在下面:
<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>
.net msbuild nuget-package dotnet-cli
1个回答
0
投票

解决方案

经过几个月的研究、尝试和错误,我找到了解决这个问题的方法。 关键是删除以下元素:

<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 是很好的工具。 别挡道,让他们做饭!

© www.soinside.com 2019 - 2024. All rights reserved.