gcc 链接时动态库和静态库的优先选择

1:23:00 PM 0 Comments

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

Some say he’s half man half fish, others say he’s more of a seventy/thirty split. Either way he’s a fishy bastard.