老话题了,不过还是记一笔
先看文件
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
Nice bro!