linux--关于GCC、动态库静态库
gcc和g++的异同
他们是不同的编译器,
在linux中,生成可执行文件不像和windows一样。
linux中是以**.out作为可执行文件**的
无论是什么系统,生成可执行文件分为4步:
预处理–>编译–>汇编–>链接。
从.c/.cpp–>.i文件–>.s文件–>.o文件–>.exe/.out文件
语法
g++ 文件 -o 生成文件名 -l 使用的库 -L 库的路径
gcc编译选项 | 作用 |
---|---|
-E | 仅预处理 |
-s | 仅编译及之前 |
-c | 仅汇编之前 |
-o | 生成可执行文件 |
-I(大写) directory | 包含include文件的搜索目录(头文件) |
-g | 编译的时候生成调试信息 |
-D | 编译的时候指定一个宏 |
-w | 不是生成任何警告信息 |
-wall | 生成所有警告信息 |
-On | n取值0-3,缺省值-o1,优化从低到高 |
-l(小写) | 编译的时候使用指定的库 |
-L | 制定编译的时候,搜索的库的路径静态库什么的地址) |
-shared | 生成共享目标文件,通常在建立共享库使用 |
-std | 制定C方言 |
可以用GCC去编译cpp只是会麻烦一些,但g++能直接链接到某些库,更方便。
库文件
库文件有两种
- 静态库:在连接阶段被复制到程序中
- 动态库:运行时由系统动态加载到内存中。
静态库的制作
window中后缀.lib
linux中后缀.a 命名为Libxxx.a。其中Lib前缀固定,后面的xxx才是自己的库的名字
- 首先获得 -o文件也就是汇编不链接的文件
- 将所有.o文件打包,用 ar 工具(archive)
ar rcs libxxx.a xxx.o xxx.o
就能生成.a文件
如果是在不同目录下的文件要用这个库生成最后的可执行文件
gcc main.c -o app -I ./include/(编译的时候制定的库所在的目录) -L ./lib/ -l 使用的库名字xxx
动态库的制作
window中是.dll
linus中是.so 命名为Libxxx.so。Lib前缀固定,XXX是具体库名称
- 首先获得汇编之后的文件,但要不带位置信息的代码 所以不是简单的 gcc -c aaa.c bbb.c而是
gcc -c -fpic xxx.c xxx.c
,其中那个-fpic指令就是生成不带位置信息的代码 - 将所有.o文件打包,但此时的打包不含其源代码,只包含其库名信息。要用的时候再动态搜寻绝对路径找到.so地址。
gcc -shared xxx.o xxx.o -o libmylib.so
,-shared上面有。
要使用的时候,需要先添加环境变量什么的,一次添加就能一直用。具体再看视频。
静态库和动态库的对比
静态库的优点:
- 被打包到应用程序中加载速度快
- 发布程序无需提供静态库,移植方便
静态库的缺点:
- 浪费内存(因为每次生成应用都会打包一份静态库到程序中)
- 更新、部署、发布麻烦(因为是需要全部重打包就要重跑一遍)
动态库的优点:
- 可以实现进程的资源共享
- 更新、发布、部署简单
- 可控制何时加载动态库
动态库的缺点:
- 加载速度比较慢(因为每次使用都要找这个地址)
2.发布程序需要提供依赖的的动态库。