*****************************
2024-03-11 20.47更新。
g++ 编译时的四个参数。-I -i -L -l
-I ( i 的大写) :指定头文件路径(相对路径或觉得路径,建议相对路径)
-i :指定头文件名字 (一般不使用,而是直接放在**.c 文件中通过#include<***.h> 添加)
-L :指定连接的动态库或者静态库路径(相对路径或觉得路径,建议相对路径)
-l (L的小写):指定需要链接的库的名字(链接 libc.a :-lc 链接动态库:libc.so : -lc 注意:-l后面直接添加库名省区“lib”和“.so”或“.a” )
原文链接:https://blog.csdn.net/abcdu1/article/details/86083295
*****************************
一、静态库
1.静态库概念
程序在编译时会把库文件的二进制代码链接到目标程序中,这种方式称为静态链接。如果多个程序中用到了同一静态库中的函数或类,就会存在多份拷贝。
2.静态库特点
- 静态库的链接是在编译时期完成的,执行的时候代码加载速度快。
- 目标程序的可执行文件比较大,浪费空间。
- 程序的更新和发布不方便,如果某一个静态库更新了,所有使用它的程序都需要重新编译。
3.制作静态库
准备材料:/home/cc/mine/libTest目录下准备了app和tools文件夹,app文件夹存放调用的代码demo01.cpp,tools文件夹存放被调用的文件代码public.h和public.cpp。
文件树为:
制作静态库命令:
g++ -c -o lib库名.a 源代码文件清单
笔者此处为g++ -c -o libpublic.a public.cpp。
4.使用静态库
使用静态库命令:
g++ 选项 源代码文件名清单 -l库名 -L库文件所在的目录名
使用静态库时-l后面的库名,不加前缀lib和后缀.a,单写库名就好。
笔者此处为g++ -o demo01 demo01.cpp -L/home/cc/mine/libTest/tools -lpublic
二、动态库
1.动态库概念
程序在编译时不会把库文件的二进制代码链接到目标程序中,而是在运行时候才被载入。
如果多个进程中用到了同一动态库中的函数或类,那么在内存中只有一份,避免了空间浪费问题。
2.动态库特点
- 程序在运行的过程中,需要用到动态库的时候才把动态库的二进制代码载入内存。
- 可以实现进程之间的代码共享,因此动态库也称为共享库。
- 程序升级比较简单,不需要重新编译程序,只需要更新动态库就行了。
3.制作动态库
制作动态库命令:
g++ -fPIC -shared -o lib库名.so 源代码文件清单
笔者此处为:g++ -fpic -shared -o libpublic.so public.cpp
4.使用动态库
使用动态库命令:
g++ 选项 源代码文件名清单 -l库名 -L库文件所在的目录名
笔者此处为:g++ -o demo01 demo01.cpp -lpublic -L/home/cc/mine/libTest/tools
此时可执行文件demo01编译成功但是无法执行。
原因是使用动态库编译的文件,在执行的时候,需要提前设置LD_LIBRARY_PATH环境变量。
(
LD_LIBRARY_PATH是Linux系统下的环境变量名,类似于Path(设置可执行文件的搜索路径)。
作用:用于指定查找共享库(动态链接库)时除了默认路径(./lib和./usr/lib)之外的其他路径。
)
查看环境变量命令:
echo $LD_LIBRARY_PATH
追加设置环境变量命令(此追加方法仅临时修改,重启后会重置消失):
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:库文件所在路径
笔者此处为: export LD_LIBRARY_PATH = $LD_LIBRARY_PATH:/home/cc/mine/libTest/tools
三、makefile
在实际开发中,项目的源代码文件比较多,按类型、功能、模块分别存放在不同的目录和文件中,哪些文件需要先编译,那些文件后编译,那些文件需要重新编译,还有更多更复杂的操作。make是一个强大的实用工具,用于管理项目的编译和链接。make需要一个编译规则文件makefile,可实现自动化编译。
写makefile文件三要素:目标、依赖和规则文件。
目标即为要生成的目标,依赖即为生成目标需要的依赖文件,规则命令则是怎么实现。
接上文,写一个在tools目录下编译静态库和动态库的简单makefile,如下:
冒号前即为目标,冒号后为依赖,红色字体为规则命令。
(规则命令前为tab键)
(clean这仅在命令行输入make clean才会运行)
此外,makefile中#为注释,同时也可以定义变量和使用变量。