如何在链接脚本中添加单个目录下的所有目标文件?
解决嵌入式C项目中链接脚本批量匹配自动生成目标文件的问题
你遇到的核心问题是:自动生成的源文件编译后,链接脚本无法通过带路径的通配符匹配目标文件,只能逐个指定无路径的文件名,扩展性极差。以下是几个可行的解决方案,以及为什么之前的写法无效的原因:
方案1:给自动生成的目标文件统一标记自定义段
通过CMake给自动生成的源文件添加编译规则,让它们的.bss段数据统一进入一个自定义段,链接脚本直接引用这个自定义段即可,无需关心文件数量。
- 在CMake中配置自动生成源文件的编译属性:
# 假设AUTOGEN_SOURCES是你收集到的自动生成源文件列表 set_source_files_properties(${AUTOGEN_SOURCES} PROPERTIES COMPILE_FLAGS "-fdata-sections")
如果代码生成工具支持,也可以直接在生成的代码里给全局变量添加段属性:
// 代码生成时给所有.bss全局变量加上这个属性 __attribute__((section(".my_module_bss"))) int auto_generated_var;
- 链接脚本中直接映射自定义段到目标内存区域:
.my_module_bss : { *(.my_module_bss) } > YOUR_TARGET_MEMORY_REGION
方案2:将自动生成的目标文件打包为静态库
用CMake把所有自动生成的源文件编译成一个独立的静态库,链接脚本通过匹配静态库的段来批量收集目标文件内容。
- CMake中创建静态库:
add_library(autogen_module STATIC ${AUTOGEN_SOURCES}) # 指定静态库输出到专属文件夹(可选) set_target_properties(autogen_module PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/autogen_lib")
- 链接脚本中匹配静态库的
.bss段:
.my_module_bss : { autogen_module.a:*(.bss) } > YOUR_TARGET_MEMORY_REGION
注:如果静态库的名称或输出路径有变化,对应调整链接脚本里的库名即可。
方案3:统一目标文件输出目录并使用无路径通配符
因为当前仅无路径的文件名能被链接脚本匹配,可以让CMake把自动生成的目标文件集中到同一目录,然后用简单的文件名通配符匹配。
- 在CMake中设置自动生成目标文件的输出目录:
# 假设your_target是你的项目目标 set_target_properties(your_target PROPERTIES OBJECT_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/autogen_objs")
- 链接脚本中直接用文件名通配符匹配:
.my_module_bss : { *.c.obj(.bss) } > YOUR_TARGET_MEMORY_REGION
注:此方法要确保项目中其他模块没有同名的.c.obj文件,避免误匹配。
为什么之前的带路径写法无效?
链接脚本中的通配符*匹配的是链接器上下文里的目标文件名称,而非文件系统的完整路径。当CMake将目标文件传递给链接器时,链接器内部记录的是文件名(或相对于链接工作目录的短路径),而非你在链接脚本中写的完整路径,因此带路径的通配符模式无法匹配到目标文件。
内容的提问来源于stack exchange,提问作者daiogo
相关产品推荐
相关产品推荐

