工程结构
该项目工程结构如下:
test作为主函数调用a中的函数,a.hpp存放函数声明,a.cpp存放函数实现.
三大编译方式
1. 直接编译
- 直接编译
g++ test.cpp src/a.cpp -o test
会报错,需要加编译参数编译如下:
g++ test.cpp src/a.cpp -Iinclude -o test
- 这两个cpp在命令行中,顺序任意
运行即可
./test
2. 链接静态库
- 进入src目录
cd src
- 汇编,生成a.o文件
g++ a.cpp -c -I../include -o a.o
- 生成静态链接库liba.a
ar rs liba.a a.o
意思是把a.o归档为liba.a的静态库文件
4. 回到主目录(上级目录)cd ..
5. 链接静态库,生成可执行文件test:
-Lsrc是静态链接库所在目录
g++ test.cpp -Iiclude -Lsrc -la -o test
- -la 引入库a,但是它不在当前目录,因此-Lsrc即引入src目录下的liba.a
- 还要输入头文件所在目录-Iinclude
然后就可以执行./test
了成功
3. 链接动态库
- 进入src目录
cd src
- 生成动态库liba.so
g++ a.cpp -I../include -fPIC -shared -o liba.so
#这条指令等价于下边两条命令
#gcc a.cpp -I../include -c -fPIC -o a.o
#gcc -shared -o liba.so a.o
-fPIC是与路径无关的一条指令
-shared表示生成成动态库文件
3. 回到主目录(上级目录)cd ..
4. 链接动态库,生成可执行文件test:
5.直接运行./test
会报错,原理后边讲
正确运行静态库生成的可执行文件如下:
LD_LIBRARY_PATH=src ./test
动态链接库和其他二者区别
- 其他二者都是在编译可执行文件的时候就将源码包含了进去
- 动态链接库生成的可执行文件只是在执行的时候才去加载,
- 因此动态链接库生成的文件小,但是执行的时候需要加入链接库的搜索路径
LD_LIBRARY_PATH