web-dev-qa-db-ja.com

.NET Core Roslynコンパイラで単一のC#コードファイルをコンパイルすることは可能ですか?

古い.NETでは、cscコンパイラを実行して単一の.csファイルまたは複数のファイルをコンパイルできました。

.NET Coreでは、dotnet build適切なプロジェクトファイルを持つことを主張します。プロジェクトがなくてもソースコードファイルをコンパイルできる(および同じコマンドラインで参照されている依存関係を一覧表示できる)スタンドアロンのコマンドラインコンパイラはありますか?

Linuxでは、古いcscと新しい.NET Coreをインストールすると、次のタイミングが得られます。

[root@li1742-80 test]# time dotnet build
Microsoft (R) Build Engine version 15.3.409.57025 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  test -> /root/test/bin/Debug/netcoreapp2.0/test.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:03.94

real    0m7.027s
user    0m5.714s
sys     0m0.838s

[root@li1742-80 test]# time csc Program.cs
Microsoft (R) Visual C# Compiler version 2.3.0.61801 (3722bb71)
Copyright (C) Microsoft Corporation. All rights reserved.


real    0m0.613s
user    0m0.522s
sys     0m0.071s
[root@li1742-80 test]#

.NET Coreでは7秒であるのに対し、同じファイルの古いcscではProgram.cs

cscでできるように、.NET Coreでできる限り速くコンパイルできるようにしたいと思います。

20
Andrew Savinykh

コンパイラは、次を使用して直接呼び出すことができます。

$ /usr/local/share/dotnet/sdk/2.0.0/Roslyn/RunCsc.sh

ただし、すべての.NET Coreまたは.NET Standard参照アセンブリを手動で渡す必要があるため、サポートするプロジェクトインフラストラクチャがないと、この特定のコマンドはあまり役に立たない場合があります。これは通常、SDKおよびNuGetによって処理されます。次のようなエラーが表示されます。

$ /usr/local/share/dotnet/sdk/2.0.0/Roslyn/RunCsc.sh Program.cs
Microsoft (R) Visual C# Compiler version 2.3.2.61921 (ad0efbb6)
Copyright (C) Microsoft Corporation. All rights reserved.

Program.cs(1,7): error CS0246: The type or namespace name 'System' could not be found (are you missing a using directive or an Assembly reference?)
Program.cs(5,11): error CS0518: Predefined type 'System.Object' is not defined or imported
Program.cs(7,26): error CS0518: Predefined type 'System.String' is not defined or imported
Program.cs(7,16): error CS0518: Predefined type 'System.Void' is not defined or imported
4
Martin Ullrich

受け入れられた答えは、ランタイムアセンブリであり推奨されないSystem.Private.CoreLib.dllの使用を参照しています。 C#コンパイラ開発者のコ​​メント から:

コンパイル参照としてランタイムアセンブリを使用することはサポートされておらず、ランタイムアセンブリの構造が頻繁に破損する

代わりに、参照アセンブリを使用する必要があります。参照アセンブリはdotnet buildの間にNuGetから取得され、csc CLIを詳細度を上げて実行すると完全なdotnet呼び出しが表示されます(dotnet build --verbosity normal)。 System.Runtime.dll NuGetパッケージのSystem.Console.dllMicrosoft.netcore.appなどのアセンブリへの参照が表示される場合があります。

ただし、単純な単一ファイルHello、World!コンパイルの場合、.NETのnetstandard.dllを参照できます。コア2.2は<installation-directory>/sdk/2.2.203/ref/netstandard.dllの下にあります。

DOTNETDIR=$(dirname $(which dotnet))
alias csc='dotnet $DOTNETDIR/sdk/2.2.203/Roslyn/bincore/csc.dll /r:$DOTNETDIR/sdk/2.2.203/ref/netstandard.dll'
csc /t:exe HelloWorld.cs

結果の実行可能ファイルをdotnet HelloWorld.exeで実行するには、対応する.NET Coreランタイムバージョンを含む対応するHelloWorld.runtimeconfig.jsonを作成する必要があることに注意してください。

{"runtimeOptions": {
    "framework": {
      "name": "Microsoft.NETCore.App",
      "version": "2.2.4"
    }
  }
}
2
Ivan

つまり、定義済みのプロジェクトがないとサポートされません。

しかし、@ Andrewのコメントは、コマンドラインオプションに暗黙的なシステムの依存関係を含むすべての依存関係をリストする準備ができていれば、まだ可能であることを示しています。

差出人 エラーCS0518:定義済みのタイプ 'System.Object'は定義またはインポートされていません#1239

現時点では、この方法でcsc.exeを簡単に使用できるようにする計画はありません。ガイダンスは、当分の間、ドットネットCLIツールを使用することです。ここでどこかに変更を加えたとしても、統合および/または簡略化されたリファレンスアセンブリをコンパイラに提供するのはフレームワーク上です。コンパイラーは、現在よりも複雑な型またはアセンブリーの解像度を持つことは決してありません(設計上)。

クローズドコンパイラーを直接起動できるようにする#7689も参照してください。

0
Vadzim