一、 依赖动态库的动态库
libfun.so依赖动态库libtest.so(libfun.so动态库里的函数intnothing()调用了libtest.so里的intmytest()函数),而main.exe又调用了libfun.so的函数int nothing()。
下面两种方式都能工作:
1> 常用的方式
g++ -shared -fPIC -o libtest.so test.cpp
g++ -shared -fPIC -o libfun.so function.cpp -L./ -I./ -ltest ---这里ldd能看到libfun.so依赖libtest.so(用ldd时可能要先在libfun.so所在目录执行下export LD_LIBRARY_PATH=./)
g++ -o main.exe main.cpp -L./ -I./ -lfun ---编译libfun.so的时候已经指定了依赖libtest.so,这里就不需要再指定了
或者
2>不常用的方式
g++ -shared -fPIC -olibtest.so test.cpp
g++ -shared -fPIC -o libfun.so function.cpp ---这里ldd可知,libfun.so没有依赖libtest.so
g++ -o main.exe main.cpp -L./ -I./ -lfun -ltest ---因为编译libfun.so的时候没有指定它依赖libtest.so,所以要加上-ltest
从2>可知,linux下面生成动态库的时候,即使动态库里有没有定义的函数,在编译链接的时候,默认不会提示错误,是能通过的。
但是,当可执行文件在链接这个有未定义函数的动态库的时候则会报错。具体解释可通过man ld查看说明。
经过测试发现,无论是在静态库或是动态库中,都可以只声明一个函数而不定义此函数,但是在库中可以调用此未定义的函数,生成库的时候都能成功;原来一直以为只有静态库才能这样用,因为静态库生成的时候是不需要链接的。现在才知道,动态库静态也能这样用。
二、依赖动态库 / 静态库的动态态库 / 静态库
静态库只是一堆object对象的集合,使用ar命令可以将编译产生的.o文件打包成.a静态库。
生成静态库只有编译,而没有链接;而动态库在生成的时候时既有编译的动作也有链接的动作。
静态库在被别的程序(可执行程序或是动态库)链接的时候,链接器会将程序中使用到函数的代码从静态库文件中拷贝到应用程序中的。
静态库生成时是没有链接的,所以生成它的时候不需要指定它所依赖的外部库;动态库生成时是有链接动作的,那当然就要指定它依赖哪些外部库了。
如:
$ gcc -c libhello -o libhello.o
$ ar rcs libhello.a libhello.o
这里先编译得到.o文件,然后再用ar命令打包即得到了静态库,它是没有链接动作的。
如一中所述,如果一个动态库依赖一个动态库,则该动态库是会知道它所依赖的动态库的。那么,如果一个动态库依赖一个静态库呢?这时,在生成这个动态库时,它就会将静态库的代码拷贝到动态库程序中的。例如, liba.so 依赖 libb.a, 则在生成liba.so时必须要在makefile中指定依赖静态库libb.a,且要指定libb.a为查找目录。同时如果可执行程序c.out依赖liba.so,则a.out只需要指出它依赖动态库liba.so就可以了,a.out不需要再去链接静态库libb.a了。
还有,一个静态库依赖一个静态库 / 动态库呢? 因为如上所述,生成静态库的时候它是没有链接动作的,所以不需要指定它所依赖的外部静态库或是动态库。所以,只要在链接静态库的地方再去指定链接该静态库的依赖库就可以了。