【问题标题】:How can I compile a .NET Standard 2.0 class library by directly invoking the C# complier using only the .NET Core SDK?如何通过仅使用 .NET Core SDK 直接调用 C# 编译器来编译 .NET Standard 2.0 类库?
【发布时间】:2019-12-20 10:07:24
【问题描述】:

在 Visual Studio 2019 中编译 .NET Standard 2.0 类库项目时,会调用 C# 编译器 (csc.exe) 来编译项目。如果我检查构建日志,使用的命令行看起来像这样(为便于阅读添加了换行符):

C:\Program Files (x86)\Microsoft Visual Studio\2019\Professional\MSBuild\Current\Bin\Roslyn\csc.exe
/noconfig
/unsafe-
/checked-
/nowarn:1701,1702,1701,1702,2008
/nostdlib+
/errorreport:prompt
/warn:4
/define:TRACE;DEBUG;NETSTANDARD;NETSTANDARD2_0
/errorendlocation
/preferreduilang:en-US

<
A whole slew of /reference: switches that point to:
    %PROGRAMFILES%\dotnet\sdk\NuGetFallbackFolder\netstandard.library
    \2.0.3\build\netstandard2.0\ref
>

/debug+
/debug:portable
/filealign:512
/optimize-
/out:obj\Debug\netstandard2.0\ClassLibrary1.dll
/target:library
/warnaserror-
/utf8output
/deterministic+
Class1.cs
/warnaserror+:NU1605

现在,假设我在一台没有任何版本的 Visual Studio 的机器上。进一步假设我已将 .NET Core SDK 解压缩到该机器上的目录中。如何使用正确的引用程序集列表重新创建上述/reference: 开关列表?我可以阅读的魔法清单在哪里可以让我组合该列表?

生成上述命令行的.csproj有以下内容:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

</Project>

可以看到,项目本身没有程序集引用标记,因此引用列表似乎只是位于上述目录中的文件列表。我想知道的是该文件列表是如何组装到 VS 的该目录中的,以及如何仅使用 .NET Core SDK 来模拟它。

请注意,出于技术原因,我需要直接调用 C# 编译器;以任何方式使用 MSBuild 都不是这个特定问题的可接受解决方案。这意味着对 .csproj 文件使用 dotnet build 不是此特定项目的选项。

【问题讨论】:

  • “我可以阅读的魔法清单在哪里,可以让我组装那个清单?” MSBuild 将从*.csproj 文件生成它。当您在 Visual Studio 中开始构建时,VS 不会直接运行 csc,而是在 *.csproj 文件上调用 MSBuild,然后运行 ​​csc
  • @Dai 我不确定它确实如此。该列表似乎只是目录中文件的完整列表。由于该目录位于%PROGRAMFILES% 中,因此不会在编译时将文件复制到该目录中。 .csproj 文件没有枚举这些引用,因为它们都是“框架”引用程序集,而不是第三方包程序集。但足够公平。那么,这一代人的目标是什么?
  • 您可能只是懒惰并引用netstandard2.0中的所有程序集。当然,矫枉过正,但除非项目明确为某些引用使用包,否则不会造成麻烦。我很确定确定这些程序集所在的实际文件夹是直接从毁灭之山发出的纯黑魔法(也就是说,MSBuild“以某种方式”确定它)。
  • 您是否尝试过在该 .csproj 文件上运行 msbuild 并查看它的作用?我很确定神奇之处在于上面的&lt;TargetFramework&gt; 标签;您不必手动管理该引用列表,构建工具会为您完成。
  • 为什么 MSBuild 不可接受?

标签: c# .net-core msbuild .net-standard


【解决方案1】:

在 .NET Core 中,依赖项是项目或 NuGet 包。有几个 NuGet 包被隐式引用。例如,如果您的目标 netstandard2.0,您将引用 NETStandard.Library 的 1.6.1 版本。

所有这些规则都编码在dotnet/sdk 存储库中。此存储库包含跨 .NET CLI 和 Visual Studio 共享的代码,因为这两种产品都需要有关 .NET Core 构建过程的基本知识。比如对 NETStandard.Library 1.6.1 的依赖被编码在Microsoft.NET.Sdk.DefaultItems.targets

您要查找的魔法命令是dotnet restore。这将解析所有引用(NuGet 和项目)并创建文件,例如 obj\projects.assets.json,其中列出了项目的所有编译时程序集引用。还有其他文件,比如{projectname}.nuget.*,里面有相关信息。

因此,对于 Bazel,您可以采取以下几种方式:

  • 运行dotnet restore,解析project.assets.json的输出。
  • 尝试使用来自 Bazel 的 dotnet/sdk 中的逻辑,就像 Visual Studio、MSBuild 和 .NET CLI 一样。这很难,因为dotnet/sdk 是用 C# 和 MSBuild 编写的,而 Bazel 可能对此一无所知。
  • 尝试在 Bazel 中复制 dotnet/sdk 中的逻辑。这将是一项艰巨的任务。

【讨论】:

    猜你喜欢
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-09
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    相关资源
    最近更新 更多