gcc 链接时动态库和静态库的优先选择
老话题了,不过还是记一笔
先看文件
ModuleA.cpp
1 | int add( int a, int b) |
2 | { |
3 | return a + b; |
4 | } |
ModuleB.cpp
1 | int minus( int a, int b) |
2 | { |
3 | return a - b; |
4 | } |
Main.cpp
1 | #include |
2 |
3 | int add( int , int ); |
4 | int minus( int , int ); |
5 |
6 | int main() |
7 | { |
8 | printf ( "%d\n" , add(1, 2)); |
9 | printf ( "%d\n" , minus(2, 1)); |
10 | return 0; |
11 | } |
Makefile
1 | all: |
2 | g++ -c -fPIC Main.cpp |
3 | g++ -c -fPIC ModuleA.cpp |
4 | g++ -c -fPIC ModuleB.cpp |
5 | g++ -shared ModuleA.o ModuleB.o -o libmodule.so |
6 | g++ -o Run Main.o -L./ -lmodule |
7 | clean: |
8 | rm *.o *.so Run |
记得指定动态库路径
1 | $ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH |
ldd 确认一下
1 | $ ldd Run |
2 | /$LIB/libonion.so => /lib64/libonion.so (0x00002b98dea29000) |
3 | libmodule.so => ./libmodule.so (0x00002b98deb39000) |
4 | libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b98dec4d000) |
5 | libm.so.6 => /lib64/libm.so.6 (0x00002b98dee4c000) |
6 | libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b98defa1000) |
7 | libc.so.6 => /lib64/libc.so.6 (0x00002b98df0ae000) |
8 | libdl.so.2 => /lib64/libdl.so.2 (0x00002b98df2ef000) |
9 | /lib64/ld-linux-x86-64.so.2 (0x00002b98de90d000) |
跑起来
1 | $ ./Run |
2 | 3 |
3 | 1 |
再来看静态的方式,修改后的 Makefile
1 | all: |
2 | g++ -c -fPIC Main.cpp |
3 | g++ -c -fPIC ModuleA.cpp |
4 | g++ -c -fPIC ModuleB.cpp |
5 | ar -r libmodule.a ModuleA.o ModuleB.o |
6 | g++ -o Run Main.o -L./ -lmodule |
7 | clean: |
8 | rm *.o *.a Run |
编译出来的已经不依赖动态库了(废话)
1 | $ ldd Run |
2 | /$LIB/libonion.so => /lib64/libonion.so (0x00002ad9ce948000) |
3 | libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002ad9cea58000) |
4 | libm.so.6 => /lib64/libm.so.6 (0x00002ad9cec56000) |
5 | libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002ad9cedac000) |
6 | libc.so.6 => /lib64/libc.so.6 (0x00002ad9ceeb9000) |
7 | libdl.so.2 => /lib64/libdl.so.2 (0x00002ad9cf0f9000) |
8 | /lib64/ld-linux-x86-64.so.2 (0x00002ad9ce82c000) |
静态版本的 Run 是 9850 字节,动态是 9954 字节,这。。
下面问题来了,如果静态动态都有,链接器要哪个呢
1 | all: |
2 | g++ -c -fPIC Main.cpp |
3 | g++ -c -fPIC ModuleA.cpp |
4 | g++ -c -fPIC ModuleB.cpp |
5 | ar -r libmodule.a ModuleA.o ModuleB.o |
6 | g++ -shared ModuleA.o ModuleB.o -o libmodule.so |
7 | g++ -o Run Main.o -L./ -lmodule |
8 | clean: |
9 | rm *.o *.a *.so Run |
答案是动态库
1 | $ ldd Run |
2 | /$LIB/libonion.so => /lib64/libonion.so (0x00002b2243070000) |
3 | libmodule.so => ./libmodule.so (0x00002b2243180000) |
4 | libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b2243294000) |
5 | libm.so.6 => /lib64/libm.so.6 (0x00002b2243493000) |
6 | libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b22435e8000) |
7 | libc.so.6 => /lib64/libc.so.6 (0x00002b22436f5000) |
8 | libdl.so.2 => /lib64/libdl.so.2 (0x00002b2243936000) |
9 | /lib64/ld-linux-x86-64.so.2 (0x00002b2242f54000) |
可以这样来强制链接静态库
1 | all: |
2 | g++ -c -fPIC Main.cpp |
3 | g++ -c -fPIC ModuleA.cpp |
4 | g++ -c -fPIC ModuleB.cpp |
5 | ar -r libmodule.a ModuleA.o ModuleB.o |
6 | g++ -shared ModuleA.o ModuleB.o -o libmodule.so |
7 | g++ -o Run Main.o libmodule.a |
8 | clean: |
9 | rm *.o *.a *.so Run |