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を追加する。