Plan 9とGo言語のブログ

主にPlan 9やGo言語の日々気づいたことを書きます。

Plan 9のローダは先頭から順にシンボルを解決する

半年に1回は8lのエラーでハマっているので書いておこうと思いました。*1

こないだ curlコンパイルしている時に、こういう設定を mkfile に入れました。

# リンクするライブラリのリスト
LIB=\
    /$objtype/lib/ape/libcurl.a\
    /$objtype/lib/ape/libz.a\
    /$objtype/lib/ape/libcrypto.a\
    /$objtype/lib/ape/libssl.a\

それぞれシンボルはアーカイブに含まれているはずなのに、この書き方では、

inflate_stream: undefined: inflate

のようなエラーでリンクできません。依存を順番に解決するような並びにする必要があります。

LIB=\
    /$objtype/lib/ape/libcurl.a\
    /$objtype/lib/ape/libssl.a\
    /$objtype/lib/ape/libcrypto.a\
    /$objtype/lib/ape/libz.a\

なんで順番が違うだけでエラーなんだろうと思ったら、GCCのスタティックリンクの順番は大事で理由が書かれていました。

gccはリンクする際に引数の順番にライブラリを読んでいきそこで見つからない関数(どこか他のライブラリにあるはず)を見つけるとそれを「見つからないテーブル」に登録する。ライブラリを読み込む中でこの見つからないテーブルにある関数が見つかるとそれを解決する。問題は再帰的にやってくれないことで発生する。どうやら速度上の問題でそうなっているらしい。

*1:Plan 9のリンカはローダと呼ぶらしいです