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

老话题了,不过还是记一笔

先看文件

ModuleA.cpp

int add(int a, int b)
{
    return a + b;
}

ModuleB.cpp

int minus(int a, int b)
{
    return a - b;
}

Main.cpp

#include <stdio.h>

int add(int, int);
int minus(int , int);

int main()
{
    printf("%d\n", add(1, 2));
    printf("%d\n", minus(2, 1));
    return 0;
}

Makefile

all:
	g++ -c -fPIC Main.cpp
	g++ -c -fPIC ModuleA.cpp
	g++ -c -fPIC ModuleB.cpp
	g++ -shared ModuleA.o ModuleB.o -o libmodule.so
	g++ -o Run Main.o -L./ -lmodule
clean:
	rm *.o *.so Run

记得指定动态库路径

$ export LD_LIBRARY_PATH=./:$LD_LIBRARY_PATH

ldd 确认一下

$ ldd Run 
/$LIB/libonion.so => /lib64/libonion.so (0x00002b98dea29000)
libmodule.so => ./libmodule.so (0x00002b98deb39000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b98dec4d000)
libm.so.6 => /lib64/libm.so.6 (0x00002b98dee4c000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b98defa1000)
libc.so.6 => /lib64/libc.so.6 (0x00002b98df0ae000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b98df2ef000)
/lib64/ld-linux-x86-64.so.2 (0x00002b98de90d000)

跑起来

$ ./Run 
3
1

再来看静态的方式,修改后的 Makefile

all:
	g++ -c -fPIC Main.cpp
	g++ -c -fPIC ModuleA.cpp
	g++ -c -fPIC ModuleB.cpp
	ar -r libmodule.a ModuleA.o ModuleB.o
	g++ -o Run Main.o -L./ -lmodule
clean:
	rm *.o *.a Run

编译出来的已经不依赖动态库了(废话)

$ ldd Run 
/$LIB/libonion.so => /lib64/libonion.so (0x00002ad9ce948000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002ad9cea58000)
libm.so.6 => /lib64/libm.so.6 (0x00002ad9cec56000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002ad9cedac000)
libc.so.6 => /lib64/libc.so.6 (0x00002ad9ceeb9000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002ad9cf0f9000)
/lib64/ld-linux-x86-64.so.2 (0x00002ad9ce82c000)

静态版本的 Run 是 9850 字节,动态是 9954 字节,这。。

下面问题来了,如果静态动态都有,链接器要哪个呢

all:
	g++ -c -fPIC Main.cpp
	g++ -c -fPIC ModuleA.cpp
	g++ -c -fPIC ModuleB.cpp
	ar -r libmodule.a ModuleA.o ModuleB.o
	g++ -shared ModuleA.o ModuleB.o -o libmodule.so
	g++ -o Run Main.o -L./ -lmodule
clean:
	rm *.o *.a *.so Run

答案是动态库

$ ldd Run 
/$LIB/libonion.so => /lib64/libonion.so (0x00002b2243070000)
libmodule.so => ./libmodule.so (0x00002b2243180000)
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00002b2243294000)
libm.so.6 => /lib64/libm.so.6 (0x00002b2243493000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00002b22435e8000)
libc.so.6 => /lib64/libc.so.6 (0x00002b22436f5000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b2243936000)
/lib64/ld-linux-x86-64.so.2 (0x00002b2242f54000)

可以这样来强制链接静态库

all:
	g++ -c -fPIC Main.cpp
	g++ -c -fPIC ModuleA.cpp
	g++ -c -fPIC ModuleB.cpp
	ar -r libmodule.a ModuleA.o ModuleB.o
	g++ -shared ModuleA.o ModuleB.o -o libmodule.so
	g++ -o Run Main.o libmodule.a
clean:
	rm *.o *.a *.so Run

One thought on “gcc 链接时动态库和静态库的优先选择

Leave a Reply

Your email address will not be published. Required fields are marked *