如何生成没有依赖项的Crystal可执行文件?

时间:2016-02-03 00:28:02

标签: dependencies static-linking crystal-lang

我正在Crystal编写一个程序,我打算编译并移动到其他系统执行。理想情况下,它应该没有依赖关系,因为目标系统将是linux的全新安装。

可悲的是,我无法绕过libc依赖项,因此我可能必须在拥有我希望定位的最低版本libc的系统上编译可执行文件。我认为它应该是向前兼容的。

但是,我对libssl有困难。 Debian Wheezy的默认安装似乎没有附带libssl,因此在运行可执行文件时出现此错误:

error while loading shared libraries: libssl.so.1.0.0:
cannot open shared object file: No such file or directory

我认为这种依赖存在,因为我的源代码中有require "http/client"。但是,我没有进行与ssl相关的呼叫,因为我只使用它连接到不安全的网站。

我显然也依赖libevent-2.0.so.5。据推测,所有Crystal程序都可以。谁知道Crystal有多少其他依赖?

我的可执行文件必须在新安装的Linux系统上运行。那么,如何生成没有依赖项的Crystal可执行文件?我认为除了libc之外。

2 个答案:

答案 0 :(得分:10)

在Linux中,您可以使用public class Card { //Data private int rank; private char rank2; private char suit; //more codes (constructor etc.) //toString public String toString ( ) { if (rank == 11) rank2 = 'J'; else if (rank == 12) rank2 = 'Q'; else if (rank == 13) rank2 = 'K'; else if (rank == 14) rank2 = 'A'; else return rank2 + suit; // <----error here. } 命令列出可执行文件所需的共享库。在OSX中,ldd可用于相同的目的。

通常,链接器在构建可执行文件时将使用共享库,如果它可以找到它们。因此,您需要做的是强制链接器使用静态库。 (将来我们可能会在编译器中添加一个标志来强制进行此选择)

您应该在/ opt / crystal / embedded / lib中找到一些静态库。我们使用它们来生成可移植的Crystal编译器。

要使用这些库,您可以运行:

otool -L

在考虑安装在标准位置的其他库之前,应该更喜欢该目录中可用的库。

不幸的是,OpenSSL不随Crystal一起发布,因此您必须复制或构建$ LIBRARY_PATH=/opt/crystal/embedded/lib crystal build my_app.cr libssl的静态版本。无论如何,它都是一个通用的库,可以在任何Linux发行版中使用。

关于libcrypto,这更棘手。我们使用旧的CentOS和Debian发行版为版本编译Crystal二进制文件,使其与更多libc版本兼容。

答案 1 :(得分:2)

Crystal docs提到--static编译器标志当前仅在Alpine Linux上有效(并建议使用Alpine Linux Docker容器)。

如果你不进泊坞窗,但碰巧有放浪你的机器上,你可以使用的(relativkreativ/alpine),而不是通过建立自己的麻烦我去阿尔卑斯框。

<强>在任一情况下,静态上高山联作品。

只需执行以下步骤:

  • 启用/etc/apk/repositories中的社区存储库
  • 运行apk update获取最新的软件包列表
  • 使用apk add crystal shards
  • 安装Crystal
  • 拉在与所述正确的libc apk add libc-dev(的元包,其中做到了这一点)

一旦做到这一点,你可以用你的编译水晶项目crystal build src/FILE.cr -o bin/FILE --release --static

现在有了无依赖性的Crystal二进制文件,您可以轻松地将项目作为RPM分发(例如,这就是我首先发现此问题的方式)。

我也在网站上的an article中对此进行了总结。