84 lines
2.9 KiB
Markdown
84 lines
2.9 KiB
Markdown
# gcc-g++ 编译器
|
||
|
||
## 目录
|
||
- [编译选项](#option)
|
||
- [优化等级](#level)
|
||
- [制作库文件](#make-lib)
|
||
|
||
## **option**
|
||
- `g++ -S test.s test.cpp` 编译成汇编文件
|
||
- `g++ -c test.o test.s` 目标文件
|
||
- `g++ -o test test.o` 链接
|
||
- `g++ -S -o - -fverbose-asm xxx.cpp > xxx.s` // 输出带注释的汇编
|
||
- `-D <MACRO_NAME>` 定义一个宏,默认值为1
|
||
- `-U <MACRO_NAME>` 取消定义
|
||
|
||
- `gcc -s` 选项用于剥除可执行文件中的符号表和重定位信息,减小可执行文件的大小
|
||
- **正常功能保持**
|
||
- **性能无显著差异**
|
||
- **调试困难**:符号表中包含了函数名、变量名等调试信息。使用 `-s` 选项后,这些信息会被移除,使得调试变得非常困难
|
||
- **反汇编和分析不便**:没有符号表,反汇编工具(如 `objdump`)无法显示函数名和变量名等信息,只能显示汇编指令和地址。这会增加对程序进行反汇编分析的难度。
|
||
|
||
---
|
||
|
||
### **level**
|
||
- **O0** 不进行任何优化
|
||
- **O1** 基础优化
|
||
- 删除未使用的变量和函数
|
||
- 简化控制流(如合并重复代码)
|
||
- 常量折叠(如 2+3 替换为 5)
|
||
- 简单的寄存器分配
|
||
- **O2** 中等优化,推荐级别
|
||
- 指令调度(提高指令级并行性)
|
||
- 循环优化(如循环展开、循环不变代码外提)
|
||
- 函数内联(简单函数直接展开)
|
||
- 分支预测优化
|
||
- 数据流分析优化
|
||
- **O3** 激进优化
|
||
- 更激进的循环优化(如自动向量化,利用 SIMD 指令如 SSE/AVX)
|
||
- 函数内联更积极(可能导致代码膨胀)
|
||
- 删除冗余内存访问
|
||
- 数学表达式重构(可能影响浮点精度)
|
||
- **优化易导致的问题**
|
||
- 暴露未定义行为(Undefined Behavior, UB)
|
||
- 调试信息不匹配
|
||
- 重新排列或合并浮点运算,导致精度损失
|
||
- 代码体积膨胀
|
||
- 重排内存访问顺序,影响多线程程序或硬件寄存器操作
|
||
- 依赖时序的代码失效
|
||
- 向量化(SIMD)导致的兼容性问题
|
||
- 内联汇编的意外行为
|
||
|
||
---
|
||
|
||
## make-lib
|
||
|
||
---
|
||
|
||
### 静态库制作:
|
||
g++ -c -o libtest.a {test.cpp 源代码文件清单}
|
||
// g++ -c test.cpp
|
||
// ar -crv libtest.a test.o
|
||
|
||
---
|
||
|
||
### 动态库制作
|
||
g++ -fPIC -shared -o libtest.so {test.cpp 源代码文件清单}
|
||
// g++ -fPIC -c test.cpp
|
||
// g++ -shared -o libtest.so tset.o
|
||
两种方法
|
||
1 + .so 放到 /usr/lib 或 /lib
|
||
2 + 路径放到/etc/ld.so.conf 运行ldconfd 重建/etc/ld.so.cache
|
||
|
||
---
|
||
|
||
### 库使用
|
||
g++ -o main -l库名 -L库路径 -I头文件路径
|
||
// g++ -o main -ltest -L/home/e0x1a/test
|
||
|
||
#### 编译主程序时链接动态库
|
||
- `gcc -o myprogram main.c -L. -lmylib -Wl,-rpath=.`
|
||
- `-L.` 告诉编译器在当前目录中查找动态库文件
|
||
- `-lmylib` 链接名为 libmylib.so 的动态库
|
||
- `-Wl,-rpath=.` 将运行时路径嵌入到可执行文件中,强制程序运行时优先从当前目录加载动态库
|