Haskell工具堆栈和可执行文件大小

问题描述 投票:4回答:1

我用Stack tool创建了一个Haskell CLI。感谢Travis,我已经成功设置了交叉编译功能,但是我不明白为什么linux(6MB),osx(2MB)和Windows(18MB!)之间的可执行文件大小如此不同。怎么会来?

发布:https://github.com/unfog-io/unfog-cli/releases/tag/v0.1.2

Travis conf:https://github.com/unfog-io/unfog-cli/blob/master/.travis.yml

编辑

当我用tar.gz压缩可执行文件时,我减少了差异,但是仍然!我现在有linux(1.35MB),osx(0.61MB),windows(3.93MB)(请参见release

haskell cross-platform travis-ci executable haskell-stack
1个回答
0
投票

Linux和MacOS版本之间的差异可能归因于“ split sections”。

在Linux上启用-split-sections GHC标志会将每个已编译的函数置于其自己的链接器节中(而不是将所有函数置于单个“ .text”节中的传统方法)。这使链接器可以丢弃没有使用的代码,否则将无法实现粒度。

不幸的是,all依赖关系需要使用此标志构建才能受益。您可以通过将以下行添加到项目的stack.yaml文件中来强制Stack正确地重建所有内容:

ghc-options:
    "$everything": -split-sections

这种为依赖项指定GHC选项的方法已在here中记录。

如果您通过此更改来重建unfog,则实际上会从头开始重建“ base”和“ vector”以及其他所有内容,因此可能需要一段时间。但是,生成的二进制文件值得。不剥皮,它的大小从大约11Meg下降到4Meg,并且如果您剥离它,它只是:

-rwxr-xr-x 1 buhr buhr 1494696 Nov 27 19:40 unfog

甚至比您发布的MacOS版本还要小。

现在,据我所知,原始MacOS版本仅为2Meg的原因是MacOS链接器已经实现了类似于拆分部分的功能。我不确定also为MacOS构建启用-split-sections是否会带来额外的收益,或者-split-sections是否为MacOS的自动默认设置。无论如何,尝试它不会有任何伤害。

对于Windows,它如此巨大的主要原因是MinGW GCC工具链用于编译Windows二进制文件,因此存在GNU类库的完整兼容性层(libc,libm,libpthread,libgmp等),以及- -与Linux和MacOS版本不同-它们都被静态链接到Windows二进制文件中。 Windows的唯一动态链接是到标准Windows DLL。

注意-split-sections在Windows上可能会或可能不会。在错误跟踪器上有一些注释使其不清楚。无论如何,可能值得尝试一下是否有所作为。

一些其他参考:

© www.soinside.com 2019 - 2024. All rights reserved.