开启-Wl,--gc-sections时如何阻止GCC移除未使用变量?
启用
-Wl,--gc-sections时保留ARM项目中未使用变量的方法 在必须保留-Wl,--gc-sections链接选项的前提下,有两种可靠方式可以指定保留特定未使用变量:
1. 使用__attribute__((used))编译器属性
这个属性会告诉编译器:该变量属于“已使用”范畴,即使代码中没有直接引用,也不会被标记为未使用符号,从而避免被链接器的垃圾回收机制移除。
示例代码(mystruct.c):
#include "test_opt.h" // 保留字符串变量 char mystring[] __attribute__((used, section(".MYSTRING"))) = "reserved string"; // 保留结构体变量 typedef struct { int val; char flag; } MyStruct; MyStruct mystruct __attribute__((used, section(".MYSTRUCT"))) = {0x12, 'A'};
该方法在ARM GCC和MINGW64 GCC环境下均有效,能同时保留变量数据和调试符号。
2. 修改链接器脚本添加KEEP指令
如果项目使用自定义链接器脚本,可以直接在脚本中指定要保留的段或符号,强制链接器不回收对应内容。
方式一:保留整个自定义段
在链接器脚本的RAM分配区域附近,添加自定义段并标记KEEP:
.MY_RESERVED : { KEEP(*(.MYSTRING)) // 保留所有放在.MYSTRING段的内容 KEEP(*(.MYSTRUCT)) // 保留所有放在.MYSTRUCT段的内容 } > RAM
变量定义时仍需指定对应段:__attribute__((section(".MYSTRING")))。
方式二:直接保留单个符号
如果不需要整段保留,也可以直接指定符号名:
KEEP(symbol=mystring) KEEP(symbol=mystruct)
这种方式无需修改变量的段属性,直接针对符号生效。
注意事项
- 部分旧版本ARM GCC可能不支持
__attribute__((keep)),因此__attribute__((used))是更通用的选择。 - 若使用链接器脚本方案,需确保脚本被正确引入到编译链接流程中(通常通过
-T linker_script.ld参数指定)。
内容的提问来源于stack exchange,提问作者sdbbs
相关产品推荐
相关产品推荐

