【问题标题】:How small can I make a clang executable?我可以使 clang 可执行文件多小?
【发布时间】:2023-02-14 23:05:40
【问题描述】:

我只是想看看我能把这个 C++ 代码写多小

#include <iostream>
using namespace std;

int main() {
    cout << "hi";
}

使用这个 zsh 命令:

g++ test.cpp -Os -g -o main

但我能做到的最小是 52 Kb,那么有什么办法可以让它更小吗?

【问题讨论】:

  • 不编译调试通常会删除一堆东西
  • “small”和“-g”有冲突。
  • 使用write(假设是 Linux)而不是 cout
  • 请记住,您将获得链接到您的代码中的一大块 C 运行时库。您可以使用objdump 来查看您的代码中真正包含的内容。
  • 您可以(应该!)通过删除 using namespace std; 并将 cout 更改为 std::cout 来减小源代码的大小。

标签: c++ clang


【解决方案1】:

将你的代码和编译器标志与g++ 11.2一起使用我得到一个35,8kB可执行文件(不同的结果可以通过使用不同的编译器版本或目标系统来解释)。

  1. 删除 -g 标志(GDB GNU 调试器或 LLDB Clang/LLVM 调试器的调试符号)使输出文件的大小减小到16,3kB.
  2. 您可以通过以下方式修改代码而不更改其功能 (16,0kB):
    #include <stdio.h>
    
    int main(){
        fputs("hi", stdout);
        return 0;  // doesn't change the output, only here for completeness sake
    }
    
    1. 使用clang 编译以上代码进一步将输出可执行文件的大小减小到15,9kB.

    2. 添加-s标志(剥离调试信息):14,5kB(使用 clangg++ 11.2 的结果相同)

    比较表(最好的结果在大胆的):

    code compiler flags size step
    original g++ 8.5.0 -Os -g 38 496 B
    -Os 16 304 B
    -Os -s 14 464 B
    g++ 11.2.0 -Os -g 35 848 B 0
    -Os 16 320 B 1
    -Os -s 14 464 B
    clang 11.0.1 -Os -g 30 736 B
    -Os 16 304 B
    -Os -g 14 552 B
    clang 13.0.0 -Os -g 29 312 B
    -Os 16 232 B
    -Os -s 14 488 B
    modified g++ 8.5.0 -Os -g 18 552 B
    -Os 16 000 B
    -Os -s 14 464 B
    g++ 11.2.0 -Os -g 18 616 B
    -Os 16 000 B 2
    -Os -s 14 464 B
    clang 11.0.1 -Os -g 16 720 B
    -Os 15 960 B
    -Os -s 14 528 B
    clang 13.0.0 -Os -g 16 640 B
    -Os 15 888 B 3
    -Os -s 14 464 B 4

【讨论】:

  • 尝试添加-flto
  • 如果您还没有这样做,您还应该去除符号,即 -s-Wl,-s 或调用 strip
  • @user17732522 我正要发布一个关于 -s...
  • 请注意,由于 glibc 是动态链接的,因此进程大小(运行时内存使用量)仍然会大得多。你可以用/usr/bin/time -v来测量它。使用较小的 libc,例如musl 或 dietlibc 和 -static,根据这个膨胀比较,你可以降低到 0.2K:etalabs.net/compare_libcs.html
  • 另一个想法是使用-m32 构建更小的 32 位二进制文​​件。 x86_64 CPU 仍然可以运行它。顺便说一句,在我的 Ubuntu 18 系统上,我得到的结果要小得多 (5612 B)。你有什么系统?
【解决方案2】:

如前所述,您应该通过“-s”去除符号

通过使用“-m32”,您可以定义 32 位代码生成,这应该更紧凑一些。

最后,我建议使用UPX 压缩器。

gcc -s -Os -m32 main.c

gcc 12.2.0 + upx = 6144 字节 win32 可执行文件

通过一些额外的努力,您可能会进入 1k 足迹范围以下:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2016-12-25
    相关资源
    最近更新 更多