🗂

zig cc がクロスコンパイルに便利な理由

2023/01/18に公開

zig cc がクロスコンパイルに便利だよというのはよく聞きます。
その理由を改めてあげてみました。

  • オールインワン
  • ビルドされたものの依存性が少ない
  • 新しいversionのclang + llvm が使える

オールインワン

クロスコンパイルするときには、クロスコンパイラの他にそのアーキテクチャの標準ライブラリも必要です。別々に持ってくるのは手間がかかりますしバージョンの整合性とかも気にする必要があるかもしれません。
zig をインストールするとそれらの必要なものが全て利用可能な状態で手に入ります。(必要なものがオンデマンドでダウンロードされます)

hello.c
#include <stdio.h>

int main()
{
	printf("Hello, world.\n");
	return 0;
}
$ mkdir x86_64
$ mkdir aarch64
$ mkdir riscv64
$ (cd x86_64 && zig cc -target x86_64-linux-musl ../hello.c)
$ (cd aarch64 && zig cc -target aarch64-linux-musl ../hello.c)
$ (cd riscv64 && zig cc -target riscv64-linux-musl ../hello.c)
$ ls -l */a.out
-rwxrwxr-x 1 koba koba 35608 Jan 18 10:07 aarch64/a.out
-rwxrwxr-x 1 koba koba 59256 Jan 18 10:07 riscv64/a.out
-rwxrwxr-x 1 koba koba 26888 Jan 18 10:06 x86_64/a.out

note: '(cd xxx && yyy)' と書くと子プロセスとして新たにshellを起動してその中で実行するので、現在のカレントディレクトリに影響を与えません。

ビルドされたものの依存性が少ない

muslのライブラリでビルドするとstatic linkになるので、他のシステムに持って行って動かすときにライブラリのバージョンの不一致の問題が起きません。

$ file */a.out
aarch64/a.out: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, with debug_info, not stripped
riscv64/a.out: ELF 64-bit LSB executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), statically linked, with debug_info, not stripped
x86_64/a.out:  ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped

新しいversionのclang + llvm が使える

ubuntu 22.04でapt installでインストールされるclangのバージョンは

$ clang --version
Ubuntu clang version 14.0.0-1ubuntu1
Target: aarch64-unknown-linux-gnu
Thread model: posix
InstalledDir: /usr/bin

zig cc では

$ zig cc --version
clang version 15.0.3 (https://github.com/ziglang/zig-bootstrap 85033a9aa569b41658404d0e8a5ab887b81d537b)
Target: aarch64-unknown-linux-musl
Thread model: posix
InstalledDir: /usr/bin

zigの方が新しいものが利用できます。
利用したzigのバージョンは

$ zig version
0.10.0

zigの次の安定版の0.11はLLVMの16がリリースされたらそれに合わせて数週間以内に出る予定だそうです。
更新されていました。 0.11.0はLLVM 16.0.5に合わせてリリースされるそうです。
https://github.com/ziglang/zig/milestone/17

つまり新しいzigをインストールすると常に新しい clang + llvm を利用できます。

補足(2022/01/18 追記)

sudo apt install qemu-user または sudo apt install qemu-user-static をやっておくと、先ほどビルドした実行ファイルを実際に動かすことができます。

$ ./aarch64/a.out 
Hello, world.
$ ./riscv64/a.out 
Hello, world.
$ ./x86_64/a.out 
Hello, world.

関連

https://zenn.dev/tetsu_koba/articles/6725d8b22cd997
https://zenn.dev/tetsu_koba/articles/0f65daab36d40a

Discussion