移动已编译的Haskell程序

Mat*_*hid 9 linux haskell ghc

我想在一个Linux机器上编译一个Haskell程序,然后在另一个Linux机器上运行它.但是,这似乎根本不起作用.我收到有关缺少库的错误.

据推测,当我安装GHC时,包管理器还会安装所需的所有库和内容.[我有些恼怒地注意到至少有一个包装系统无法安装GCC,如果没有GHC,GHC显然无法运行......]但是当然,目标系统没有安装这些依赖项.因此,如果我将已编译的二进制文件复制到目标系统,它就无法运行.

有什么方法可以解决这个问题吗?我习惯使用Windows,如果你编译一些东西,它只适用于所有Windows系统.(至少,直到你真正尝试使用非标准设施,如数据库访问或其他东西......)我在Haskell中编译了Hello World,将其复制到另一个Linux盒子,并抱怨libgmp.so.10缺失或像那样神秘的mumbo-jumbo.

只是为了让事情变得有趣:我只有FTP访问目标机器,而不是shell访问.我甚至不完全确定它正在运行什么操作系统.所以我可以以任何我想要的方式更改我的构建机器,但除了将文件复制到目标机器之外,我无法对目标机器做任何事情.

dfl*_*str 9

在这方面,Linux的行为就像Windows一样.如果在Linux上编译Haskell可执行文件,它将在任何具有正确库的Linux发行版上运行.问题是在Windows中,Haskell可执行文件不是用动态版本的libgmp编译的; 它们使用静态版本编译(以便将库编译成可执行文件),因为在分发可执行文件时,在Windows上处理dll非常困难.在Linux上处理新库的安装相对容易.

您可以做的是将/ usr/lib中的libgmp.so.10(可能是指向不同文件的符号链接)复制到与可执行文件相同的目录中.然后,可以在启动可执行文件之前将LD_LIBRARY_PATH环境变量设置为".",表示当前目录.这将使Linux在与其启动的可执行文件相同的目录中查找库,从而使其找到库.这可以使用启动器脚本完成:

#!/bin/sh
export LD_LIBRARY_PATH=.
`dirname "$0"`/myexecutable "$@"
Run Code Online (Sandbox Code Playgroud)

保存此脚本并将其标记为可执行文件chmod +x myscript将使您的可执行文件正常工作.

您可以使用该ldd命令检查可执行文件可能需要的哪些库以及目标系统上不存在的库.

  • ..对其所有依赖关系.您将获得大型二进制文件,其中包含运行所需的所有代码.你可以为GHC提供`-static`选项,它应该编译你的二进制文件,其中包含所有库. (3认同)
  • 包管理器只管理包.文件被复制.没有魔法参与. (2认同)
  • 你看,ELF(在linux中使用)和PE(在windows中使用)可执行文件格式都支持静态和动态链接.在所有主要的Linux发行版中,大多数已安装的二进制文件都由发行版维护者动态链接到此发行版也提供的共享库.因此将`/ usr/bin/gnome-panel`移动到另一个Linux系统可能很困难,因为共享库名称被编译成二进制文件,并且可能无法在外部发行版中解析它们.另一方面,没有什么能阻止你编译你的二进制文件和*静态*链接它... (2认同)