2016-02-03 14 views
6

Sto scrivendo un programma in Crystal, che intendo compilare e passare ad altri sistemi per l'esecuzione. Idealmente, non dovrebbe avere dipendenze, poiché i sistemi di destinazione saranno nuove installazioni di Linux.Come posso produrre un eseguibile Crystal senza dipendenze?

Purtroppo non riesco ad aggirare la dipendenza di libc, quindi presumibilmente dovrò compilare l'eseguibile su un sistema che possiede la versione più bassa di libc che desidero colpire. Immagino dovrebbe essere avanti compatibile.

Ho difficoltà con libssl, tuttavia. Le installazioni di default di Debian Wheezy non sembrano venire con libssl, così ottengo questo errore quando si esegue il file eseguibile:

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

presumo esista questa dipendenza perché ho require "http/client" nella mia fonte. Tuttavia, non faccio alcuna chiamata relativa a ssl, poiché la uso solo per connettermi a siti Web non protetti.

Apparentemente ho anche una dipendenza su libevent-2.0.so.5. Presumibilmente tutti i programmi Crystal fanno. Chissà quante altre dipendenze ha Crystal?

I miei eseguibili devono essere eseguiti su un sistema linux appena installato. Quindi, come posso produrre un eseguibile Crystal senza dipendenze? A parte la libc, suppongo.

+0

Mi piace questa domanda; un tempo tutto era staticamente collegato. Il verme gira. – will

risposta

7

In Linux, è possibile elencare le librerie condivise di cui un eseguibile necessita utilizzando il comando ldd. In OSX, otool -L potrebbe essere utilizzato per lo stesso scopo.

Normalmente, il linker utilizzerà le librerie condivise mentre costruisce l'eseguibile se può trovarle. Quindi, quello che devi fare è forzare il linker ad usare invece le librerie statiche. (In futuro potremmo aggiungere un flag al compilatore per forzare questa scelta)

Si dovrebbero trovare alcune di queste librerie statiche in/opt/crystal/embedded/lib. Li usiamo per generare un compilatore Crystal portatile.

Per poter utilizzare queste librerie è possibile eseguire:

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

Questo dovrebbe preferire librerie disponibili in quella directory prima di considerare gli altri installati nelle posizioni standard.

Sfortunatamente, OpenSSL non è distribuito con Crystal, quindi è necessario copiare o creare una versione statica di libssl e libcrypto. È comunque una libreria comune, disponibile in qualsiasi distribuzione Linux.

Per quanto riguarda libc, è più difficile. Compiliamo il binario di Crystal per le versioni usando le vecchie distribuzioni CentOS e Debian per renderlo compatibile con molte altre versioni di libc.

+1

Fantastico, grazie. Ho avuto successo con 'crystal build FILE.cr --cross-compile" Linux x86_64 "--target" x86_64-unknown-linux-gnu "' e 'cc FILE.o -o FILE -Wl, -Bstatic -levent -lpcre -lssl -lgc -lcrypto -lz -Wl, -Bdynamic -ldl -lrt -lpthread -lc', ma la tua strada è molto più semplice. Ho usato 'apt-file' per localizzare i file' .a', poi li ho linkati nella directory crystal lib. –

+0

Un file eseguibile compilato a 32 bit collegato staticamente funzionerà correttamente con linux a 64 bit? –

+0

'objdump' è utile per elencare anche le dipendenze della libreria dinamica, tra l'altro. –