如何仅使用.NET Core SDK直接调用C#complier来编译.NET标准2.0类库?

如何仅使用.NET Core SDK直接调用C#complier来编译.NET标准2.0类库?,c#,.net-core,msbuild,.net-standard,C#,.net Core,Msbuild,.net Standard,在Visual Studio 2019中编译.NET标准2.0类库项目时,会调用C#编译器(csc.exe)来编译该项目。如果我检查构建日志,所使用的命令行如下所示(为了可读性增加了换行符): 可以看到,项目本身中没有程序集引用标记,因此引用列表似乎只是位于上述目录中的文件列表。我想知道的是如何将文件列表组合到VS的目录中,以及如何仅使用.NET Core SDK模拟它 请注意,我需要直接调用C#编译器有一些技术原因;以任何方式使用MSBuild都不是解决此特定问题的可接受的解决方案。这意味着对

在Visual Studio 2019中编译.NET标准2.0类库项目时,会调用C#编译器(
csc.exe
)来编译该项目。如果我检查构建日志,所使用的命令行如下所示(为了可读性增加了换行符):

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


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

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

所有这些规则都在存储库中编码。此存储库包含跨.NET CLI和Visual Studio共享的代码,因为这两种产品都需要有关.NET核心构建过程的最新知识。例如,对NETStandard.Library 1.6.1的依赖项编码为

您正在寻找的神奇命令是
dotnetrestore
。这将解析所有引用(NuGet和project),并创建文件,如
obj\projects.assets.json
,其中列出了项目的所有编译时程序集引用。还有其他文件,如
{projectname}.nuget.*
,包含相关信息

因此,对于Bazel来说,有两条路可以走:

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

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

所有这些规则都在存储库中编码。此存储库包含跨.NET CLI和Visual Studio共享的代码,因为这两种产品都需要有关.NET核心构建过程的最新知识。例如,对NETStandard.Library 1.6.1的依赖项编码为

您正在寻找的神奇命令是
dotnetrestore
。这将解析所有引用(NuGet和project),并创建文件,如
obj\projects.assets.json
,其中列出了项目的所有编译时程序集引用。还有其他文件,如
{projectname}.nuget.*
,包含相关信息

因此,对于Bazel来说,有两条路可以走:

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

“我可以读取的让我组装该列表的魔法清单在哪里?”MSBuild将从
*.csproj
文件生成该清单。在Visual Studio中启动生成时,VS不会直接运行
csc
,而是调用
*.csproj
文件上的
MSBuild
,该文件反过来运行
csc
@Dai,但我不确定它是否会这样做。该列表似乎只是目录中文件的完整列表。由于目录位于
%PROGRAMFILES%
中,因此在编译时不会将文件复制到该目录中。.csproj文件不枚举这些引用,因为它们都是“框架”引用程序集,而不是第三方包程序集。但这很公平。那么,生成的目标是什么呢?您可能只是懒惰地引用netstandard2.0中的所有程序集。当然,这是过分的,但除非项目明确地将包用于某些引用,否则不会造成麻烦。我敢肯定,确定这些程序集所在的实际文件夹纯粹是直接从Mount Doom(也就是说,MSBuild“以某种方式”确定它)中产生的一种黑暗魔法。您是否尝试过在该.csproj文件上运行MSBuild并查看它的功能?我敢肯定,魔法就在那里的
标签上;您不必手动管理该引用列表,生成工具将为您执行此操作。为什么MSBuild不可接受?“我可以读取的用于组装该列表的魔法清单在哪里?”MSBuild将从
*.csproj
文件生成该清单。在Visual Studio中启动生成时,VS不会直接运行
csc
,而是调用
*.csproj
文件上的
MSBuild
,该文件反过来运行
csc
@Dai,但我不确定它是否会这样做。该列表似乎只是目录中文件的完整列表。由于目录位于
%PROGRAMFILES%
中,因此在编译时不会将文件复制到该目录中。.csproj文件不枚举这些引用,因为它们都是“
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
<Project Sdk="Microsoft.NET.Sdk">

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

</Project>