at backyard

Color my life with the chaos of trouble.

Denoのcompileコマンドやクロスコンパイルについて調べた

目次

このポストにおけるDenoのversion

最初に明記しておこうと思い、Denoのversionを下記に記載する。

$ deno --version
deno 1.15.1 (release, aarch64-apple-darwin)
v8 9.5.172.19
typescript 4.4.2

versionにも記載されている通り、M1 Mac(MacBook Air)で試している。

なお、ここで記載している内容は下記の公式ドキュメントを参照している。

deno.land

Denoで実行ファイルのバイナリを生成する方法

Denoでは deno compile コマンドを利用して実行バイナリを生成することができる。

例えば Welcome to Deno! と表示するだけの下記のプログラムがある。

$ deno run https://deno.land/std/examples/welcome.ts
Download https://deno.land/std/examples/welcome.ts
Warning Implicitly using latest version (0.112.0) for https://deno.land/std/examples/welcome.ts
Download https://deno.land/std@0.112.0/examples/welcome.ts
Check https://deno.land/std/examples/welcome.ts
Welcome to Deno!

実行するとこのような表示が行われる。
(Denoではインターネット上のファイルを直接実行できるので、このような実行も可能。実行引数のURLにアクセスすることで処理の内容も確認が可能。)

では、次に deno compile コマンドを利用して実行バイナリを作成してみる。

$ deno compile https://deno.land/std/examples/welcome.ts
Check https://deno.land/std/examples/welcome.ts
Bundle https://deno.land/std/examples/welcome.ts
Compile https://deno.land/std/examples/welcome.ts
Emit welcome

以上のようなログが出力され、カレントに welcome という実行バイナリが生成される。

試しに file コマンドで中身を確認してみる。

$ file welcome
welcome: Mach-O 64-bit executable arm64

そしてこれを実行してみると、下記のように正常にプログラムが実行されるのがわかる。

$ ./welcome
Welcome to Deno!

バイナリファイルのサイズと、deno compile --lite オプションがなくなっていたことについて

ちなみに上記ファイルのサイズはおよそ 79MB ほどあり、それなりにファイルサイズは大きい。

ちなみに以前はバイナリファイルのサイズを少なくしてくれるための --lite オプションがあったようだが、最新版では消えている。

このことについて調べてみると、下記のissueにたどり着いた。

github.com

--lite オプションをなくしたのは、このオプションを付けるとビルド時間が長くなりすぎるから、というような意見が見られたが、あまり煮え切らない意見のようにも見られたので、他にも理由があったのだろうか?
(上のコメントに対してバイナリサイズを削れるのならCompile時間が長くなったとしても、それはトレードオフではないか?という意見があり、私もそう思った。ただ、これはあくまでGitHub上の1イシュー内での出来事なので、ほかにもなくした背景はあるのかもしれない。そこは調べきれていない)

いずれにせよ、最新版のdenoでは --liteオプションは使えないようだ。

Denoでのクロスコンパイルについて

現在Denoはクロスコンパイルに対応している。

これは非常にありがたい機能で、Mac上でDenoの開発をしながらWindowsLinux用のバイナリも生成できるのなら、今後Denoの選択肢がより広まると個人的には考えている。

ここについて今後色々と自身でも利用してみようと考えているが、ひとまず先程のソースコードをクロスコンパイルでビルドするところまでを行ってみようと思う。

現在ビルド可能な環境を調べるには下記のコマンドを利用する。

$ deno compile --help

すると、--target という箇所に下記のような説明が表示される。

--target <target>
            Target OS architecture [possible values: x86_64-unknown-linux-gnu, x86_64-pc-windows-msvc, x86_64-apple-darwin, aarch64-apple-darwin]

どうやら現在ビルドできる環境は下記のようだ。

試しにこれらの環境それぞれのバイナリを生成してみる。
なお、--target に複数のオプションを付けられるかが分からなかったので、ひとまずそれぞれの環境を一つずつ試してみる。

ちなみに --outputをつけることでバイナリ名を指定できる。

linux用のバイナリを生成する

$ deno compile --target x86_64-unknown-linux-gnu --output welcome_linux https://deno.land/std/examples/welcome.ts

生成したバイナリは下記。

$ file welcome_linux
welcome_linux: ELF 64-bit LSB pie executable, ~

バイナリサイズは 87MB ほど。

Windows用のバイナリを生成する

$ deno compile --target x86_64-pc-windows-msvc --output welcome_windows https://deno.land/std/examples/welcome.ts

生成したバイナリは下記。

$ file welcome_windows.exe
welcome_windows.exe: PE32+ executable (console) x86-64, for MS Windows

バイナリのサイズは 56MB ほど。

Inter Mac用のバイナリを生成する

$ deno compile --target x86_64-apple-darwin  --output welcome_intel_mac https://deno.land/std/examples/welcome.ts

生成したバイナリは下記。

$ file welcome_intel_mac
welcome_intel_mac: Mach-O 64-bit executable x86_64

バイナリのサイズは 82MB ほど。

M1 Mac(Apple Silicon)用のバイナリを生成する

$ deno compile --target aarch64-apple-darwin --output welcome_m1_mac https://deno.land/std/examples/welcome.ts

生成したバイナリは下記。

$ file welcome_m1_mac
welcome_m1_mac: Mach-O 64-bit executable arm64

バイナリのサイズは 79MB ほど、バイナリとしては最初に--target を指定せずに生成したバイナリと同じ内容となる。

TODO: GitHub Actionsと連携させて、自動的にリリース用のバイナリを生成したい

ひとまずはここまで。

後ほどGitHub Actionsと絡めて、リリース用のPRがマージされたタイミングでバイナリをGitHubのリリースページから自動的にリリースできないかと考えている。

後々時間を見つけて調べ次第、こちらに追記していこうと考えています。