- Linux下使用gcc/g++ 四步编译链接:C/C++文件的执行过程,由原始cpp文件输入,经过预编译器,对头文件和宏定义进行展开,生成.i文件;再经过编译器,生成汇编文件.o类型;而后经过汇编器,生成二进制.o文件;最后经过链接器生成可执行文件.exe。
//在Linux下,分别使用带参数的g++命令对cpp文件进行分步生成
//index.cpp
g++ -E index.cpp -o index.i
//index.i
g++ -S index.i -o index.s
//index.s
g++ -c index.s -o index.o
//index.o
g++ index.o -o index
//index.exe
//使用gcc编译处理C程序
//sum.c
gcc -E sum.c -o sum.i
//sum.i
gcc -S sum.i -o sum.s
//sum.s
gcc -c sum.s -o sum.o
//sum.o
gcc sum.o -o sum
//sum.exe
当不需要中间文件生成时,直接使用不带参数的指令
g++ index.cpp -o index
//index.exe
gcc sum.c -o sum
//sum.exe
- gcc下参数
1. 参数
(1) -E 预编译 --> 生成.i文件
(2) -S 编译 --> 生成.s文件
(3) -c 汇编 --> 生成.o文件
(4) 链接 --> 生成exe文件
(5) -o 指定生成的文件名
(6) -I 指定编译的头文件路径
gcc sum.c -I ./include -o sumapp
(7) -D 不在源文件中定义宏,而在编译的时候定义
gcc sum.c -I include -D DEBUG
(8) -O<num> 指定优化等级,num有效为0-3,0无优化,1为默认值,3优化级别最高
int a = 10; int b = a; int c = b; int d = c; --> 优化为:int a = 10; int d = 10;
(9) -Wall 在编译时输出警告信息
gcc sum.c -I include -D DEBUG -O3 -Wall
(10) -g gdb调试时在程序中添加调试信息,生成的文件会略大
(11) -v 查看版本信息
- 静态库的制作
1. 命名规则
(1) lib + 库名字 + .a --> libmylib.a
2. 制作步骤
(1) 生成对应的.o 文件 --> .c文件 => -c => .o文件
(2) 将生成的.o文件打包 --> ar rcs + 静态库名称(例如:libmylib.a) + 需要打包的所有.o文件
3. 发布和使用静态库
(1) 发布静态库 --> 不用交付源文件
(2) 提供头文件 --> 头文件中指明了可以调用的借口
(3) 使用静态库(<include/head.h>,<lib/libMyCalc.a>,<main.c>)
a. gcc main.c lib/libMyCalc.a -I include -o myapp
使用lib目录下的MyCalc静态库,使用include目录下的head头文件,生成myapp
b. gcc main.c -L lib -l MyCalc -I inlcude -o myapp
-L指定静态库的目录,-l指定静态库的名称,-I指定编译所需头文件的目录,-o指定生成文件名
4. 查看静态库
(1) nm <libFile> --> nm libMyCalc.a
(2) 可执行文件中只包含静态库中使用了的.o文件,而不会包含所有的被打包的.o文件
- 静态库的优缺点
优点:
1. 发布程序的时候,不需要提供对应的库
2. 加载库的速度快
缺点:
1. 库被打包到应用程序中,导致程序过大
2. 库升级需要重新编译程序
- 共享库的制作<类似Windows下的dll>
1. 命名规则
(1) lib + 共享库名称 + .so --> libMyCalc.so
2. 制作步骤
(1) 生成与位置无关的.o文件<与位置无关指的是在共享库中相对地址来表示,而不是绝对地址>
.c文件 => -fPIC -c => 与位置无关的.o文件
gcc -fPIC -c *.c
(2) 打包生成共享库
gcc -shared -o <共享库名称(libMySharedCalc.so)> <需要打包的.o文件(*.o)>
3. 发布和使用动态链接库
(1) 发布动态链接库
(2) 提供头文件
(3) 使用动态链接库(<include/head.h>,<lib/libMySharedCalc.so>,<main.c>)
a. gcc main.c lib/libMySharedCalc.so -o myshareapp -I include
使用动态链接库生成指定可执行文件
b. gcc main.c -L lib -l MySharedCalc -o myshareapp -I include
使用该方法需要配置项使得动态链接器能够找到share库
动态链接器其实也是一个动态链接库 --> /lib64/ld-linux-x86-64.so.2
c. 查看可执行程序的依赖库
ldd <exeFIle>
查看exe执行的依赖库
(4) 解决程序执行无法加载动态链接库问题
a. 禁止使用方式
第一种方法是将动态链接库放在根目录下的lib下 --> 最好不要这样做,避免影响系统库
b. 用于临时测试
第二种配置LD_LIBRARY_PATH,使用export LD_LIBRARY_PATH=./lib,将动态链接库的目录导入其中,但仅限该终端有效
c. 不建议使用
第三种修改家目录下.bashrc文件,加入语句export LD_LIBRARY_PATH=<so_lib的绝对路径>,重启终端起效
d. 建议使用
第四种方式:
i. 需要找到动态链接器的配置文件 --> /etc/ld.so.conf
ii. 自身动态链接库的路径写到配置文件中
iii. 更新动态链接器 --> sudo ldconfig -v -v表示输出信息
- 动态库的优缺点
优点:
1. 执行程序体积小
2. 动态库更新不需要重新编译程序
缺点:
1. 发布程序时,需要提供动态库给用户
2. 加载速度较静态库慢些