如何在GNU链接脚本中按目录批量映射指定文件夹下的.bss和.data段
你当前的写法无法匹配子目录下的段,核心是两个问题:
- GNU ld的默认
*通配符不会匹配路径分隔符/,所以"./custom/*"只能匹配custom根目录下直接存放的目标文件,无法匹配子目录内的文件 - 如果你自定义的段定义放在了默认
.bss、.data段定义之后,链接器会先把对应段匹配到默认规则,自然不会走到你的自定义配置中
修正后的链接脚本写法
注意要将这两个自定义段放在默认.bss、.data段的定义之前:
.custom_bss (NOLOAD) : AT (0) { custom_bss_start = .; /* ** 通配符递归匹配custom下所有层级子目录的.o目标文件 */ ./custom/**/*.o (.bss .bss.* COMMON) custom_bss_end = .; } /* 初始化数据需要加载,因此单独定义 */ .custom_data : AT(ld_custom_data_load_addr) { custom_data_start = .; ./custom/**/*.o (.data .data.*) custom_data_end = .; }
补充说明
- 额外增加普通
.bss、.data和COMMON段是为了兼容极端场景:比如部分编译单元未开启-fdata-sections,或者全局变量被分配到了COMMON段,避免出现遗漏 **递归通配符从GNU ld 2.34版本开始支持,如果你的工具链版本过低不支持该语法,可以直接通过构建系统传入当前激活的custom配置子目录路径,直接指定路径即可,比如激活的是build_cfg1就写./custom/build_cfg1/*.o- 如果调整后仍匹配不到,可以先通过
objdump -t <custom下的目标文件路径>确认传入链接器的目标文件路径前缀,部分构建系统会展开为绝对路径,对应修改匹配规则的前缀即可 - 验证方法:链接时添加
-Map=output.map参数生成映射文件,搜索custom下的目标文件名,即可确认对应段是否被正确分配到自定义段中
内容的提问来源于stack exchange,提问作者Jonathon S.
相关产品推荐
相关产品推荐

