ARM Cortex-M项目中如何排除未使用C文件参与编译?
解决ARM Cortex-M项目中LD未回收未使用目标文件的问题
一、先确认gc-sections的完整配置
仅加链接阶段的--gc-sections不够,必须配合编译阶段的段拆分选项,让LD能识别独立的未使用段:
- 编译时给所有源文件添加
-ffunction-sections -fdata-sections,这会把每个函数、每个全局数据都放到单独的段里,而非合并到.text/.data大段中。在CMake里可以全局配置:add_compile_options(-ffunction-sections -fdata-sections) - 链接阶段确保加上
-Wl,--gc-sections,同时检查是否存在--whole-archive选项——如果链接时用了这个参数,会强制包含库或目标文件的所有内容,直接阻断垃圾回收。如果必须用--whole-archive,要把不需要强制包含的部分放在--no-whole-archive之后:target_link_options(your_target PRIVATE -Wl,--gc-sections -Wl,--no-whole-archive)
二、排查LD未回收的根源(用LD调试开关)
如果配置没问题但还是有未用目标文件被链接,用--print-gc-sections开关让LD输出回收过程的细节:
target_link_options(your_target PRIVATE -Wl,--print-gc-sections)
运行make后,会看到LD列出哪些段被保留、哪些被回收,以及保留该段的引用来源——大概率是某个全局符号(比如弱符号、被启动脚本KEEP()指令保留的段)被间接引用了,比如链接脚本里写了KEEP(*(.text.some_function)),哪怕这个函数没被调用也会被保留。
三、CMake自动处理未用源文件的技巧
不想手动剔除源文件的话,不用修改源文件列表,只要保证上述编译/链接选项配置正确:
- 即使CMake包含了所有源文件,只要编译时拆分了段、链接时开启了垃圾回收,未被引用的函数/数据段会被自动从最终二进制中移除,不会占用空间。
- 如果确实想避免编译未用的源文件,可以用CMake的
OBJECT_LIBRARY把源文件打包成对象库,然后链接时配合$<TARGET_OBJECTS>,但本质上还是依赖gc-sections来过滤未用对象。
内容的提问来源于stack exchange,提问作者us3rnotfound
相关产品推荐
相关产品推荐

