11

我正在用 C++ 开发裸机 cortex-M3 以获得乐趣和利润。我使用 STL 库,因为我需要一些容器。我认为通过简单地提供我的分配器,它不会向最终的二进制文件添加太多代码,因为你只得到你使用的东西。

实际上,我什至根本没想到会使用 STL(给我的分配器)进行任何链接过程,因为我认为这都是模板代码。

顺便说一句,我正在编译-fno-exception

不幸的是,我的二进制文件中添加了大约 600KB 或更多。我用 nm 查看了最终二进制文件中包含哪些符号,这对我来说似乎是个笑话。清单太长了,我不会尝试过去。虽然有一些弱符号。

我还查看了链接器生成的 .map 文件,我什至发现了 scanf 符号

.text
0x000158bc       0x30   /CodeSourcery/Sourcery_CodeBench_Lite_for_ARM_GNU_Linux/bin/../arm-none-linux-gnueabi/libc/usr/lib/libc.a(sscanf.o)
0x000158bc                __sscanf
0x000158bc                sscanf
0x000158bc                _IO_sscanf

和:

$ arm-none-linux-gnueabi-nm binary | grep scanf
000158bc T _IO_sscanf
0003e5f4 T _IO_vfscanf
0003e5f4 T _IO_vfscanf_internal
000164a8 T _IO_vsscanf
00046814 T ___vfscanf
000158bc T __sscanf
00046814 T __vfscanf
000164a8 W __vsscanf
000158bc T sscanf
00046814 W vfscanf
000164a8 W vsscanf

我该如何调试呢?首先,我想了解 GCC 用于链接的确切内容(我正在通过 GCC 链接)。我知道如果在文本段中找到符号,则会使用整个段,但这仍然太多了。

任何有关如何解决此问题的建议将不胜感激。

谢谢

4

2 回答 2

6

使用 GCC-v-Wl,-v选项将显示正在使用的链接器命令(和链接器的版本信息)。

您使用的是哪个版本的 GCC?我对 GCC 4.6 进行了一些更改(请参阅PR 44647PR 43863)以减少代码大小以帮助嵌入式系统。仍然有一个未完成的增强请求 ( PR 43852 ) 允许禁用包含您看到的 IO 符号 - 其中一些来自详细终止处理程序,当进程因活动异常终止时打印一条消息。如果您不使用 execptions,那么其中一些代码对您来说毫无用处。

于 2012-07-21T18:06:17.017 回答
2

问题不在于 STL,而在于标准库。

STL 本身是纯粹的(在某种程度上),但标准库还包括所有这些流包,而且您似乎也设法加入了libc......

问题是标准库从来没有被分开,所以可能没有太多关注重用 C 标准库中的东西......

您应该首先尝试确定在编译时提取了哪些文件(strace 例如使用),这样您可以验证您是否只使用过仅头文件。

然后,您可以尝试删除发生的链接。有一些选项可以传递给 gcc 以精确地表明您想要一个标准的无库构建,--nostdlib例如,但是我对这些内容不够精通,无法在这里准确地指导您。

于 2012-07-21T17:11:09.933 回答