我创建了一个小程序作为系统的概念验证,这些系统将在嵌入式平台上实现。该程序是用C ++ 11编写的,使用std编译并在笔记本电脑上运行。应该在以后实施的最终程序是嵌入式系统。我们无权访问嵌入式平台的编译器。
我想知道是否有一种方法可以在将应用程序移植到嵌入式平台时以合理且可比较的方式确定程序静态内存(已编译二进制文件的大小)。 要求是二进制文件的大小小于10kb。 编译时我们的二进制文件大小为700Kb,并使用以下标志进行剥离:
g++ options: -Os -s -ffunction-sections -fdata-sections
linker options: -s -Wl,--gc-sections
strip libmodel.a -s -R .comment -R .gnu.version --strip-unneeded -R .note
在使用条带和优化选项之前,它占用了4MB。
我仍然离开了,并不是那么大的计划。如何以任何方式与嵌入式平台上的等效程序进行比较是合理的。
答案 0 :(得分:4)
请注意,二进制文件的大小可能有点具有欺骗性,因为未初始化的变量(.bss部分)不一定会占用二进制文件中的物理空间,因为这些通常只是存在,而实际上没有任何空间给予他们......这通常是由OS加载程序在运行程序时发生的。
objdump
(http://www.gnu.org/software/binutils/)或elfdump
或精灵工具链(http://sourceforge.net/apps/trac/elftoolchain/)可帮助您确定各个细分,数据和文字的大小,如以及各个函数和全局等的大小。所有这些程序“查看”到您编译的二进制文件并提取大量信息,如.text,.data部分的大小,列出各种符号,它们的位置和大小,甚至可以解散.text部分......
在ELF图像test.elf上使用elfdump的示例可能是elfdump -z test.elf > output.txt
。这将转储包括文本部分反汇编在内的所有内容。例如,从我系统上的elfdump
我看到了
Section #6: .text, type=NOBITS, addr=0x500, off=0x5f168
size=149404(0x2479c), link=0, info=0, align=16, entsize=1
flags=<WRITE,ALLOC,EXECINSTR>
Section #7: .text, type=NOBITS, addr=0x24c9c, off=0x5f168
size=362822(0x58946), link=0, info=0, align=4, entsize=1
flags=<WRITE,ALLOC,EXECINSTR,INCLUDE>
....
Section #9: .rodata, type=NOBITS, addr=0x7d5e4, off=0x5f168
size=7670(0x1df6), link=0, info=0, align=4, entsize=1
flags=<WRITE,ALLOC>
所以我可以看到我的代码占用了多少(.text部分)和我的只读数据。稍后在文件中我会看到......
Symbol table ".symtab"
Value Size Bind Type Section Name
----- ---- ---- ---- ------- ----
218 0x7c090 130 LOC FUNC .text IRemovedThisName
所以我可以看到我的函数IRemovedThisName
需要130个字节。快速脚本允许您列出按大小排序的函数和按大小排序的变量。这可以指出你要优化的地方......
有关objdump
尝试http://www.thegeekstuff.com/2012/09/objdump-examples/的一个很好的例子,特别是第3节,其中介绍了如何使用-h
选项获取节标题的内容。
关于程序如何在两个不同的平台上进行比较,我认为您只需要在两个平台上进行编译并比较每个系统上obj/elfdump
的结果 - 结果将取决于系统指令设置,每个编译器可以优化的程度,一般硬件架构差异等。
如果您无法访问嵌入式系统,则可以尝试在笔记本电脑上使用为最终目标配置的交叉编译器。这将为您提供适合嵌入式平台的二进制文件和分析文件的工具(即objdump
的跨平台版本)。这将为您提供一些关于程序在最终嵌入式系统中的外观的球场图。
希望这有帮助。
编辑:这也有助于How to get the size of a C function from inside a C program or with inline assembly?
答案 1 :(得分:1)
看起来包含的库占用了大量的空间(正如评论中指出的那样),通过删除这些,可以将以下标志的大小减小到几乎没有:
set(CMAKE_CXX_FLAGS "-Os -s -ffunction-sections -fdata-sections -DNO_STD -fno-rtti -fno-exceptions")
set(CMAKE_EXE_LINKER_FLAGS "-s -Wl,--gc-sections")
使用以下方法删除任何不必要的代码:
strip libmodel.a -s -R .comment -R .gnu.version --strip-unneeded -R .note
4MB可以减少到9.4kb,低于我们的限制。
总之,std
占用了大量的空间。