5

我有一个构建项目的脚本,输出 .NET 4.0 程序集。

该项目包括来自 NuGet 的 NLog。所以项目文件中的引用如下所示:

<Reference Include="NLog">
  <HintPath>..\packages\NLog.2.0.1.2\lib\NLog\net40\NLog.dll</HintPath>
</Reference>

我的 packages.config 看起来像这样:

<packages>
  <package id="NLog" version="2.0.1.2" targetFramework="net40" />
</packages>

该项目将在 NuGet 上发布,现在我想更新构建脚本,以便它还可以构建 .NET 4.5 程序集。

现在,我知道我可以传递/p:TargetFrameworkVersion="4.5"msbuild.NET 4.5 并将其作为目标 - 但这仍然会重新构建 .NET 4.0 NLog 程序集。

如何使用正确版本的 NuGet 依赖项为目标框架构建它?

4

1 回答 1

1

前段时间在这里有完全相同的要求,但没有找到“纯”的 NuGet 解决方案。我怀疑有。唯一的选择似乎是维护不同的项目文件(或其中的一部分)——对于大量代码库来说绝对是不行的。

相反,我所做的只是在所有项目中以 4.5 为目标,并有一个相当简单的 msbuild 脚本来创建项目的副本及其所有 NuGet 配置,以针对其他版本的 .Net。基本上它只是枚举所有 .csproj 文件,从net45->net40字符串中进行查找/替换并将它们保存在不同的名称下。包配置/目标/解决方案文件的同上。

这里几乎是完整的 MSBuild 目标:

<Target Name="MakeNet40Projects">
  <ItemGroup>
    <SourceProjs Include="$(MyProjectDir)*\*\*.csproj" Exclude="$(MyProjectDir)\*\*\*.Net40.csproj"/>
      ...
    <SourceConfigs Include="$(MyProjectDir)*\*\packages.config"/>
      ...
    <DestProjs Include="%(SourceProjs.RootDir)%(SourceProjs.Directory)%(SourceProjs.FileName).Net40.csproj"/>
    <DestConfigs Include="%(SourceConfigs.RootDir)%(SourceConfigs.Directory)%(SourceConfigs.FileName).Net40.config"/>
  </ItemGroup>
  <PropertyGroup>
    <OldPackages>packages.config</OldPackages>
    <NewPackages>packages.Net40.config</NewPackages>
    <OldTargets>NuGet.targets</OldTargets>
    <NewTargets>NuGet.Net40.targets</NewTargets>
    <OldProj>\.csproj</OldProj>
    <NewProj>.Net40.csproj</NewProj>
  </PropertyGroup>

  <Copy SourceFiles="@(SourceProjs)" DestinationFiles="@(DestProjs)"/>
  <FileUpdate Files="@(DestProjs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldTargets)" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
  <FileUpdate Files="@(DestProjs)" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>

  <Copy SourceFiles="@(SourceConfigs)" DestinationFiles="@(DestConfigs)"/>
  <FileUpdate Files="@(DestConfigs)" Regex="[Nn][Ee][Tt]45" ReplacementText="net40" Encoding="utf-8"/>

  <Copy SourceFiles="$(MsBuildThisFileDirectory)\.nuget\$(OldTargets)" DestinationFiles="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\.nuget\$(NewTargets)" Regex="$(OldPackages)" ReplacementText="$(NewPackages)" Encoding="utf-8"/>

  <Copy SourceFiles="$(MsBuildThisFileDirectory)\my.sln" DestinationFiles="$(MsBuildThisFileDirectory)\my.Net40.sln"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="$(OldProj)" ReplacementText="$(NewProj)" Encoding="utf-8"/>
  <FileUpdate Files="$(MsBuildThisFileDirectory)\my.Net40.sln" Regex="NuGet\.targets" ReplacementText="$(NewTargets)" Encoding="utf-8"/>
</Target>

运行此程序后,每个项目都有一个 .Net40.csproj、一个 .Net40.sln、一个用于解决方案的 Nuget.Net40.targets 和 packages.Net40.config 文件,所有这些都可以构建了。到目前为止,一切都很好。

不过小问题:packages.config在 Nuget.exe 中被硬编码为字符串,因此它不会packages.net40.config在命令行上接受。它是“算法”的一部分,用于决定传递给-install算法的路径是实际的包配置还是包 ID。哈哈。我对此提出了一个问题,但没有答案。无论如何,我不打算让这破坏乐趣,所以我在源代码中进行了单行调整,让它接受以 . 结尾的任何内容.config,构建它并立即使用该 Nuget.exe。

于 2013-08-01T19:06:15.400 回答