在LINUX下用静态库进行链接的时候经常会碰到如下情况:存在与静态库名一样的动态库。以MKL为例,在目录/MKLROOT/lib/em64t下,库libmkl_core.a和库libmkl_core.so同名。这样的话我们如果在链接时加入链接的库名-lmkl_core,编译器只同动态库libmkl_core.so链接,而屏避掉静态库文件libmkl_core.a。所以静态库文件里的对象文件无法被链接。解决这一问题有两个办法:
1. 直接将静态库的绝对路径加到编译过程中去:
gcc -I$(INCLUDE) -L$(LIB) main.c /MKLROOT/lib/em64t/libmkl_core.a -o a.out
这样的话编译器就会根据指定的文件进行编译链接,不过这种做法在静态库文件少的时候可用,如果文件一多,就会让整个指令冗长,可读性差。下面是一种比较可取的方法。
2. 在目录/MKLROOT/lib/em64t下用vi编辑器打开一个与所有库文件都不重名的库,例如libmkl.a。然后在该文件中加入下面的一行:
GROUP (libmkl_*.a libmkl_*.a libmkl_*.a ............... libmkl_*.a)
(GROUP一定要大写)
保存退出。之后在编译程序的时候只要将该文件加入链接项就OK了。命令如下:
gcc -I$(INCLUDE) -L$(LIB) main.c -lmkl -o a.out
上面的选项(-lmkl)就相当于让编译器gcc到文本文件libmkl.a指定的静态库文件中寻找.o文件进行链接,而不用人工地将每个静态库地址都输进行。查找.o对象文件的顺序从左到右,所以应该将最低层的静态库放到最右边,把需要调用右边库里的对象的库放到左边,否则会出现找不到对象文件,导致报函数没定义的错误。