交叉编译时的文件大小差异

Filesize difference when cross compiling

本文关键字:文件大小 交叉编译      更新时间:2023-10-16

我正在用c++编写一个小型应用程序,它在我的主机(linuxx86)和目标机器(arm)上运行
我遇到的问题是,在主机上,我的二进制文件大小约为700kb,但在目标机器上,它约为7mb
我在两个平台上使用相同的编译开关。我的第一个想法是,目标机器上的一个库被静态链接,但我用objdump检查了这两个二进制文件,它们都使用相同的动态链接库。那么,有人能给我一个提示吗?我怎么才能弄清楚为什么尺寸有这么大的差异?

虽然不同的计算机体系结构在理论上可以为同一程序需要完全不同数量的可执行代码,但在现代体系结构中,10的因素并不是真正期望的。ARM和x86可能有所不同,但它们仍然是在同一个宇宙中设计的,在这个宇宙中,内存和带宽是不可浪费的,这导致CPU设计者试图保持可执行代码尽可能紧凑。

因此,我将按概率顺序考虑以下可能性:

  • 符号剥离:如果两个二进制文件中的一个已经从其符号中剥离,那么它将明显更小,尤其是在使用调试信息编译的情况下。您可能想尝试剥离这两个二进制文件,看看会发生什么。

  • 静态链接:我偶尔会遇到嵌入式目标的构建系统,它们更喜欢静态链接而不是使用共享库。检查每个二进制文件的库依赖关系可能会检测到这一点。

  • 额外启用的代码:较大的二进制文件可能启用了额外的代码,因为例如构建系统找到了额外的可选库,或者因为目标平台需要特定的句柄。

    尽管如此,10倍可能太大了,除非较小的二进制文件缺少很多功能,或者较大的二进制文件静态地链接到了一些可选库中。

  • 不同的编译器配置:您不仅应该查看提供的编译器选项,还应该查看编译器为每个目标使用的默认值。例如,如果编译器在一个体系结构中具有明显更高的内联或循环展开限制,则生成的可执行文件可能会显著变平衡。

首先,没有理由期望为不同体系结构编译的相同代码在大小上彼此有任何关系。你可以很容易地让A大于B,然后更改一行代码,然后B大于A。

其次,你所说的"二进制"是我猜的elf,它有点二进制,有些开销很大。开销可能因体系结构和其他此类事物而异。

最重要的是,如果您正在为两个体系结构/平台编译相同的代码,或者使用不同的编译器或为同一体系结构编译选项,则没有理由期望文件大小彼此之间有任何关系。

不同的体系结构可以有完全不同的方式来处理同一件事。例如,在CISC(例如x86)体系结构上加载立即值通常是一条指令,而在RISC(例如ppc、arm)上,通常是多条指令,实际需要的数量取决于值。例如,如果指令集只允许16位立即值,则可能需要多达7条指令来加载64位值(按16位加载并在加载之间切换)。因此,代码本质上是不同的。

一个至今未提及但与ARM/x86比较相关的原因是浮点仿真。如今,所有x86芯片都支持本机FP(x86-64甚至通过SSE支持SIMD FP),但ARM CPU通常缺少FP单元。这反过来意味着,即使是简单的FP加法也必须转化为对指数和尾数的长序列整数运算。