c - 为什么链接后我的可执行文件更大

标签 c arm embedded

我有一个小的 C 程序,我需要在不同的芯片上运行。 可执行文件应小于 32kb。 为此,我有几个工具链,其中包含用于 arm、mips 等的不同编译器。

程序由几个文件组成,每个文件都被编译成一个目标文件,然后链接在一起成为一个可执行文件。

当我使用系统 gcc (x86) 时,我的可执行文件有 15kb 大。 使用 arm 工具链,可执行文件大小为 65kb。 使用另一个工具链是 47kb。

例如,对于 arm,可执行文件中包含的所有对象加在一起有 14kb 大。

对象使用以下选项编译:

-march=armv7-m -mtune=cortex-m3 -mthumb -msoft-float -Os

为了链接,使用了以下选项:

-s -specs=nosys.specs -march-armv7-m

nosys.specs 库有 274 字节大。

当我的代码只有 14kb 而库有 274 字节时,为什么我的可执行文件仍然大得多 (65kb)?

更新:

根据答案的建议,我从我的代码中删除了所有 malloc 和 printf 命令,并删除了未使用的包含。我还添加了编译标志 -ffunction-sections -fdata-sections 和链接标志 --gc-sections ,但可执行文件仍然太大。

为了实验,我创建了一个虚拟程序:

int main()
{
    return 1;
}

当我用不同的编译器编译程序时,我得到非常不同的可执行文件大小:

8.3 KB : gcc -Os
22 KB  : r2-gcc -Os
40 KB  : arm-gcc --specs=nosys.specs -Os
1.1 KB : avr-gcc -Os

那么为什么我的 arm-gcc 可执行文件要大得多? 我猜 avr-gcc 可执行文件也进行静态链接。

最佳答案

您的 x86 可执行文件可能是动态链接的,因此您使用的任何标准库函数——mallocprintf、字符串和数学函数等——都不包括在内在二进制文件中。

ARM 可执行文件是静态链接的,因此这些函数必须包含在您的二进制文件中。这就是它更大的原因。要使其更小,您可能需要考虑使用 -ffunction-sections -fdata-sections 进行编译,然后使用 --gc-sections 进行链接以丢弃任何未使用的函数或数据来自你的二进制文件。

(“nosys.specs 库”不是一个库。它是一个配置文件。真正的库文件在别处。)

关于c - 为什么链接后我的可执行文件更大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39172325/

相关文章:

c - 如何访问 CPU 的热传感器?

c - 在另一个程序中加载一个 c 程序

为 ARM M4 编译和链接位置独立代码 (PIC)

embedded - 在 ARM CPU 上启用外部中止

在运行时从具有相同函数签名的许多文件中的一个文件调用 C 函数

c++ - 除了 autoconf 之外,m4 有什么值得注意的用途吗?

c - 要找到数组之间的共同值,还需要找到计数

linux - ARM 是否在 NEON 运行时闲置?

programming-languages - 有哪些可用的在微小内存中运行的交互式语言?

c - -Werror 导致编译器在#warning 处停止。我能做些什么来防止这种情况发生?