WasmLinux: リンカオプション差し替えの検討
Cコンパイラに一定のオプションを渡したり削ったりするのは簡単だが、リンカのオプションをどうすんのかは難しい問題となる。
簡単には普通にCコンパイラのオプションと一緒に -Wl,...
オプションも追加してしまえばオプションの追加は可能だが、直接 ld
を呼んでいるようなプロジェクトには対応できない。
Clangには一応 -fuse-ld=
オプションがあるが、これはリンカの種別を指定するもの(GNU ldとGOLDみたいな)で、パスの指定に使えない。(リンカの種別はLTOのようなコンパイラとリンカの協調が必要なケースで設定が必要になる)
とりあえず:
- 基本的には常にCコンパイラドライバがリンカを呼ぶと仮定する →
cc
コマンドのwrapperでリンカのオプションの加除も行う - Linuxカーネルのビルド時のように、リンカを直接呼ぶユースケースでは
ld
のパスを明示的に指定する
というルールを前提にしたい。
カーネル編
... カーネルとユーザランドでABIが違うので、念のためコンパイラオプションの編集ルールも分けておく。。
コンパイラ
--target=wasm32
-ffreestanding
-Xclang -target-feature -Xclang +atomics
を追加する。 ... -ffreestanding
は要らない気もするな。。
ポイントは -fPIC
が無い点。wasm2cはGOTのリロケーションをサポートしていないので常に単純なポインタ足し算になり、 -fPIC
にはそれなりのオーバーヘッドがあると考えられる。LKLはカーネル内がマルチスレッドでないので、無用なカーネルのオーバーヘッドは避けたい。
リンカ
--start-group
--end-group
はサポートしていないので除去する。ただ、そもそもLinuxカーネルのビルドは vmlinux.a
までで止めるようにする方法を考えないとな。。たぶん LKLのMakefileを使うのを止めた方が良い。
ユーザーランド編
ユーザーランドは -fPIC
が入るのが最大の差ということになる。
コンパイル
オプションに -c
とか -E
がある場合はコンパイルモードということで、リンカ向けのオプションは編集しない。
-fPIC
-nostdinc
-isystem $WASMLINUX_HOST/lib/clang/18/include
-isystem $WASMLINUX_PREFIX/include
を追加する。
あと main
関数の置き換えも処理しないとダメだな。。どうしたもんか。。
リンクフェーズ
-nostdlib
-shared
-L$WASMLINUX_PREFIX/lib
-lm
-Wl,--no-entry
-Wl,--export=_start_c
$WASMLINUX_PREFIX/lib/crt1.o
-lc
を追加する。