[已经解决]如何使用gcc在编译的时候既指定动态链接又指定静态链接?
本帖最后由 vaqeteart 于 2010-12-24 15:51 编辑在使用gcc编译的时候,有些库同时有静态和动态的版本,我的目的是,在编译的时候,我可以自由指定使用静态或者动态库进行链接。
感谢大家帮助,这个问题的答案我已经找到了,总结参见:
点击这里阅读解决方法 http://linux.chinaunix.net/bbs/images/common/back.gif
原问题描述如下:
我之前查找了许多,也没有找到,
有一个:http://bbs.chinaunix.net/thread-111581-1-1.html
也没有说清楚。
所以自己实践如下:
按照我的理解,基于如下原理来进行同时静态链接和动态连接:
以库a和b为例:
如果同时存在:liba.so liba.a libb.so libb.a
使用-la -lb选项的时候,会选择动态的liba.so libb.so来进行链接。
如果想要使用静态库,那么使用-Bstatic选项,接着-Bstatic选项后面的-l都选择静态库链接了。
如果既想要静态,又要动态,那么使用-Bstatic和-Bdynamic选项,-Bdynamic意义类似-Bstatic.
通过man ld可知,-static和-Bstatic应该等价,但是实践发现使用了-static连glibc都不依赖了。
但是,我实践之后,结果不是我想要的,所以我想请教大家究竟有没有好用的方法,可以自由指定哪些库用静态的,哪些用动态的?
我在附件里面给出了完整的测试源代码,希望好心人能够帮忙看一下怎么修改我的makefile。
下面是我的makefile,以及输出结果:
Makefileall:testapp
testapp:test_all liba.so liba.a libb.so libb.a \
test_static test_statica_staticb test_statica_dynamicb test_dynamica_staticb test_dynamica_dynamicb
myliba.o:myliba.c
mylib.o:mylibb.c
test_all:main.c myliba.o mylibb.o
gcc -o $@ $^
liba.so:myliba.o
gcc -shared -o liba.so myliba.o
libb.so:mylibb.o
gcc -shared -o libb.so mylibb.o
liba.a:myliba.o
ar -r liba.a myliba.o
libb.a:mylibb.o
ar -r libb.a mylibb.o
test_static:main.c
gcc -o $@ $< -L./ -static -la -lb
test_statica_staticb:main.c
gcc -o $@ $< -L./ -Bstatic -la -lb
test_statica_dynamicb:main.c
gcc -o $@ $< -L./ -Bstatic -la -Bdynamic -lb
test_dynamica_staticb:main.c
gcc -o $@ $< -L./ -Bdynamic -la -Bstatic -lb
test_dynamica_dynamicb:main.c
gcc -o $@ $< -L./ -la -lb
.PHONY:clean
clean:
rm *.o *.a *.so test*
输出结果:$ ldd test*
test_all:
linux-gate.so.1 =>(0x00ab5000)
libc.so.6 => /lib/libc.so.6 (0x0016d000)
/lib/ld-linux.so.2 (0x0014e000)
test_dynamica_dynamicb:
linux-gate.so.1 =>(0x00619000)
liba.so => not found
libb.so => not found
libc.so.6 => /lib/libc.so.6 (0x0016d000)
/lib/ld-linux.so.2 (0x0014e000)
test_dynamica_staticb:
linux-gate.so.1 =>(0x00da9000)
liba.so => not found
libb.so => not found
libc.so.6 => /lib/libc.so.6 (0x0016d000)
/lib/ld-linux.so.2 (0x0014e000)
test_static:
not a dynamic executable
test_statica_dynamicb:
linux-gate.so.1 =>(0x0082c000)
liba.so => not found
libb.so => not found
libc.so.6 => /lib/libc.so.6 (0x0016d000)
/lib/ld-linux.so.2 (0x0014e000)
test_statica_staticb:
linux-gate.so.1 =>(0x002ff000)
liba.so => not found
libb.so => not found
libc.so.6 => /lib/libc.so.6 (0x0016d000)
/lib/ld-linux.so.2 (0x0014e000)
我很疑惑,为什么无论如何都使用liba和libb的动态版本 用automake和libtool试试? 1,库文件名为什么非要相同,不同文件名即可以解决问题
2,动态库和静态库的执行效率几乎相同,完全可以选其一
不知道楼主的使用环境为什么非要这样做? 谢谢各位回复,我已经找到答案了。
1,库文件名为什么非要相同,不同文件名即可以解决问题
2,动态库和静态库的执行效率几乎相同,完全可以选 ...
bekars 发表于 2010-12-24 13:21 http://linux.chinaunix.net/bbs/images/common/back.gif
是可以用不同的文件名字,但是我的目的是想要知道根本的原因,而不是解决问题就行了。
至于为什么这么做,因为我目前做的一个项目中,需要连接一个库,这个库是他们提供的,在安装交叉编译环境的时候自动生成了lib*.so和lib*.a两种版本,这样我怎么能改个名字就行呢?
原来-Bstatic和-Bdynamic这两个链接器选项需要用gcc的-Wl,option来传递才行。
我最新写的Makefile和源代码.
Makefile:CFLAGS+=-DMYFLAG
all:testapp
testapp:test_all liba.so liba.a libb.so libb.a \
test_static test_statica_staticb test_statica_dynamicb test_dynamica_staticb test_dynamica_dynamicb
myliba.o:myliba.c
mylib.o:mylibb.c
test_all:main.c myliba.o mylibb.o
gcc -o $@ $^
liba.so:myliba.o
gcc -shared -o liba.so myliba.o
libb.so:mylibb.o
gcc -shared -o libb.so mylibb.o
liba.a:myliba.o
ar -r liba.a myliba.o
libb.a:mylibb.o
ar -r libb.a mylibb.o
test_static:main.c
gcc -o $@ $< -L./ -static -la -lb
test_statica_staticb:main.c
gcc -o $@ $< -L./ -Wl,-Bstatic -la -lb -Wl,-Bdynamic
test_statica_dynamicb:main.c
gcc -o $@ $< -L./ -Wl,-Bstatic -la -Wl,-Bdynamic -lb
test_dynamica_staticb:main.c
gcc -o $@ $< -L./ -Wl,-Bdynamic -la -Wl,-Bstatic -lb -Wl,-Bdynamic
test_dynamica_dynamicb:main.c
gcc -o $@ $< -L./ -la -lb
.PHONY:clean
clean:
rm *.o *.a *.so test*
源代码:
页:
[1]