我正在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之外。
答案 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
apk add libc-dev
(的元包,其中做到了这一点)一旦做到这一点,你可以用你的编译水晶项目crystal build src/FILE.cr -o bin/FILE --release --static
现在有了无依赖性的Crystal二进制文件,您可以轻松地将项目作为RPM分发(例如,这就是我首先发现此问题的方式)。
我也在网站上的an article中对此进行了总结。