【发布时间】:2020-01-21 12:56:50
【问题描述】:
我很惊讶地发现,即使是这样的简单程序:
print_string "Hello world !\n";
当通过ocamlopt 使用一些非常激进的选项(使用musl)静态编译为本机代码时,在我的系统上仍然约为 190KB。
$ ocamlopt.opt -compact -verbose -o helloworld \
-ccopt -static \
-ccopt -s \
-ccopt -ffunction-sections \
-ccopt -fdata-sections \
-ccopt -Wl \
-ccopt -gc-sections \
-ccopt -fno-stack-protector \
helloworld.ml && { ./helloworld ; du -h helloworld; }
+ as -o 'helloworld.o' '/tmp/camlasm759655.s'
+ as -o '/tmp/camlstartupfc4271.o' '/tmp/camlstartup5a7610.s'
+ musl-gcc -Os -o 'helloworld' '-L/home/vaab/.opam/4.02.3+musl+static/lib/ocaml' -static -s -ffunction-sections -fdata-sections -Wl -gc-sections -fno-stack-protector '/tmp/camlstartupfc4271.o' '/home/vaab/.opam/4.02.3+musl+static/lib/ocaml/std_exit.o' 'helloworld.o' '/home/vaab/.opam/4.02.3+musl+static/lib/ocaml/stdlib.a' '/home/vaab/.opam/4.02.3+musl+static/lib/ocaml/libasmrun.a' -static -lm
Hello world !
196K helloworld
如何从 ocamlopt 获取最小的二进制文件?
190KB 的大小对于像今天的限制(iot、android、alpine VM...)这样的简单程序来说太过分了,并且与简单的 C 程序(大约 6KB,或直接编码 ASM)相比很差并调整一些东西以获得可能在 150B 左右的工作二进制文件)。我天真地认为我可以简单地放弃C 来编写简单的静态程序来做一些琐碎的事情,编译后我会得到一些简单的汇编代码,这些代码与等效的 C 程序相比不会那么大。那可能吗 ?
我认为我理解的内容:
当删除 gcc 的 -s 以获取有关二进制文件中剩余内容的一些提示时,我可以注意到很多 ocaml 符号,并且我还读到了 ocamlrun are meant to be interpreted even in this form 的一些环境变量。就好像ocamlopt 所说的“本地编译”是将程序的ocamlrun 和非本地bytecode 打包到一个文件中并使其可执行。不完全是我所期望的。我显然错过了一些重要的点。但如果是这样的话,我会很感兴趣为什么它不像我预期的那样。
其他编译为本机代码的语言也有同样的问题:给一些天真的用户(比如我自己)留下大致相同的问题:
我也用 Haskell 进行了测试,并且在没有调整的情况下,所有语言的编译器都会为“hello world”程序生成 700KB 以上的二进制文件(调整之前的 Ocaml 也是如此)。
【问题讨论】:
-
虽然没有回答问题,但我相信下面的作品可能会对这篇帖子的潜在观众感兴趣(注意,与作品无关)algo-prog.info/ocapic/web/index.php?id=ocapic
标签: compilation size ocaml executable minimum