メモの日々


2012年08月18日(土) [長年日記]

[dev][c] gccの-lオプションを指定する位置

gccでライブラリを指定する-lオプションは、その指定する順番が重要なことを理解していなかったのでメモ。

gccのマニュアル(リンク切れ → gccのマニュアル)の-lオプションの説明に次のようにある。

       -llibrary
       -l library
           (省略)

           利用者がコマンドで、このオプションを書くところで違いを生じます。リ
           ンカは、ライブラリとオブジェクトファイルが指定される順序でそれらを
           検索して処理します。したがって、foo.o -lz bar.o は、ライブラリ z を
           ファイル foo.o の後で、bar.o の前に、検索します。bar.o が z 中の関
           数を参照しているなら、それらの関数はロードされません。

-lで指定するライブラリ内の関数をロードしたくないケースはあまりないと思うので、通常は-lオプションは後ろの方に書くのがよさそう。

試しておく。次の3つのファイルを用意。

  • main.c
#include <stdio.h>
#include "one.h"
int main() {
    printf("one=%d\n", one());
    return 0;
}
  • one.h
int one();
  • one.c
#include "one.h"
int one() { return 1; }

オブジェクトファイルとライブラリファイルを作成。

$ gcc -Wall -c *.c

$ ar -r libone.a one.o
ar: creating libone.a

-lオプションをmain.oの前に書くとリンクエラーになるが、後に書けば大丈夫。

$ gcc -L. -lone main.o
main.o: In function `main':
main.c:(.text+0xa): undefined reference to `one'
collect2: ld はステータス 1 で終了しました

$ gcc -L. main.o -lone

$ ./a.out
one=1