.NET Core 3.0 でシングルバイナリを作れるようになるオプションが追加されました。自分的には、シングルバイナリを作りたいときは今までは常にGoでプログラムを書いてきました。それはリリースやインストールが圧倒的に楽だからです。これがC#でできるようになることはうれしいことです。以前から存在は知っていましたが、試したことはなかったので、実際に使ってアプリを作ってみました。
Self Contained アプリケーション
最初は名前からしてこれが該当設定と思っていました。.NET Core のコンソールアプリケーションを Self-Contained
にしてみます。csproj
ファイルに次の設定を入れてみましょう。ちなみに Self Contained
は DotNet のランタイムを成果物に含むという意味で1つのバイナリファイルという意味ではありません。Self Contained
を1つのファイルにパッケージすることで、シングルバイナリのアプリケーションが出来上がります。
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
<PublishReadyToRun>true</PublishReadyToRun>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>
Property | Description | Possible Value | Default |
---|---|---|---|
OutputType | 出力タイプのフォーマット | Library, Exe, Module, Winexe | Library |
TargetFramework | アプリケーションを実行するのに必要な .NET のフレームワーク | netcore3.1 等 詳細 | N/A |
RuntimeIdentifier | Publish で使われるランタイム識別子、OSの種類やアーキテクチャを指定する | win10-x64 詳細 | N/A |
PublishReadyToRun | ILに加えて、ネイティブにコンパイルされたコードを含む。現在のところクロスプラットフォームビルドはサポートされていない。詳細 | true/false | false |
PublishSingleFile | アプリケーションを1つのExeにまとめる | true/false | false |
この設定をしてdotnet publish
コマンドを実行するとwin10-x64
用のアプリケーションができます。
$ dotnet publish
PublishReadyToRun
をするとすでにネイティブにコンパイルされているバイナリを含むので起動時間が早くなります。ただし、現在のところクロスプラットフォームビルドはサポートされていません。具体的にはWindows10で、Linuxのビルドをするときにこのオプションは現在のバージョン(3.1.301)では使えないようです。CIでビルドする場合は、ビルドしたい対象のプラットフォームのビルドを使うとよさげです。ただ、このオプションの指定はサイズを増加させるようです。リリースのコマンドでオプションを指定して試してみましょう。
PS > dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=true
PS > ls C:\Users\tsushi\source\repos\KafkaSpike\KafkaSpike\bin\Release\netcoreapp3.1\win10-x64\publish\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/4/2020 1:32 PM 76303080 ProducerSample.exe
-a---- 7/4/2020 1:32 PM 1588 ProducerSample.pdb
PS > dotnet publish -c Release -r win10-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=false
PS > ls C:\Users\tsushi\source\repos\KafkaSpike\KafkaSpike\bin\Release\netcoreapp3.1\win10-x64\publish\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/4/2020 1:32 PM 75643254 ProducerSample.exe
-a---- 7/4/2020 1:32 PM 1588 ProducerSample.pdb
思ったより大したことなさそうですね。ちなみに、2つのコマンドの間には、Remove-Item -Path .\bin -Recurse
などでbin
を削除してからやるほうがよさそうです。しないと同じ結果になりました。
Linuxもビルドしてみましょう。ただし、この場合は、PublishReadyToRun
Windows10だと使えませんので、
PS > dotnet publish -c Release -r linux-x64 -p:PublishSingleFile=true -p:PublishReadyToRun=false
PS > ls C:\Users\tsushi\source\repos\KafkaSpike\KafkaSpike\bin\Release\netcoreapp3.1\linux-x64\publish\
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 7/4/2020 1:38 PM 137016076 ProducerSample
-a---- 7/4/2020 1:38 PM 1588 ProducerSample.pdb
サイズでけぇなぁw でも、Linux 用のビルドもできるのはありがたい。137MB で、Windows の 75MB の倍ぐらいですね。
Visual Studio
最後に、Visual Studio でも設定ができますので、見てみましょう。Project ファイル右クリック > Publish を選択します。
これで、一通りのシングルバイナリ系の設定が理解できたと思います。次が、シングルバイナリにほしくなる、コマンドラインパーサーの調査をしてみたいと思います。
参考までにリソースのパートに私が実際に使ったサンプルのURLを張っておきますね。