2016-02-03 67 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」對於順便列出動態庫依賴關係也很有用。 –