我正在为C ++ 14模式下的GCC 7.3.1和C ++的ARM Cortex-M上的嵌入式应用程序开发固件。只有64k的闪存可用,我的二进制文件不合适。查看映射文件,我发现二进制文件中有一个名为__gcclibcxx_demangle_callback
的函数,占用了27k的闪存空间。我知道这与C ++名称分解有关。链接器不会放弃该符号,尽管我绝对不会在代码中进行任何名称分解。我在这里和那里都在使用STL。如何消除此功能以获得一些闪存空间?
我尝试将-ffreestanding -fno-exceptions -nostartfiles -fno-rtti
传递给编译器和链接器。即使我通过-nostdlib
,传递-lc -lg -lgcc -lstdc++
也会导致链接失败。
答案 0 :(得分:0)
更多选项:
-Os -flto -fno-fat-lto-objects -fuse-ld=gold -fuse-linker-plugin \
-Wl,--icf=all -Wl,--icf-iterations=4 -Wl,--gc-sections -Wl,--as-needed \
-Wl,--strip-all -Wl,-O3 -Wl,--orphan-handling=discard -Wl,--no-eh-frame-hdr \
-Wl,--no-ld-generated-unwind-info -fno-unwind-tables
已纠正错误
(--icf
专门针对“黄金”)
我只是在学习自己的方式,但是如果不这样做,则可以开始修改链接描述文件...您可以通过在链接行上传递“隐式”链接描述文件到常规默认设置( ld尝试读取任何看起来不像目标代码的脚本。我最好的猜测是,您需要将问题库分配到其自己的部分,然后将其丢弃: >
链接器将忽略地址分配(*注意输出部分 地址::)在废弃的输出节上,但链接程序脚本除外 在输出部分中定义符号。在这种情况下,链接器将 遵守地址分配,即使 部分被丢弃。
特殊输出节名称“ / DISCARD /”可用于丢弃 输入部分。分配给输出的任何输入部分 名为“ / DISCARD /”的部分不包含在输出文件中。
我觉得这确实不应该,但是还有--no-demangle
...
编辑:如果您尝试使用-nostdlib
进行编译,则可能需要-lgcc_s -lsupc++ -lm
,-B `your/compiler/dir`
等的某种组合
答案 1 :(得分:0)
@Russ Schultz的评论让我开始思考。很有可能确实是一些使用名称分解的STL代码,如果没有其他更适合嵌入式系统的libstdc ++,那将是令人惊讶的。显然,GNU Arm Embedded Toolchain提供了libstdc ++的备用版本。一种是“纳米”版本,可以通过将-specs=nano.specs
传递给链接器来轻松使用。这样可以大大减少生成的二进制文件的大小(115k至45k),并且粗略地看内容,它实际上仅包含必要的符号。除了一些很小的C ++ vtable之外,几乎没有代码膨胀。