2016-02-03 68 views
6

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

不幸的是,我无法绕过libc依赖项,所以我想大概必须在拥有最低版本libc的系统上编译可执行文件,我希望以此为目标。我认为它应该是向前兼容的。

但是,我遇到了libssl的困难。 Debian的喘息的默认安装中似乎并没有配备的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有多少其他依赖关系?

我的可执行文件必须在新安装的linux系统上运行。那么,我怎样才能生成一个没有依赖的Crystal可执行文件呢?除了libc,我想。

+0

我喜欢这个问题;有一段时间一切都是静态联系的。蠕虫会转动。 – will

回答

7

在Linux中,您可以使用ldd命令列出可执行文件需要的共享库。在OSX中,otool -L可用于相同的目的。

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

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

为了使用这些库,你可以运行:

$ LIBRARY_PATH=/opt/crystal/embedded/lib crystal build my_app.cr 

这应该倾向于在该目录中可用库考虑安装在标准位置在别人面前。

不幸的是,OpenSSL没有与Crystal一起发布,因此您必须复制或构建一个静态版本libssllibcrypto。无论如何,这是一个通用的库,可用于任何Linux发行版。

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

+1

太棒了,谢谢。我成功地用'crystal build FILE.cr --cross-compile'Linux x86_64“--target”x86_64-unknown-linux-gnu“和'cc FILE.o -o FILE -Wl,-Bstatic -levent -lpcre -lssl -lgc -lcrypto -lz-W1,-Bdynamic -ldl -lrt -lpthread -lc',但你的方法要简单得多。我使用'apt-file'来定位'.a'文件,然后将它们软链接到crystal lib目录中。 –

+0

静态链接的32位编译可执行文件将在64位Linux中正常工作吗? –

+0

“objdump”对于顺便列出动态库依赖关系也很有用。 –