1. Linux编译器:gcc/g++入门指南
第一次在Linux下敲下gcc命令时,我盯着满屏的警告信息发呆了半小时。作为从Windows转战Linux的开发者,gcc/g++这个看似简单的编译器工具链,隐藏着太多教科书上不会告诉你的实战细节。本文将带你从零开始,掌握这个Linux世界最核心的编译工具。
gcc(GNU Compiler Collection)和g++(GNU C++ Compiler)是Linux系统默认的C/C++编译器套件,它们不仅支持标准C/C++,还能处理Objective-C、Fortran等多种语言。与Windows下的Visual Studio不同,Linux开发者必须直面编译器本身,理解从源代码到可执行文件的完整过程。
2. 环境准备与基础配置
2.1 安装与版本管理
在大多数Linux发行版中,gcc/g++通常已经预装。通过以下命令检查版本:
gcc --version g++ --version如果未安装,在基于Debian的系统(如Ubuntu)上使用:
sudo apt install build-essential这个元包会安装gcc、g++、make等基础开发工具。对于需要多版本共存的情况,可以使用update-alternatives工具管理:
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-11 60 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 40注意:部分发行版(如CentOS)默认gcc版本较旧,建议通过SCL(Software Collections)安装新版:
sudo yum install centos-release-scl sudo yum install devtoolset-11-gcc* scl enable devtoolset-11 bash
2.2 基础编译流程
一个最简单的编译示例:
g++ -o hello hello.cpp这行命令背后实际经历了四个阶段:
- 预处理(Preprocessing):展开宏和头文件
- 编译(Compilation):生成汇编代码
- 汇编(Assembly):生成目标文件
- 链接(Linking):生成可执行文件
可以用-save-temps参数保留中间文件:
g++ -save-temps -o hello hello.cpp生成的文件包括:
- hello.ii(预处理后的C++代码)
- hello.s(汇编代码)
- hello.o(目标文件)
- hello(最终可执行文件)
3. 编译选项深度解析
3.1 常用编译选项
| 选项 | 作用 | 示例 |
|---|---|---|
| -O0/-O1/-O2/-O3 | 优化级别 | g++ -O2 main.cpp |
| -g | 生成调试信息 | g++ -g -o debug_app debug.cpp |
| -Wall | 开启所有警告 | g++ -Wall strict.cpp |
| -std=c++11 | 指定C++标准 | g++ -std=c++17 modern.cpp |
| -I | 添加头文件路径 | g++ -I../include src.cpp |
| -L | 添加库文件路径 | g++ -L../lib -lmylib app.cpp |
| -l | 链接特定库 | g++ -lpthread thread.cpp |
| -D | 定义宏 | g++ -DDEBUG debug.cpp |
3.2 优化选项详解
gcc的优化级别对程序性能影响巨大:
- -O0:不优化(默认),编译速度快,适合调试
- -O1:基础优化,不影响调试
- -O2:推荐级别,大多数生产环境使用
- -O3:激进优化,可能增加代码体积
- -Os:优化代码大小
- -Ofast:违反标准的小数优化(慎用)
实测不同优化级别对计算密集型程序的影响:
# 计算圆周率程序 g++ -O0 pi.cpp -o pi_O0 g++ -O2 pi.cpp -o pi_O2 g++ -O3 pi.cpp -o pi_O3 time ./pi_O0 # 3.21s time ./pi_O2 # 1.07s time ./pi_O3 # 0.89s3.3 警告与静态检查
gcc的警告系统能捕捉许多潜在错误:
g++ -Wall -Wextra -Wpedantic strict.cpp特别有用的警告选项:
- -Wshadow:变量遮蔽警告
- -Wconversion:隐式类型转换警告
- -Werror:将警告视为错误
- -fsanitize=address:内存错误检测
对于现代C++项目,建议至少使用:
g++ -Wall -Wextra -Wpedantic -std=c++17 -Werror4. 多文件项目管理
4.1 手动编译多文件项目
对于简单项目,可以手动编译每个源文件:
g++ -c main.cpp -o main.o g++ -c utils.cpp -o utils.o g++ main.o utils.o -o app技巧:使用通配符简化操作:
g++ -c *.cpp g++ *.o -o app
4.2 Makefile自动化
当项目规模增大时,Makefile成为必需品。一个基础模板:
CXX = g++ CXXFLAGS = -std=c++17 -Wall -Wextra -O2 TARGET = app SRCS = $(wildcard *.cpp) OBJS = $(SRCS:.cpp=.o) all: $(TARGET) $(TARGET): $(OBJS) $(CXX) $(CXXFLAGS) -o $@ $^ %.o: %.cpp $(CXX) $(CXXFLAGS) -c $< -o $@ clean: rm -f $(OBJS) $(TARGET)4.3 动态库与静态库
创建静态库:
g++ -c lib.cpp -o lib.o ar rcs libmylib.a lib.o创建动态库:
g++ -shared -fPIC lib.cpp -o libmylib.so使用库文件:
# 静态链接 g++ main.cpp libmylib.a -o app_static # 动态链接 g++ main.cpp -L. -lmylib -o app_shared export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH5. 高级技巧与调试
5.1 内联汇编
gcc支持在C/C++中嵌入汇编代码:
int add(int a, int b) { int result; asm volatile ( "add %[a], %[b]" : [b] "+r" (result) : [a] "r" (a) ); return result; }5.2 编译器扩展
gcc提供了许多有用的语言扩展:
// 范围for循环(C++11前) #define foreach(item, array) \ for(int keep=1, count=0, size=sizeof(array)/sizeof*(array); \ keep && count != size; \ keep = !keep, count++) \ for(item = (array)+count; keep; keep = !keep) // 属性语法 void __attribute__((noreturn)) fatal_error() { exit(1); }5.3 性能分析工具
结合gprof进行性能分析:
g++ -pg -O2 app.cpp -o app ./app gprof app gmon.out > analysis.txt使用perf工具:
perf record ./app perf report6. 常见问题解决
6.1 链接错误排查
典型的未定义引用错误:
/tmp/ccXYZ123.o: In function `main': main.cpp:(.text+0x15): undefined reference to `foo()' collect2: error: ld returned 1 exit status解决方案:
- 确认函数声明与定义一致
- 检查是否编译了包含实现的源文件
- 确认链接时指定了正确的库路径(-L)和库名(-l)
6.2 版本兼容性问题
当遇到"GLIBCXX_3.4.29 not found"这类错误时,说明运行环境的libstdc++版本低于编译环境。解决方案:
# 查找编译器带的libstdc++.so find / -name "libstdc++.so*" 2>/dev/null # 复制到程序目录或系统库目录 cp /path/to/new/libstdc++.so.6 /usr/lib/x86_64-linux-gnu/6.3 内存错误诊断
使用AddressSanitizer检测内存问题:
g++ -fsanitize=address -g buggy.cpp -o buggy ./buggy常见错误输出:
==12345==ERROR: AddressSanitizer: heap-use-after-free on address 0x60300000dfd07. 现代C++特性支持
gcc对C++新特性的支持情况:
| 标准 | gcc最低版本 | 关键特性 |
|---|---|---|
| C++11 | 4.8.1 | auto, lambda, range-for |
| C++14 | 4.9.0 | 泛型lambda, 二进制字面量 |
| C++17 | 7.1 | 结构化绑定, std::filesystem |
| C++20 | 10.1 | 概念(concepts), 协程 |
| C++23 | 13.1 | std::print, 多维下标 |
检查特定特性的支持情况:
g++ -dM -E -x c++ /dev/null | grep __cplusplus8. 交叉编译技巧
构建ARM平台可执行文件:
sudo apt install gcc-arm-linux-gnueabihf arm-linux-gnueabihf-g++ -o arm_app app.cpp检查二进制文件架构:
file arm_app # 输出:arm_app: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked...9. 编译器内部探索
查看预处理结果:
g++ -E main.cpp > main.ii查看生成的汇编代码:
g++ -S main.cpp cat main.s使用编译器中间表示(GIMPLE):
g++ -fdump-tree-gimple main.cpp10. 性能优化实战
10.1 向量化优化
检查自动向量化结果:
g++ -O3 -fopt-info-vec-optimized simd.cpp手动使用SIMD intrinsics:
#include <immintrin.h> void add_arrays(float* a, float* b, float* c, int n) { for (int i = 0; i < n; i += 8) { __m256 va = _mm256_load_ps(a + i); __m256 vb = _mm256_load_ps(b + i); __m256 vc = _mm256_add_ps(va, vb); _mm256_store_ps(c + i, vc); } }10.2 链接时优化(LTO)
启用全程序优化:
g++ -flto -O2 main.cpp utils.cpp -o app10.3 分支预测优化
使用likely/unlikely宏:
#define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0) if (likely(condition)) { // 快速路径 } else { // 慢速路径 }11. 编译器插件开发
gcc支持通过插件扩展功能。基础插件示例:
#include <gcc-plugin.h> #include <plugin-version.h> #include <tree-pass.h> int plugin_is_GPL_compatible; void callback(void *event_data, void *user_data) { printf("Compilation finished\n"); } int plugin_init(struct plugin_name_args *info, struct plugin_gcc_version *version) { if (!plugin_default_version_check(version, &gcc_version)) return 1; register_callback(info->base_name, PLUGIN_FINISH, callback, NULL); return 0; }编译插件:
g++ -I`gcc -print-file-name=plugin`/include -shared -fPIC plugin.cpp -o plugin.so使用插件:
g++ -fplugin=./plugin.so test.cpp12. 嵌入式开发特殊考量
对于资源受限的嵌入式系统,关键编译选项:
arm-none-eabi-g++ -mcpu=cortex-m4 -mthumb -Os \ -ffunction-sections -fdata-sections \ -Wl,--gc-sections -specs=nano.specs \ -T link.ld -o firmware.elf main.cpp关键优化:
-Os优化代码大小-ffunction-sections配合链接器垃圾回收- 使用nano标准库减小体积
13. 安全编译选项
加固程序安全性的编译选项:
g++ -fstack-protector-strong -D_FORTIFY_SOURCE=2 \ -Wformat -Wformat-security -fPIE -pie \ -Wl,-z,now -Wl,-z,relro -o secure_app main.cpp各选项作用:
-fstack-protector-strong:栈保护-D_FORTIFY_SOURCE=2:缓冲区溢出检查-fPIE -pie:地址空间随机化-Wl,-z,now:立即绑定符号-Wl,-z,relro:只读重定位
14. 编译器性能调优
14.1 并行编译
利用多核加速编译:
make -j$(nproc)或直接使用gcc的并行模式:
g++ -pipe -j4 main.cpp utils.cpp14.2 预编译头文件
创建预编译头:
g++ -x c++-header stdafx.hpp -o stdafx.hpp.gch使用预编译头:
#include "stdafx.hpp"14.3 缓存优化
使用ccache加速重复编译:
sudo apt install ccache export CC="ccache gcc" export CXX="ccache g++"15. 调试技巧进阶
15.1 核心转储分析
生成和分析核心转储:
ulimit -c unlimited ./crash_app gdb ./crash_app core15.2 反向调试
使用rr记录执行:
rr record ./buggy_app rr replay15.3 内存布局检查
查看二进制文件布局:
objdump -h app readelf -S app16. 编译器错误解读
典型错误类型及解决方法:
模板实例化错误:
error: no matching function for call to 'foo(T)'检查模板参数类型和约束条件
const正确性错误:
error: passing 'const X' as 'this' argument discards qualifiers确保成员函数正确标记const
重载解析歧义:
error: call of overloaded 'bar(int)' is ambiguous检查所有候选重载的匹配程度
17. 编译器资源管理
17.1 内存限制
防止编译器消耗过多内存:
g++ -Wl,--stack,16777216 -Wl,--heap,16777216 large_app.cpp17.2 临时文件管理
指定临时文件目录:
export TMPDIR=/mnt/big_temp g++ large_project.cpp18. 编译器内部机制
18.1 函数多版本化
为不同CPU特性生成多个版本:
__attribute__((target("default"))) void foo() { /* 通用实现 */ } __attribute__((target("avx2"))) void foo() { /* AVX2优化实现 */ }18.2 热路径优化
使用profile-guided优化:
g++ -fprofile-generate -o train_app train.cpp ./train_app g++ -fprofile-use -o opt_app train.cpp19. 编译器与标准库关系
理解libstdc++版本:
# 查看链接的标准库 ldd ./app | grep stdc++ # 查看编译器支持的C++标准 g++ -v --help 2>&1 | grep "std="20. 构建系统集成
20.1 CMake集成
基础CMake配置:
cmake_minimum_required(VERSION 3.10) project(MyApp) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra") add_executable(app main.cpp utils.cpp)20.2 Autotools集成
configure.ac示例:
AC_INIT([myapp], [1.0]) AM_INIT_AUTOMAKE AC_PROG_CXX AC_CONFIG_FILES([Makefile]) AC_OUTPUTMakefile.am示例:
bin_PROGRAMS = myapp myapp_SOURCES = main.cpp utils.cpp myapp_CXXFLAGS = -Wall -Wextra -std=c++1721. 编译器测试与验证
21.1 测试用例编写
使用GTest框架:
#include <gtest/gtest.h> TEST(MathTest, Addition) { EXPECT_EQ(2, 1 + 1); } int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }编译测试:
g++ -std=c++11 test.cpp -lgtest -lgtest_main -pthread -o test_app21.2 静态分析集成
使用clang-tidy:
clang-tidy --extra-arg=-std=c++17 main.cpp --22. 编译器与调试信息
22.1 调试信息优化
减少调试信息大小:
g++ -g1 -O2 app.cpp -o app # 最小调试信息 g++ -g3 -O0 app.cpp -o app # 最大调试信息22.2 分离调试信息
创建分离的调试文件:
g++ -g -o app app.cpp objcopy --only-keep-debug app app.debug strip --strip-debug --strip-unneeded app objcopy --add-gnu-debuglink=app.debug app23. 编译器与ABI兼容性
23.1 ABI检查
检查二进制ABI:
abi-dumper app -o app.abi abi-compliance-checker -l mylib -old old.abi -new new.abi23.2 兼容性选项
保持ABI稳定:
g++ -fabi-version=2 -Wabi-tag legacy_code.cpp24. 编译器与链接器脚本
自定义内存布局(link.ld示例):
MEMORY { FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 256K RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 64K } SECTIONS { .text : { *(.text*) } > FLASH .data : { *(.data*) } > RAM AT > FLASH }使用链接脚本:
g++ -T link.ld -o firmware.elf startup.cpp main.cpp25. 编译器与性能剖析
25.1 时间优化
测量编译各阶段耗时:
g++ -time -o app app.cpp25.2 资源使用分析
使用strace跟踪系统调用:
strace -f -o compile.log g++ app.cpp26. 编译器与预处理技巧
26.1 宏高级用法
X宏技术示例:
#define COLORS \ X(Red) \ X(Green) \ X(Blue) enum Color { #define X(name) name, COLORS #undef X }; const char* color_names[] = { #define X(name) #name, COLORS #undef X };26.2 条件编译
平台特定代码处理:
#if defined(__linux__) // Linux专用代码 #elif defined(_WIN32) // Windows专用代码 #endif27. 编译器与代码生成
27.1 自动生成代码
使用gcc的代码生成功能:
#define DECLARE_GETTER(type, name) \ type get_##name() const { return name; } class Point { int x, y; public: DECLARE_GETTER(int, x) DECLARE_GETTER(int, y) };27.2 属性语法
函数属性示例:
__attribute__((always_inline)) inline void fast_path() { // 强制内联 } __attribute__((noinline)) void slow_path() { // 禁止内联 }28. 编译器与模板元编程
28.1 SFINAE技巧
类型特征检查:
template<typename T> auto test_has_foo(int) -> decltype(std::declval<T>().foo(), std::true_type{}); template<typename> std::false_type test_has_foo(...); template<typename T> using has_foo = decltype(test_has_foo<T>(0));28.2 编译时计算
constexpr函数示例:
constexpr int factorial(int n) { return n <= 1 ? 1 : n * factorial(n - 1); } static_assert(factorial(5) == 120, "Factorial error");29. 编译器与异常处理
29.1 异常开销分析
查看异常处理代码:
g++ -fdump-class-hierarchy -c exceptions.cpp29.2 异常安全选项
禁用异常:
g++ -fno-exceptions -DNO_EXCEPTIONS secure_code.cpp30. 编译器与并发编程
30.1 原子操作支持
检查原子操作实现:
g++ -E -dM - < /dev/null | grep __ATOMIC30.2 内存模型选项
指定内存模型:
g++ -std=c++11 -march=ivybridge concurrent.cpp31. 编译器与浮点运算
31.1 浮点精度控制
严格浮点模型:
g++ -ffloat-store -fexcess-precision=standard precise_math.cpp31.2 SIMD浮点优化
自动向量化检查:
g++ -fopt-info-vec-missed -O3 simd_float.cpp32. 编译器与安全审计
32.1 静态分析集成
使用cppcheck:
cppcheck --enable=all --std=c++17 app.cpp32.2 动态分析工具
使用Valgrind:
valgrind --tool=memcheck --leak-check=full ./app33. 编译器与代码覆盖率
生成覆盖率数据:
g++ --coverage -O0 -o test_app test.cpp ./test_app lcov --capture --directory . --output-file coverage.info genhtml coverage.info --output-directory coverage_report34. 编译器与调试符号
34.1 符号表管理
查看符号表:
nm -C app | grep MyClass34.2 调试符号优化
压缩调试信息:
objcopy --compress-debug-sections app compressed_app35. 编译器与二进制分析
35.1 反汇编检查
生成反汇编代码:
objdump -d -M intel app > disassembly.asm35.2 控制流分析
生成控制流图:
g++ -fdump-tree-cfg -O2 app.cpp36. 编译器与链接优化
36.1 符号可见性控制
显式指定符号可见性:
__attribute__((visibility("default"))) void api_func(); __attribute__((visibility("hidden"))) void internal_func();编译选项:
g++ -fvisibility=hidden -fvisibility-inlines-hidden shared_lib.cpp36.2 链接时优化
全程序优化:
g++ -flto -O2 -o app main.cpp utils.cpp37. 编译器与代码生成选项
37.1 目标架构指定
针对特定CPU优化:
g++ -march=haswell -mtune=skylake performance.cpp37.2 指令集扩展控制
启用AVX2指令集:
g++ -mavx2 -mfma simd_code.cpp38. 编译器与运行时检查
38.1 边界检查
数组边界检查:
g++ -fsanitize=bounds array_access.cpp38.2 未定义行为检查
捕捉UB:
g++ -fsanitize=undefined ub_test.cpp39. 编译器与代码大小优化
39.1 最小化二进制
去除不必要内容:
g++ -Os -ffunction-sections -fdata-sections -Wl,--gc-sections minimal.cpp39.2 节区合并
合并相似节区:
g++ -Wl,--merge-exidx-entries -Wl,--gc-sections embedded.cpp40. 编译器与调试技巧
40.1 内联函数调试
强制生成内联函数代码:
g++ -fkeep-inline-functions -g inline_debug.cpp40.2 模板实例化追踪
查看模板实例化过程:
g++ -ftemplate-backtrace-limit=10 template_debug.cpp41. 编译器与跨平台开发
41.1 目标三元组指定
交叉编译示例:
x86_64-w64-mingw32-g++ -o app.exe win_app.cpp41.2 系统头文件隔离
使用sysroot:
g++ --sysroot=/path/to/target_sysroot cross_compile.cpp42. 编译器与语言扩展
42.1 语句表达式
gcc扩展语法:
#define maxint(a,b) \ ({ int _a = (a), _b = (b); _a > _b ? _a : _b; })42.2 类型推导扩展
auto关键字增强:
__auto_type x = some_complex_expression;43. 编译器与静态分析
43.1 静态断言增强
编译时检查:
_Static_assert(sizeof(int) == 4, "int must be 4 bytes");43.2 属性语法扩展
函数属性:
__attribute__((access(read_only, 1, 2))) void safe_copy(char *dst, const char *src, size_t len);44. 编译器与性能剖析
44.1 热点分析
生成性能剖析数据:
g++ -pg -O2 -o profiled_app profile.cpp ./profiled_app gprof profiled_app gmon.out > analysis.txt44.2 指令级分析
使用perf工具:
perf record ./app perf annotate45. 编译器与代码生成控制
45.1 内联控制
强制/禁止内联:
__attribute__((always_inline)) void fast_path(); __attribute__((noinline)) void slow_path();45.2 分支预测提示
likely/unlikely宏:
if (__builtin_expect(ptr != nullptr, 1)) { // 快速路径 }46. 编译器与调试信息管理
46.1 调试信息级别
控制调试信息量:
g++ -g1 -O2 minimal_debug.cpp # 最小调试信息 g++ -g3 -O0 full_debug.cpp # 最大调试信息46.2 分离调试信息
创建独立调试文件:
objcopy --only-keep-debug app app.debug strip --strip-debug app objcopy --add-gnu-debuglink=app.debug app47. 编译器与ABI兼容性
47.1 ABI版本控制
指定ABI版本:
g++ -fabi-version=2 legacy_code.cpp47.2 ABI检查工具
使用abi-compliance-checker:
abi-dumper lib.so -o lib.abi abi-compliance-checker -l mylib -old v1.abi -new v2.abi48. 编译器与链接器优化
48.1 符号排序优化
按调用顺序布局函数:
g++ -ffunction-sections -Wl,--sort-section=name app.cpp48.2 预链接优化
使用ld -r进行部分链接:
ld -r -o partial.o a.o b.o g++ -o app partial.o c.o49. 编译器与安全加固
49.1 栈保护选项
加强栈保护:
g++ -fstack-protector-strong security.cpp49.2 控制流完整性
启用CFI保护:
g++ -fcf-protection=full secure_app.cpp50. 编译器与嵌入式开发
50.1 裸机编程支持
无标准库编译:
arm-none-eabi-g++ -nostdlib -ffreestanding bare_metal.cpp50.2 中断处理
指定中断处理函数:
__attribute__((interrupt)) void Timer_Handler() { // 中断处理代码 }51. 编译器与多语言混合编程
51.1 C与C++混合
确保C兼容性:
extern "C" { void c_function(); }51.2 内联汇编集成
混合汇编与C++:
asm volatile ( "mov %[result], %[value]" : [result] "=r" (output) : [value] "r" (input) );52. 编译器与构建系统
52.1 并行构建优化
分布式编译:
distcc g++ -c -O2 app.cpp52.2 增量构建加速
使用ccache:
export CCACHE_PREFIX="icecc" g++ -O2 app.cpp53. 编译器与代码质量
53.1 静态分析集成
使用clang静态分析器:
scan-build g++ app.cpp53.2 动态分析工具
结合Valgrind:
valgrind --tool=memcheck --leak-check=full ./app54. 编译器与模板调试
54.1 模板实例化追踪
查看模板展开过程:
g++ -ftemplate-backtrace-limit=10 template_debug.cpp54.2 模板错误诊断
改进错误信息:
g++ -fdiagnostics-show-template-tree complex_template.cpp55. 编译器与异常处理
55.1 异常开销分析
查看异常处理表:
g++ -fdump-class-hierarchy -c exceptions.cpp55.2 异常安全选项
禁用异常:
g++ -fno-exceptions -DNO_EXCEPTIONS secure_code.cpp56. 编译器与并发编程
56.1 原子操作支持
检查原子实现:
g++ -E -dM - < /dev/null | grep __ATOMIC56.2 内存模型选项
指定内存模型:
g++ -std=c++11 -march=ivybridge concurrent.cpp57. 编译器与浮点运算
57.1 浮点精度控制
严格浮点模型:
g++ -ffloat-store -fexcess-precision=standard precise_math.cpp57.2 SIMD浮点优化
自动向量化检查:
g++ -fopt-info-vec-missed -O3 simd_float.cpp58. 编译器与安全审计
58.1 静态分析集成
使用cppcheck:
cppcheck --enable=all --std=c++17 app.cpp58.2 动态分析工具
使用Valgrind:
valgrind --tool=memcheck --leak-check=full ./app59. 编译器与代码覆盖率
生成覆盖率数据:
g++ --coverage -O0 -o test_app test.cpp ./test_app lcov --capture --directory . --output-file coverage.info genhtml coverage.info --output-directory coverage_report60. 编译器与调试符号
60.1 符号表管理
查看符号表:
nm -C app | grep MyClass60.2 调试符号优化
压缩调试信息:
objcopy --compress-debug-sections app compressed_app61. 编译器与二进制分析
61.1 反汇编检查
生成反汇编代码:
objdump -d -M intel app > disassembly.asm61.2 控制流分析
生成控制流图:
g++ -fdump-tree-cfg -O2 app.cpp62. 编译器与链接优化
62.1 符号可见性控制
显式指定符号可见性:
__attribute__((visibility("default"))) void api_func(); __attribute__((visibility("hidden"))) void internal_func();编译选项:
g++ -fvisibility=hidden -fvisibility-inlines-hidden shared_lib.cpp62.2 链接时优化
全程序优化:
g++ -flto -O2 -o app main.cpp utils.cpp63. 编译器与代码生成选项
63.1 目标架构指定
针对特定CPU优化: