在大型工程开发中,工程目录会分的非常细,在modules下会创建很多模块,每个modules都会编译成.a静态库文件供主路径/app/src/下使用,这样就会产生链接库问题,比如在app下的函数要调用静态库里的函数,会出现未定义的错误,需要通过
-Wl,--whole-archive -lXXX -Wl,--no-whole-archive在脚本里修改下链接库的选项,这里XXX代表静态库的名称
--whole-archive是链接器选项,作用是设置连接器将库中的符号全部加载到链接的库中,在编译的时候要用-Wl,[options]来传递给链接器,不然编译器会不认得这个选项。
例子如下:
// a.h extern void foo(); // a.cpp #include void foo() { printf("foo\n"); } // x.cpp #include "a.h" int main() { foo(); return 0; } // Makefile all: x x: x.cpp liba.so g++ -g -o $@ $^ liba.so: liba.a g++ -g -fPIC -shared -o $@ $^ #g++ -g -fPIC -shared -o $@ -Wl,--whole-archive $^ -Wl,-no-whole-archive liba.a: a.o ar cru $@ $^ a.o: a.cpp g++ -g -c $^ clean: rm -f x a.o liba.a liba.so $ make g++ -g -c a.cpp ar cru liba.a a.o g++ -g -fPIC -shared -o liba.so liba.a #g++ -g -fPIC -shared -o liba.so -Wl,--whole-archive liba.a -Wl,-no-whole-archive g++ -g -o x x.cpp liba.so /tmp/cc6UYIAF.o: In function `main': /data/jayyi/ld/x.cpp:5: undefined reference to `foo()' collect2: ld returned 1 exit status make: *** [x] Error 1
默认情况下,对于未使用到的符号(函数是一种符号),链接器不会将它们链接进共享库和可执行程序。
这个时候,可以启用链接参数“--whole-archive”来告诉链接器,将后面库中所有符号都链接进来,参数“-no-whole-archive”则是重置,以避免后面库的所有符号被链接进来。
主要作用就是解决主目录函数与模块间函数相互调用问题
// Makefile all: x x: x.cpp liba.so g++ -g -o $@ $^ liba.so: liba.a g++ -g -fPIC -shared -o $@ -Wl,--whole-archive $^ -Wl,-no-whole-archive liba.a: a.o ar cru $@ $^ a.o: a.cpp g++ -g -c $^ clean: rm -f x a.o liba.a liba.so