GCC二进制文件构成
GCC编译二进制产物一般有静态库、动态库和可执行程序。本篇文章的目的是为了探寻可能存在的减小二进制程序体积的方法。
查询文件格式
file查看是否是ELF格式
格式:file [file path]
10:31:34 ELF $file * |
readelf详细查看ELF文件信息
格式:readelf <option(s)> elf-file(s)
10:46:14 ELF $readelf -h json_example |
分析文件体积
size/du查看文件所占内存/磁盘
10:50:12 ELF $size json_example |
字段说明
| 字段 | 含义 | 示例值 | 说明 |
|---|---|---|---|
| text | 代码段 | 40726 字节 | 包含程序的可执行代码(机器指令),通常是只读的 |
| data | 数据段 | 1032 字节 | 包含已初始化的全局变量和静态变量,占用磁盘空间 |
| bss | 未初始化数据段 | 304 字节 | 包含未初始化的全局变量和静态变量,运行时初始化为0 |
| dec | 十进制总和 | 42062 字节 | 前三项的总和:40726 + 1032 + 304 |
| hex | 十六进制总和 | a44e | 总大小的十六进制表示 |
| filename | 文件名 | json_example | 被分析的可执行文件名称 |
体积优化
移除调试信息
file命令查看是否包含符号信息
查看是否包含not stripped字段10:50:26 ELF $file libcjson.so
libcjson.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped
13:35:25 ELF $file json_example
json_example: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, with debug_info, not strippedstrip --strip-debug --strip-unneeded libcjson.so移除调试符号
动态库不能过度strip,不然有可能导致无法使用,上面两个参数是相对安全的参数strip json_example移除所有调试信息
-Os 编译选项
GCC的-O选项是一组用于控制编译优化级别的参数,这些优化级别在代码大小和执行速度之间进行不同的权衡。
| 优化级别 | 编译时间 | 执行速度 | 代码体积 | 可调试性 |
|---|---|---|---|---|
| -O0 | 最快 | 最慢 | 最大 | 最好 |
| -O1 | 较快 | 较快 | 较小 | 较好 |
| -O2 | 中等 | 快 | 中等 | 一般 |
| -O3 | 较慢 | 最快* | 较大 | 差 |
| -Os | 中等 | 较快 | 最小 | 一般 |
| -Og | 较快 | 中等 | 中等 | 好 |
bloaty分析二进制文件大小
Google开源维护的二进制文件分析工具
编译
- 检查一下编译工具的C++标准:
g++ -dM -E -x c++ /dev/null | grep -i cplusplus199711L: C++98/C++0316:14:04 build $g++ -dM -E -x c++ /dev/null | grep -i cplusplus
#define __cplusplus 201703L
201103L: C++11
201402L: C++14
201703L: C++17
202002L: C++20
202302L: C++23
保持CMakeLists.txt里CMAKE_CXX_STANDARD和系统版本一致 - 编译
git clone https://github.com/google/bloaty.git
cd bloaty
mkdir build
cd build
cmake ..
make
sudo make install
使用
bloaty ./my_programbloaty -d compileunits,symbols ./my_program
| 数据源 | 解释 |
|---|---|
| sections | 按 ELF 文件的段(Section)查看 |
| symbols | 按符号(函数名、变量名)查看 |
| compileunits | 按编译单元(源文件)查看 |
| inlines | 尝试解析内联函数,显示内联展开后的体积分布 |
17:00:27 ELF $bloaty json_example |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 L.S.W!
评论