链接可分为静态链接和动态链接
静态链接:对函数库的链接是放在编译时期完成的是静态链接
生成静态链接库的步骤:
(1)先将源文件编译成 .o 文件:
(源文件可从上一篇查看)
g++ -c printA.cpp
g++ -c printB.cpp
生成的文件为 printA.o printB.o ,-c 的编译选项,表示只执行到编译,输出目标文件。
- 无论是静态库文件还是动态库文件,都是由 .o 文件创建的
(2)由 .o 文件创建静态库(.a 文件),执行命令:
ar cr libmyprint.a printA.o printB.o
生成的静态库文件就是libmyprint.a,命名规范是以lib 开头(前缀),紧接着是静态库名,以.a为后缀名
ar 命令的 c 选项:创建一个库。
ar 命令的 r 选项:在库中插入模块(替换);如果若干模块中有一个模块在库中不存在,ar会显示一个错误信息,并且不替换其他同名模块。
(3)在程序中使用静态库,链接生成可执行文件:
g++ -o main main.cpp -L. -lmyprint
动态链接:程序运行到要调用待链接的库函数时,才链接载入,拷贝至内存,内存已有不重复载入。
生成动态链接库的步骤:
(1)先将源文件编译成位置独立的.o文件
g++ -fPIC -o printA.o -c printA.cpp
g++ -fPIC -o printB.o -c printB.cpp
(2)由 .o 文件创建动态库(.so 文件),执行命令:
g++ -shared -o libmyprint.so printA.o printB.o
(1) ,(2)也可以一步到位:
g++ -fPIC -shared -o libmyprint.so printA.cpp printB.cpp
(3)将动态库文件拷贝至动态库搜索路径目录下
动态库的搜索路径的先后顺序是:
- 编译目标代码时指定的动态库搜索路径
- 环境变量 LD_LIBRARY_PATH 指定的动态库搜索路径
- 配置文件 /etc/ld.so.conf 中指定的动态库搜索路径;即只需在该文件中追加一行库所在的完整路径如“root/test/conf/lib”即可,然后ldconfig使修改生效
- 默认的动态搜索路径 /lib
- 默认的动态库搜索路径 /usr/lib
为此解决步骤为:
将动态库文件 拷贝至目录 /usr/lib 中
cp libmyprint.so /usr/lib/
修改环境变量 LD_LIBRARY_PATH,并使修改生效
export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH
sudo ldconfig
(4)在程序中(隐式)使用动态库,链接生成可执行文件
g++ -o main main.cpp -L. -lmyprint
代码和静态库生成可执行文件一样
选项备注:
-fPIC :表示编译为位置独立的代码
-Lpath:表示从path 目录中搜索库文件,若从当前路径 . 查找,选项为 -L. (有一点)
-Iname:name为动态库的真正名字,编译器查找动态链接库时有隐含的命名规则,即在给出的名字前面+lib,后面加.so确定库的名称,即实际动态库文件名为 libname.so
参考:《后台开发核心与应用实践》