GHC编译的二进制文件是否需要GHC或者它们是独立的?

45

如果朋友想运行我的Haskell二进制文件,他是否必须先安装Haskell,还是可以直接运行该二进制文件?

这个答案在Mac、Windows和Linux上都一样吗?


请参考关于动态链接的早期回答,https://dev59.com/NW025IYBdhLWcg3wRDq8。 - Don Stewart
关于静态链接,可以参考以下链接:https://dev59.com/Tm435IYBdhLWcg3w7kwK - Don Stewart
4个回答

45

GHC可以生成独立的二进制文件,不需要安装GHC本身,但是它们会链接到一些动态库,最显著的是libgmp。剩余的库在大多数Linux系统中通常都可以找到。我相信Windows上的情况也类似。

您可以使用Linux上的ldd检查您所依赖的动态库。这是我在Ubuntu Natty上获得的一个简单Hello World程序的结果:

$ echo 'main = putStrLn "Hello World"' > Hello.hs                                                   
$ ghc --make Hello.hs                                                                     
[1 of 1] Compiling Main             ( Hello.hs, Hello.o )
Linking Hello ...
$ ldd Hello                                                                                
    linux-vdso.so.1 =>  (0x00007fffe45ff000)
    libgmp.so.3 => /usr/lib/libgmp.so.3 (0x00007f8874cf9000)
    libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8874a74000)
    librt.so.1 => /lib/x86_64-linux-gnu/librt.so.1 (0x00007f887486b000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f8874667000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f88742d3000)
    libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f88740b4000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f8874f7a000)

2
ldd 应该也可以在 Mac OS X 上工作,而在 Windows 上,您可以使用 Dependency Walker 来获取相同的信息。 - Daniel Pryden
10
@Daniel Pryden:ldd 不在 OS X 上,但是你可以使用 otool -L 来获取类似的信息。 - mipadi

24

GHC将Haskell编译为目标代码,并链接运行时。这意味着您不需要安装Haskell编译器即可执行Haskell程序。

生成的可执行文件将使用某种静态和动态链接,用于C和Haskell库依赖项。任何静态链接的内容都不需要安装在用户的机器上。任何动态链接的内容必须被安装。

要查看您需要随可执行文件一起发送的内容,在Linux(或Cygwin)上使用ldd。通过向GHC传递-static,您可以强制几乎所有内容进行静态链接。


12

如果希望将一些C库与您的Haskell可执行文件静态链接,在Linux上可以使用GNU链接器的--whole-archive选项; 例如:

  ghc --make HelloZ.hs \
    -optl-Wl,--whole-archive \
      -optl/usr/lib/x86_64-linux-gnu/libffi.a \
      -optl/usr/lib/x86_64-linux-gnu/libz.a \
    -optl-Wl,--no-whole-archive

虽然它们相当常见,但是libffilibz并非普及的(我在Haskell二进制文件中经常看到libffi)。

这种方法最近在haskell-cafe上首次被建议给我。


1
非常抱歉,我之前回答时犯了一个错误——我在一个构建环境中进行测试,已经将一些.a文件复制到了 GHC 的 libdir 中。重要的是,所有库都必须在它们前面加上 -optl,就像上面(现在已更正)的示例中所给出的那样,否则 GHC 会重新排列它们与链接器选项的关系。 - solidsnack

5

对于大多数二进制文件,不需要安装GHC。但有些(例如xmonad)使用Haskell作为配置语言,在这种情况下,您需要一个编译器。

还有一个关于静态链接和动态链接的问题。我认为现在的默认设置仍然是静态链接,这种情况下将二进制文件从一台机器迁移到另一台机器应该很容易(只需要具有相同的架构和操作系统即可)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接