FLAGS 和 INCLUDES这两行是 Android NDK 编译时的编译器选项,用于控制代码生成、优化、调试、安全性和头文件搜索路径。下面逐项详解:
1. FLAGS 详解(编译器选项)
FLAGS 定义了传递给 C/C++ 编译器(如 clang 或 gcc) 的选项,影响代码的编译方式:
(1) 调试相关选项
| 选项 | 作用 | 
|---|---|
| -g | 生成调试信息( DWARF格式),用于gdb/lldb调试 | 
| -O0 | 禁用优化( -O0= 不优化,-O2/-O3= 优化代码) | 
| -fno-limit-debug-info | 不限制调试信息大小,保留更多变量名和符号 | 
适用场景:开发调试阶段使用,发布时应移除
-g -O0 -fno-limit-debug-info,改用-O2优化性能。
(2) Android 平台定义
| 选项 | 作用 | 
|---|---|
| -DANDROID | 定义宏 ANDROID,代码中可用#ifdef ANDROID判断平台 | 
(3) 代码分段 & 体积优化
| 选项 | 作用 | 
|---|---|
| -fdata-sections | 每个变量放在独立的 ELF section | 
| -ffunction-sections | 每个函数放在独立的 ELF section | 
| -funwind-tables | 生成堆栈展开信息,用于异常处理和崩溃分析 | 
适用场景:配合链接器选项
-Wl,--gc-sections可删除未使用的代码,减小.so体积。
(4) 安全性增强
| 选项 | 作用 | 
|---|---|
| -fstack-protector-strong | 栈溢出保护(防止缓冲区溢出攻击) | 
| -D_FORTIFY_SOURCE=2 | 增强 memcpy/strcpy等函数的安全性检查 | 
| -Wformat -Werror=format-security | 检查 printf/scanf的格式字符串漏洞,错误直接报错 | 
适用场景:所有正式版本都应启用这些选项,防止安全漏洞。
(5) 兼容性 & 稳定性
| 选项 | 作用 | 
|---|---|
| -no-canonical-prefixes | 禁止路径标准化,避免交叉编译问题 | 
| -mstackrealign | 强制栈对齐(某些老旧 ARM 设备需要) | 
| -std=c++11 | 使用 C++11 标准(需代码支持 C++11) | 
| -fPIC | 生成位置无关代码( .so动态库必须) | 
适用场景:
-fPIC是共享库(.so)的强制要求,否则加载会失败。
-std=c++11可根据项目需求改为-std=c++14/-std=c++17。
2. INCLUDES 详解(头文件搜索路径)
INCLUDES 定义了 编译器查找头文件的路径:
            
            
              bash
              
              
            
          
          INCLUDES=" -isystem $NDK_ROOT/sources/android/support/include"| 选项 | 作用 | 
|---|---|
| -isystem | 指定系统头文件目录(比 -I优先级低,避免覆盖标准头文件) | 
| $NDK_ROOT/sources/android/support/include | Android 支持库的头文件路径(如 android/support/*.h) | 
适用场景:
- 如果代码使用了
android/support库(如兼容旧版 API),则需要此路径。- 通常和
-isysroot $NDK_ROOT/sysroot配合使用。
3. 完整编译示例
            
            
              bash
              
              
            
          
          # 设置 NDK 路径
export NDK_ROOT=/path/to/ndk
export ANDROID_API=24
# 编译选项
FLAGS="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -std=c++11 -O0 -fno-limit-debug-info -fPIC"
INCLUDES="-isystem $NDK_ROOT/sources/android/support/include"
# 传递给 FFmpeg/CMake 等构建系统
./configure \
    --extra-cflags="$FLAGS $INCLUDES" \
    --extra-ldflags="-Wl,--gc-sections"  # 删除未使用的代码4. 总结
| 选项类别 | 作用 | 是否必须? | 
|---|---|---|
| 调试选项 ( -g -O0) | 方便调试,但影响性能 | 开发时启用,发布时移除 | 
| 安全选项 ( -fstack-protector, -D_FORTIFY_SOURCE=2) | 防止内存/格式化字符串漏洞 | 必须 | 
| 体积优化 ( -fdata-sections, -ffunction-sections) | 配合 -Wl,--gc-sections减小.so大小 | 推荐 | 
| Android 支持 ( -DANDROID,-isystem) | 定义平台宏,支持 Android 特有头文件 | 必须 | 
| C++ 标准 ( -std=c++11) | 指定 C++ 版本 | 按需调整 | 
| PIC 代码 ( -fPIC) | 生成位置无关代码(动态库必须) | 必须 | 
建议:
• 开发阶段:保留 -g -O0 方便调试。
• 发布阶段:移除 -g -O0,改用 -O2 优化性能,并确保安全选项开启。
常见问题
- 为什么发布版不能用 -O0?
-O0 会禁用优化,导致性能极差(可能慢 10 倍以上)。- -fPIC 报错怎么办?
检查是否遗漏了 -fPIC,或尝试显式指定 -fPIE(Android 7.0+ 可替代)。- 如何进一步减小库体积?
添加链接选项:-Wl,--gc-sections -Wl,--strip-all。