GCCのスタティックリンクの順番は大事

投稿者: | 2016/12/5 月曜日

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

これはあくまでライブラリをリンクするときでオブジェクトファイルをリンクするときには当てはまらない。

実験

func.c

int func(int i)
{
	return i+1;
}

main.c

#include <stdio.h>
 
int func();
void main()
{
	printf("%d\n", func(1));
}
$ gcc main.c func.c
$ ./a.out
2
$ gcc func.c main.c
$ gcc -c func.c main.c
$ ls
a.out  func.c  func.o  main.c  main.o
$ gcc func.o main.o
$ gcc main.o func.o
$ ar rcs libfunc.a func.o
$ nm libfunc.a
 
func.o:
00000000 T func
$ gcc main.c -L. func
gcc: error: func: No such file or directory
$ gcc main.c -L. -lfunc
$ ./a.out
2
$ gcc -L. -lfunc main.c
/tmp/ccmzhB7I.o: In function `main':
main.c:(.text+0x11): undefined reference to `func'
collect2: ld returned 1 exit status
$ gcc -L. -lfunc main.o
main.o: In function `main':
main.c:(.text+0x11): undefined reference to `func'
collect2: ld returned 1 exit status
$

再帰的に検索する

-Wl,–start-group-Wl,–end-groupでライブラリを括るとこの問題が解決できるが先にも書いたように遅くなる場合がある。

$ gcc -L. -Wl,-start-group -lfunc main.c -Wl,-end-group
$ gcc -L. -Wl,-start-group main.c -lfunc -Wl,-end-group
$

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です