Imparare a compilare cose dalla fonte (su Unix / Linux / OSX)


47

Mentre installo software da pacchetti (MacPorts / apt-get) dove possibile, spesso mi trovo a dover compilare pacchetti dal sorgente. ./configure && make && sudo make installdi solito è abbastanza, ma a volte non funziona - e quando non lo fa, mi blocco spesso. Questo in qualche modo si riferisce quasi sempre alle dipendenze di altre librerie.

Mi piacerebbe imparare quanto segue:

  • Come faccio a capire a quali argomenti passare ./configure?
  • Come funzionano le librerie condivise su OS X / Linux: dove vivono nel filesystem, come le ./configure && maketrovano, cosa succede realmente quando sono collegate
  • Quali sono le effettive differenze tra una libreria condivisa e una collegata staticamente? Perché non riesco solo a collegare staticamente tutto (RAM e spazio su disco sono poco costosi in questi giorni) e quindi evitare strani conflitti di versione della libreria?
  • Come posso sapere quali librerie ho installato e quali versioni?
  • Come posso installare più di una versione di una libreria senza rompere il mio normale sistema?
  • Se sto installando materiale dal sorgente su un sistema che altrimenti viene gestito usando i pacchetti, qual è il modo più pulito per farlo?
  • Supponendo che riesco a compilare qualcosa di complicato dalla fonte, come posso quindi impacchettarlo in modo che altre persone non debbano saltare attraverso gli stessi cerchi? Soprattutto su OS X ....
  • Quali sono gli strumenti da riga di comando che devo padroneggiare per diventare bravo in queste cose? Roba come otool, pkg-config ecc.

Sono disposto a investire un po 'di tempo e fatica qui - Non voglio necessariamente risposte dirette alle domande di cui sopra, preferirei di gran lunga ricevere consigli su libri / tutorial / FAQ che posso leggere che mi daranno il conoscenza che ho bisogno di capire cosa sta realmente succedendo e quindi capire i problemi da solo.

Risposte:


40

Mi scuso per aver risposto direttamente a tutto, ma non conosco tutorial utili, FAQ, ecc. Fondamentalmente ciò che segue sono 8 anni di creazione di app desktop (che aiuto a distribuire), frustrazione e googling:

1. Come posso capire a quali argomenti passare ./configure?

Pratica davvero. Gli autotools sono abbastanza facili in quanto coerenti. Ma ci sono molte cose là fuori che usano cmake o script di build personalizzati. Generalmente, non dovresti passare nulla da configurare, dovrebbe capire se il tuo sistema è in grado di creare foo-tool o no.

Gli strumenti di configurazione e GNU cercano tutte le dipendenze in /, / usr e / usr / local. Se installi altrove (il che rende le cose dolorose se la dipendenza è stata installata da MacPorts o Fink), dovrai passare un flag per configurare o modificare l'ambiente della shell per aiutare gli strumenti GNU a trovare queste dipendenze.

2. Come funzionano le librerie condivise su OS X / Linux: dove vivono nel filesystem, come ./configure && make le trova, cosa succede realmente quando sono collegate

Su Linux devono essere installati su un percorso che può trovare il linker dinamico, questo è definito dalla LD_LIBRARY_PATHvariabile d'ambiente e dal contenuto di /etc/ld.conf. Su Mac è quasi sempre lo stesso per la maggior parte dei software open source (a meno che non si tratti di un progetto Xcode). Tranne che la variabile env è DYLD_LIBRARY_PATHinvece.

Esiste un percorso predefinito in cui il linker cerca le librerie. È / lib: / usr / lib: / usr / local / lib

È possibile integrare ciò utilizzando la variabile CPATH, o CFLAGS o un numero qualsiasi di altre variabili d'ambiente davvero (convenientemente complicate). Suggerisco CFLAGS in questo modo:

export CFLAGS = "$ CFLAGS -L / nuovo / percorso"

Il parametro -L si aggiunge al percorso del collegamento.

Le cose moderne usano lo strumento pkg-config. Le cose moderne che installi installa anche un file .pc che descrive la libreria e dove si trova e come collegarla. Questo può rendere la vita più facile. Ma non viene fornito con OS X 10.5, quindi dovrai installarlo anche tu. Anche molti deps di base non lo supportano.

L'atto di collegamento è semplicemente "risolvere questa funzione in fase di esecuzione", in realtà è una grande tabella di stringhe.

3. Quali sono le effettive differenze tra una libreria condivisa e una collegata staticamente? Perché non riesco solo a collegare staticamente tutto (RAM e spazio su disco sono poco costosi in questi giorni) e quindi evitare strani conflitti di versione della libreria?

Quando si collega a un file di libreria statica, il codice diventa parte dell'applicazione. Sarebbe come se ci fosse un file .c gigante per quella libreria e lo compilassi nella tua applicazione.

Le librerie dinamiche hanno lo stesso codice, ma quando l'app viene eseguita, il codice viene caricato nell'app in fase di esecuzione (spiegazione semplificata).

Puoi collegarti staticamente a tutto, tuttavia, purtroppo quasi nessun sistema di compilazione lo rende facile. Dovresti modificare manualmente i file di sistema di compilazione (ad es. Makefile.am o CMakeLists.txt). Tuttavia, probabilmente vale la pena imparare se si installano regolarmente cose che richiedono versioni diverse delle librerie e se si riscontrano difficoltà nell'installare dipendenze in parallelo.

Il trucco è cambiare la linea di collegamento da -lfoo a -l / path / in / static / foo.a

Probabilmente puoi trovare e sostituire. Successivamente controlla che lo strumento non si colleghi a .so o dylib usando ldd foo o otool -L foo

Un altro problema non è che tutte le librerie vengono compilate in librerie statiche. Molti lo fanno. Ma poi MacPorts o Debian potrebbero aver deciso di non spedirlo.

4. Come posso sapere quali librerie ho installato e quali versioni?

Se hai file pkg-config per quelle librerie è facile:

pkg-config --list-all

Altrimenti spesso non puoi facilmente. Il dylib può avere un soname (es. Foo.0.1.dylib, il soname è 0.1) che è lo stesso della versione della libreria. Tuttavia questo non è richiesto. Il soname è una funzionalità di calcolabilità binaria, devi modificare la maggior parte del soname se cambi il formato delle funzioni nella libreria. Quindi puoi ottenere ad es. soname versione 14.0.5 per una libreria 2.0. Anche se questo non è comune.

Sono stato frustrato da questo genere di cose e ho sviluppato una soluzione per questo su Mac, e ne parlerò in seguito.

5. Come posso installare più di una versione di una libreria senza rompere il mio normale sistema?

La mia soluzione a questo è qui: http://github.com/mxcl/homebrew/

Mi piace installare dal sorgente e volevo uno strumento che lo rendesse facile, ma con una certa gestione dei pacchetti. Quindi con Homebrew costruisco, ad es. wget me stesso dalla fonte, ma assicurati di installare un prefisso speciale:

/usr/local/Cellar/wget/1.1.4

Quindi uso lo strumento homebrew per collegare tutto ciò in / usr / local, quindi ho ancora / usr / local / bin / wget e /usr/local/lib/libwget.dylib

In seguito, se ho bisogno di una versione diversa di wget, posso installarla in parallelo e cambiare semplicemente la versione che è collegata nell'albero / usr / local.

6. Se sto installando materiale dal sorgente su un sistema che altrimenti viene gestito usando i pacchetti, qual è il modo più pulito per farlo?

Credo che il modo Homebrew sia il più pulito, quindi usalo o fai l'equivalente. Installa in / usr / local / pkgs / name / version e symlink o hard link nel resto.

Usa / usr / local. Ogni strumento di compilazione esistente cerca lì dipendenze e intestazioni. La tua vita sarà molto più semplice.

7. Supponendo che riesco a compilare qualcosa di complicato dalla fonte, come posso quindi impacchettarlo in modo che altre persone non debbano saltare attraverso gli stessi cerchi? Soprattutto su OS X ....

Se non ha dipendenze puoi caricare la directory di build e consegnarla a qualcun altro che può fare "make install". Tuttavia, puoi farlo in modo affidabile solo per le stesse identiche versioni di OS X. Su Linux probabilmente funzionerà per Linux simile (es. Ubuntu) con la stessa versione del kernel e la versione minore di libc.

Il motivo per cui non è facile distribuire i binari su Unix è a causa della compatibilità binaria. Le persone GNU e tutti gli altri cambiano spesso le loro interfacce binarie.

Fondamentalmente non distribuire i binari. Le cose probabilmente si romperanno in modi molto strani.

Su Mac, l'opzione migliore è creare un pacchetto macports. Tutti usano i macport. Su Linux ci sono così tanti sistemi e combinazioni di build diversi, non penso che ci sia qualche consiglio migliore di quello di scrivere un post sul blog su come sei riuscito a costruire x tool in una strana configurazione.

Se fai una descrizione del pacchetto (per macports o homebrew) allora chiunque può installare quel pacchetto e risolve anche i problemi di dipendenza. Tuttavia, questo spesso non è facile e non è nemmeno facile includere la ricetta di Macport nella struttura principale di Macport. Inoltre macports non supporta tipi di installazione esotici, offre una scelta per tutti i pacchetti.

Uno dei miei obiettivi futuri con Homebrew è quello di rendere possibile fare clic su un collegamento su un sito Web (ad es. Homebrew: // blah e scaricherà lo script Ruby, installerà i deps per quel pacchetto e quindi costruirà l'app. Ma sì, non ancora fatto, ma non troppo complicato considerando il design che ho scelto.

8. Quali sono gli strumenti da riga di comando che devo padroneggiare per diventare bravo in queste cose? Roba come otool, pkg-config ecc.

otool è davvero utile solo in seguito. Ti dice a cosa si collega il binario incorporato. Quando stai scoprendo le dipendenze di uno strumento che devi costruire, è inutile. Lo stesso vale per pkg-config poiché avrai già installato la dipendenza prima di poterla usare.

La mia catena di strumenti è, leggi i file README e INSTALL, ed esegui una configurazione --help. Guarda l'output di build per verificare che sia sano. Analizza eventuali errori di compilazione. Forse in futuro, chiedi su serverfault :)


2
Interessante, Homebrew assomiglia molto a Portage (il gestore dei pacchetti di Gentoo Linux). Sembra un bel lavoro.
David Z,

12

Questo è un argomento enorme, quindi iniziamo con le librerie condivise su Linux (ELF su Linux e Mach-O su OS X), Ulrich Drepper ha una buona introduzione alla scrittura di DSO (oggetti condivisi dinamici) che copre un po 'di storia delle librerie condivise su Linux disponibili qui compreso perché sono importanti

Ulrich descrive anche perché il collegamento statico è considerato dannoso, uno dei punti chiave qui sono gli aggiornamenti di sicurezza. Gli overflow del buffer in una libreria comune (ad es. Zlib) ampiamente collegati staticamente possono causare un enorme sovraccarico per le distribuzioni - ciò si è verificato con zlib 1.1.3 ( avviso di Red Hat )

ELFO

La pagina di manuale di linker ld.so.

man ld.so 

spiega i percorsi e i file di base coinvolti nel collegamento dinamico di runtime. Sui moderni sistemi Linux vedrai percorsi aggiuntivi aggiunti tramite /etc/ld.so.conf.d/ aggiunti di solito tramite un glob incluso in /etc/ld.so.conf.

Se vuoi vedere ciò che è disponibile dinamicamente tramite la tua configurazione ld.so puoi eseguire

ldconfig -v -N -X

Leggere il DSO howto dovrebbe darti un buon livello di base di conoscenza per poter poi capire come questi principi si applicano a Mach-O su OS X.

Mach-O

Su OS X il formato binario è Mach-O. La documentazione di sistema locale per il linker è

man dyld

La documentazione sul formato Mach è disponibile da Apple

Strumenti di compilazione UNIX

Il comune configure, make, make installprocesso è generalmente fornito da GNU autotools che ha un servizio di prenotazione online che si occupa delle storia del configure / build spaccata e la toolchain GNU. Autoconf utilizza i test per determinare la disponibilità delle funzionalità sul sistema di generazione di destinazione, per guidare questo utilizza il linguaggio macro M4 . Automake è fondamentalmente un metodo di template per Makefile, il modello generalmente chiamato Makefile.am che genera un Makefile.in che l'output di autoconf (lo script di configurazione) converte in un Makefile.

Il programma ciao GNU costituisce un buon esempio per comprendere la toolchain GNU - e il manuale include la documentazione degli autotools.


10

Simon! So come ti senti; Ho lottato anche con questa parte dell'apprendimento di Linux. Sulla base delle mie esperienze personali, ho scritto un tutorial su alcuni degli elementi che risolvi (principalmente come riferimento per me stesso): http://easyaspy.blogspot.com/2008/12/buildinginstalling-application-from.html . Penso che apprezzerai la mia nota su quanto siano semplici da costruire / installare le applicazioni Python. :)

Spero che questo aiuti! E buona compilazione.

Tim Jones


Creazione / installazione di un'applicazione dalla sorgente in Ubuntu Linux

Mentre i repository Ubuntu sono pieni di fantastiche applicazioni, una volta o l'altra ti imbatterai in quello strumento "indispensabile" che non è nei repository (o non ha un pacchetto Debian) o hai bisogno di un versione più recente rispetto ai repository. cosa fai? Bene, devi creare l'applicazione dal sorgente! Non preoccuparti, non è così complicato come sembra. Ecco alcuni suggerimenti, basati sulla mia esperienza di passare dall'essere un dilettante di rango! (Mentre sto usando Ubuntu per questo esempio, i concetti generali dovrebbero essere applicabili alla maggior parte di qualsiasi distribuzione Unix / Linux, come Fedora, e persino alla piattaforma Cygwin su Windows.)

Il processo di base per creare (compilare) la maggior parte delle applicazioni dall'origine segue questa sequenza: configura -> compila -> installa. I tipici comandi Unix / Linux per fare queste cose sono: config-> make-> make install. In alcuni casi, troverai persino pagine Web che mostrano che tutte queste possono essere combinate in un singolo comando:

$ config && make && make install

Naturalmente, questo comando presuppone che non ci siano problemi in nessuno di questi passaggi. È qui che entra in gioco il divertimento!

Iniziare

Se non hai mai compilato un'applicazione dal sorgente sul tuo sistema in precedenza, probabilmente dovrai configurarla con alcuni strumenti di sviluppo generali, come la gccsuite di compilatori, alcuni file di intestazione comuni (pensa a questo come codice che è già stato scritto da qualcun altro utilizzato dal programma che si sta installando) e lo strumento di creazione. Fortunatamente, in Ubuntu, c'è un metapacchetto chiamato build-essentialche installerà questo. Per installarlo (o semplicemente assicurarti di averlo già!), Esegui questo comando nel terminale:

$ sudo apt-get install build-essential

Ora che hai la configurazione di base, scarica i file sorgente dell'applicazione e salvali in una directory per la quale hai i permessi di lettura / scrittura, come la tua directory "home". In genere, questi saranno in un file di archivio con estensione di .tar.gzo .tar.bz2. La .tarsignifica semplicemente che si tratta di un "archivio a nastro", che è un raggruppamento di file che conserva la struttura di directory relativa. È l' .gzacronimo di gzip (GNU zip), che è un popolare formato di compressione Unix / Linux. Allo stesso modo, .bz2sta per bzip2, che è un formato di compressione più recente che fornisce una compressione più elevata (dimensione del file compresso più piccola) rispetto a gzip.

Dopo aver scaricato il file sorgente, apri una finestra del terminale (Terminale di sistema dal menu Ubuntu) e passa alla directory in cui hai salvato il file. (In ~/downloadquesto esempio userò . Qui, '~' è un collegamento alla directory "home".) Utilizzare il comando tar per estrarre i file dal file di archivio scaricato:

Se il tuo file è un archivio gzip (ad esempio, termina con .tar.gz), usa il comando:

            $ tar -zxvf filename.tar.gz

Se il tuo file è un archivio bzip2 (ad esempio, termina con .tar.bz2), usa il comando:

            $ tar -jxvf filename.tar.gz

Suggerimento: se non si desidera ricordare tutte le opzioni della riga di comando per l'estrazione degli archivi, si consiglia di ottenere una (o entrambe) queste utilità: dtrx (il mio preferito!) O deco (più popolare). Con una di queste utility, basta inserire il nome dell'utility (dtrx o deco) e il nome del file, e fa tutto il resto. Entrambi "sanno" come gestire la maggior parte dei formati di archivio che è probabile che si verifichino e hanno un'ottima gestione degli errori.

Quando si genera dalla fonte, ci sono due tipi comuni di errori che è probabile che si verifichino:

  1. Si verificano errori di configurazione quando si esegue lo script di configurazione (in genere denominato config o configure) per creare un makefile specifico per la propria installazione.
  2. Gli errori del compilatore si verificano quando si esegue il comando make (dopo che il makefile è stato generato) e il compilatore non è in grado di trovare il codice necessario.

Esamineremo ciascuno di questi e discuteremo come risolverli.

Errori di configurazione e configurazione

Dopo aver estratto il file di archivio del codice sorgente, nel terminale, è necessario passare alla directory che contiene i file estratti. In genere, questo nome di directory sarà uguale al nome del file (senza l' estensione .tar.gzo .tar.bz2). Tuttavia, a volte il nome della directory è solo il nome dell'applicazione, senza alcuna informazione sulla versione.

Nella directory di origine cercare un READMEfile e / o un INSTALLfile (o qualcosa con nomi simili). Questi file in genere contengono informazioni utili su come compilare / compilare l'applicazione e installarla, comprese le informazioni sulle dipendenze. "Dipendenze" sono solo un nome di fantasia per altri componenti o librerie che sono necessari per compilare correttamente.

Dopo aver letto il file READMEe / o INSTALL(e, si spera, abbia consultato la documentazione online pertinente per l'applicazione), cercare un file eseguibile (con il permesso "x" impostato sul file) chiamato configo configure. A volte il file potrebbe avere un'estensione, come .sh(ad esempio, config.sh). Questo di solito è uno script di shell che esegue alcune altre utilità per confermare che si dispone di un ambiente "sano" per la compilazione. In altre parole, verificherà che sia installato tutto ciò di cui hai bisogno.

Suggerimento: se si tratta di un'applicazione basata su Python, anziché un file di configurazione, è necessario trovare un file denominato setup.py. Le applicazioni Python sono in genere molto semplici da installare. Per installare questa applicazione, come root (ad esempio, metti sudo davanti al seguente comando sotto Ubuntu), esegui questo comando:

    $ python setup.py install

Dovrebbe essere tutto ciò che devi fare. Puoi saltare il resto di questo tutorial e procedere direttamente all'utilizzo e alla fruizione della tua applicazione.

Esegui lo script di configurazione nel terminale. In genere, puoi (e dovresti!) Eseguire lo script di configurazione con il tuo account utente normale.

$ ./config

Lo script mostrerà alcuni messaggi per darti un'idea di ciò che sta facendo. Spesso, lo script ti darà un'indicazione se ha avuto esito positivo o negativo e, in caso contrario, alcune informazioni sulla causa dell'errore. Se non ricevi alcun messaggio di errore, di solito puoi presumere che tutto sia andato bene.

Se non trovi uno script che assomigli a uno script di configurazione, significa in genere che l'applicazione è molto semplice ed è indipendente dalla piattaforma. Ciò significa che puoi semplicemente saltare al passaggio di compilazione / compilazione di seguito, poiché il prodotto fornito Makefiledovrebbe funzionare su qualsiasi sistema.

Un esempio

In questo tutorial, userò il lettore RSS basato su testo chiamato Newsbeuter come esempio per i tipi di errori che potresti riscontrare durante la creazione della tua applicazione. Per Newsbeuter, il nome dello script di configurazione è config.sh. Sul mio sistema, quando eseguo config.sh, si verificano i seguenti errori:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ ./config.sh
Checking for package sqlite3... not found

You need package sqlite3 in order to compile this program.
Please make sure it is installed.

Dopo aver fatto qualche ricerca, ho scoperto che, in effetti, l' sqlite3applicazione è stata installata. Tuttavia, dal momento che sto provando a costruire dal sorgente, questo è un suggerimento che ciò che config.shrealmente sta cercando sono le librerie di sviluppo (intestazioni) per sqlite3. In Ubuntu, la maggior parte dei pacchetti ha un pacchetto di controparte di sviluppo associato che termina in -dev. (Altre piattaforme, come Fedora, usano spesso un suffisso -develper i pacchetti di sviluppo.)

Per trovare il pacchetto appropriato per il sqlite3pacchetto di sviluppo, possiamo usare l' apt-cacheutilità in Ubuntu (e, analogamente, l' yumutilità in Fedora):

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-cache search sqlite

Questo comando restituisce un elenco piuttosto ampio di risultati, quindi dobbiamo fare un po 'di lavoro investigativo per determinare quale sia il pacchetto appropriato. In questo caso, il pacchetto appropriato risulta essere libsqlite3-dev. Si noti che a volte il pacchetto che stiamo cercando avrà il libprefisso, anziché solo lo stesso nome del pacchetto più -dev. Questo perché a volte stiamo solo cercando una libreria condivisa che possa essere utilizzata da molte applicazioni diverse. Per installare libsqlite3-dev, esegui il tipico comando apt-get install nel terminale:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ sudo apt-get install libsqlite3-dev

Ora, dobbiamo eseguire di config.shnuovo per assicurarci di aver risolto questo problema di dipendenza e che non abbiamo più problemi di dipendenza. (Anche se non lo mostrerò qui, nel caso di Newsbeuter, ho anche dovuto installare il libcurl4-openssl-devpacchetto.) Inoltre, se si installa un pacchetto di sviluppo (come libsqlite3-dev) e il pacchetto dell'applicazione associato (ad es. sqlite3) Non lo è già installato, la maggior parte dei sistemi installerà automaticamente il pacchetto dell'applicazione associato contemporaneamente.

Quando la configurazione viene eseguita correttamente, il risultato sarà che creerà uno o più file make. Questi file sono generalmente denominati Makefile(ricorda che il caso del nome file è importante in Unix / Linux!). Se il pacchetto build include sottodirectory, come src, ecc., Ognuna di queste sottodirectory conterrà anche una Makefile.

Errori di costruzione e compilazione

Ora siamo pronti per compilare effettivamente l'applicazione. Questo è spesso chiamato costruzione e il nome è preso in prestito dal processo del mondo reale di costruire qualcosa. I vari "pezzi" dell'applicazione, che sono in genere più file di codice sorgente, sono combinati insieme per formare l'applicazione complessiva. L'utility make gestisce il processo di compilazione e chiama altre applicazioni, come il compilatore e il linker, per svolgere effettivamente il lavoro. Nella maggior parte dei casi, si esegue semplicemente make (con il proprio account utente normale) dalla directory in cui è stata eseguita la configurazione. (In alcuni casi, come la compilazione di applicazioni scritte con la libreria Qt, sarà invece necessario eseguire un'altra applicazione "wrapper" come qmake. Ancora una volta, controllare sempre READMEe / o i INSTALLdocumenti per i dettagli.)

Come con lo script di configurazione sopra, quando si esegue make (o un'utilità simile) nel terminale, verranno visualizzati alcuni messaggi su ciò che è in esecuzione e eventuali avvisi ed errori. In genere puoi ignorare gli avvisi, in quanto sono principalmente per gli sviluppatori dell'applicazione e stanno dicendo loro che ci sono alcune pratiche standard che vengono violate. Di solito, questi avvisi non influiscono sulla funzione dell'applicazione. D'altra parte, gli errori del compilatore devono essere gestiti. Con Newsbeuter, quando ho eseguito make, le cose sono andate bene per un po ', ma poi ho avuto un errore:

tester@sitlabcpu22:~/download/newsbeuter-1.3$ make
...
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/configparser.o -c src/configparser.cpp
c++ -ggdb -I/sw/include -I./include -I./stfl -I./filter -I. -I./xmlrss -Wall -Wextra -DLOCALEDIR=\"/usr/local/share/locale\" -o src/colormanager.o -c src/colormanager.cpp
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:5:18: error: stfl.h: No such file or directory
In file included from ./include/pb_view.h:5,
from src/colormanager.cpp:4:
./include/stflpp.h:33: error: ISO C++ forbids declaration of \u2018stfl_form\u2019 with no type
./include/stflpp.h:33: error: expected \u2018;\u2019 before \u2018*\u2019 token
./include/stflpp.h:34: error: ISO C++ forbids declaration of \u2018stfl_ipool\u2019 with no type
./include/stflpp.h:34: error: expected \u2018;\u2019 before \u2018*\u2019 token
make: *** [src/colormanager.o] Error 1

Il processo di creazione si interromperà non appena si verifica il primo errore. Gestire gli errori del compilatore a volte può essere un affare complicato. Devi guardare gli errori per alcuni indizi sul problema. In genere, il problema è che mancano alcuni file di intestazione, che di solito hanno l'estensione di .ho .hpp. Nel caso dell'errore sopra riportato, è (o dovrebbe essere!) Chiaro che il problema è che stfl.hnon è possibile trovare il file di intestazione. Come mostra questo esempio, si desidera esaminare le prime righe del messaggio di errore e procedere fino in fondo per trovare la causa sottostante del problema.

Dopo aver esaminato la documentazione di Newsbeuter (cosa che avrei dovuto fare prima di iniziare, ma questa parte del tutorial non sarebbe stata molto significativa!), Ho scoperto che richiede una libreria di terze parti chiamata STFL. Quindi cosa facciamo in questo caso? Bene, essenzialmente ripetiamo questo stesso identico processo per quella libreria richiesta: ottenere la libreria ed eseguire il processo configure-build-install per esso e, quindi, riprendere a costruire l'applicazione desiderata. Ad esempio, nel caso di STFL, ho dovuto installare il libncursesw5-devpacchetto per farlo compilare correttamente. (Di solito, non è necessario ripetere il passaggio di configurazione sulla nostra applicazione originale dopo aver installato un'altra applicazione richiesta, ma non fa neanche male.)

Dopo aver installato correttamente il toolkit STFL, il processo di creazione di Newsbeuter è stato eseguito correttamente. Il processo di creazione in genere riprende da dove si interrompe (nel punto dell'errore). Pertanto, tutti i file già compilati correttamente non verranno ricompilati. Se si desidera ricompilare tutto, è possibile eseguire make clean all per rimuovere eventuali oggetti compilati e quindi eseguire nuovamente make.

Installazione

Al termine del processo di compilazione, si è pronti per installare l'applicazione. Nella maggior parte dei casi, per installare l'applicazione nelle aree comuni del file system (ad es., /usr/binO /usr/share/bin, ecc.), È necessario eseguire l'installazione come root. L'installazione è davvero il passaggio più semplice dell'intero processo. Per installare, nel terminale eseguire:

$ make install

Controlla l'output di questo processo per eventuali errori. Se tutto ha avuto successo, dovresti essere in grado di eseguire il nome del comando nel terminale e verrà avviato. (Aggiungi e alla fine della riga di comando, se si tratta di un'applicazione GUI, o non sarai in grado di utilizzare la sessione del terminale fino a quando l'applicazione non termina l'esecuzione.)

Quando si crea un'applicazione dall'origine, in genere non viene aggiunta un'icona o un collegamento ai menu della GUI in Ubuntu. Dovrai aggiungerlo manualmente.

E questo è fondamentalmente il processo, sebbene potenzialmente iterativo, per la costruzione e l'installazione di un'applicazione dal sorgente in Ubuntu. Dopo averlo fatto solo poche volte, diventerà una seconda natura per te!


Tim, mi sarebbe piaciuto leggere il tuo tutorial, ma il link che hai pubblicato non funziona.
gareth_bowles,

6

Bene, ./configure --help ti darà molte informazioni, per i file di configurazione generati dagli autotools GNU. La maggior parte di questi si riduce a - con / - senza abilitare le funzionalità (questi potrebbero richiedere un parametro aggiuntivo, come "condiviso" per dire dove trovare la libreria).

Altri importanti sono --prefix (che per impostazione predefinita è / usr / local / la maggior parte del tempo) per dire dove installare (se stai costruendo pacchetti di solito lo vuoi come --prefix = / usr o forse --prefix = / opt / YourPackage).

Su Linux, / lib, / usr / lib e / usr / local / lib sono generalmente cercati nel mio gcc e inclusi nella configurazione predefinita di ldconfig. A meno che tu non abbia una buona ragione, questo è dove vuoi le tue biblioteche. /etc/ld.so.conf può tuttavia elencare voci extra.

configurare e farli trovare semplicemente tentando di eseguire "gcc -l" e vedere se si tratta di errori. È possibile aggiungere "-L" al parametro CFLAGS per aggiungere percorsi aggiuntivi alla ricerca.

Puoi avere più versioni installate e il software collegato a una versione precedente rimarrà collegato contro di essa (esegui ldd per scoprire l'associazione su Linux), ma le nuove compilazioni generalmente mirano all'ultima versione di una libreria dinamica sul tuo sistema.

La maggior parte dei software presuppone librerie dinamiche, soprattutto se utilizza libtool, quindi potresti scoprire che app non banali non vengono compilate correttamente staticamente.

ls -l è la soluzione migliore per trovare le librerie installate.

Ed è lì che sono fuori informazione; come giocare bene con i pacchetti: non lo so. Quando possibile, provo a racchiudere le cose in un pacchetto per evitare il problema.


4

"Come faccio a capire a quali argomenti passare ./configure?"

di solito: ./configure --help ti dirà cosa vuoi lì.

"Come posso sapere quali librerie ho installato e quali versioni?"

Dipende dal sistema. Un modo è semplicemente fare un find /|grep libname|lessfile, poiché generalmente i file di libreria hanno la versione nel nome del file.

"Come posso installare più di una versione di una libreria senza rompere il mio normale sistema?"

Ancora una volta, dipende dal sistema e dalla libreria. sudo make altinstallcreerà un nome con versione per te. Tuttavia, i file di libreria in genere si autodefiniscono. Tieni presente tuttavia; poiché le versioni spesso creano collegamenti simbolici a un nome "normalizzato", ciò può spezzare le cose.

"Se installo roba dal sorgente su un sistema che altrimenti viene gestito usando i pacchetti, qual è il modo più pulito di farlo?"

Usare i parametri --prefix in ./configure e metterli da qualche parte in /optè una buona pratica da seguire.

Disclaimer: non sono affatto un esperto, ma sto usando Linux per oltre 5 anni dalla linea cmd (slackware, CentOS, redhat, ubuntu, misc altri e OS X).


4

Per rispondere un po 'alla tua domanda, l'altro giorno ho trovato un buon modo per vedere quali librerie hai installato e le versioni (Questo è su Debian Linux, quindi dovrebbe funzionare anche con altre versioni).

dpkg --list

Dovresti ottenere un elenco molto lungo con alcuni output come questo

ii  libssl0.9.8    0.9.8c-4etch5  SSL shared libraries
ii  libssp0        4.1.1-21       GCC stack smashing protection library
ii  libstdc++5     3.3.6-15       The GNU Standard C++ Library v3
ii  libstdc++5-3.3 3.3.6-15       The GNU Standard C++ Library v3 (development
ii  libstdc++6     4.1.1-21       The GNU Standard C++ Library v3

4

Simon,

1.) ./configure --help fornisce una buona quantità di informazioni. Suggerisco di provarlo. In genere ha opzioni per la compilazione di librerie statiche / collegate dinamicamente quando appropriato.

2.) Le libarie vivono nel percorso del linker dinamico. Questo è di solito impostato in /etc/ld.so.conf. Il linker cerca le librerie appropriate proprio come la variabile d'ambiente PATH corrispondente alla prima trovata.

3.) Ciò generalmente causa problemi in quanto è necessario ricompilare tutto quando cambia una versione della libreria. Se fai qualche ricerca, troverai probabilmente una gran quantità di motivi per cui il collegamento statico è una cattiva idea. Non lo faccio da così tanto tempo che non riesco davvero a elaborare qui.

4.) Questo è un po 'difficile. Per essere assolutamente sicuro, è necessario controllare il percorso della libreria. Le librerie in genere dispongono di un collegamento simbolico alla versione installata.

ad esempio libssh2.so.1 -> libssh2.so.1.0.0

Generalmente le persone gestiscono le librerie e i programmi che installano arrotolando i propri pacchetti debian o usando qualche altra tecnica. Gestisco il software installato usando stow ( http://www.gnu.org/software/stow/ ) che è molto semplice e installa la libreria usando collegamenti simbolici. Lo trovo più semplice poiché non devo creare / installare / testare un pacchetto deb / rpm.

5.) Più versioni delle librerie possono essere installate normalmente nelle directory delle librerie. Le librerie collegate agli eseguibili rimarranno collegate alle versioni a cui erano collegate. eseguire ldd su un eseguibile ti dirà a quali librerie è collegato l'eseguibile.

6.) Come ho già detto in precedenza, girare i propri pacchetti debian o usare stow è probabilmente la soluzione più pulita.

7.) Non posso davvero parlare per Mac OSX ma per Linux il sistema di packaging della distribuzione è il modo migliore.

8.) Probabilmente molta frustrazione verrà risolta usando ldd e scoprendo quale versione è collegata a qualcosa o quale libreria collegata a un eseguibile non può essere trovata. pkg-config ti aiuterà molto, ma solo per i software che lo utilizzano. Non fa parte del sistema di compilazione predefinito degli autotools sebbene sia popolare in questi giorni.


4

Le librerie statiche non sono una buona idea: se devi aggiornare la libreria (per risolvere un problema di sicurezza, ad esempio), dovrai ricompilare tutto con una dipendenza da quella libreria.

Non mi piace l'idea di "make install" che possa potenzialmente rovinare il mio sistema, ma come altri hanno già detto, di solito è molto meno doloroso installare cose in / usr / local invece di usare --prefix per installarle altrove. Quindi, ho riconosciuto / usr / local al mio utente normale (non privilegiato). In questo modo "make install" è praticamente garantito per non pasticciare con file di sistema importanti. (Questo ovviamente non funzionerà su sistemi multiutente. Tuttavia, è ottimo per i server virtuali.)


4

Anche se non era esplicitamente nell'elenco delle domande, menzionate nella prefazione:

./configure && make && sudo make install di solito è abbastanza, ma a volte non funziona - e quando non funziona, mi blocco spesso.

Quando rimango bloccato su Debian o Ubuntu userò auto-apt che installerà automagicamente i pacchetti che contengono i file che la configurazione non riesce a trovare.

Vedere:

Un altro strumento che potresti trovare utile è CheckInstall, che aggiunge le applicazioni installate make installal tuo elenco di pacchetti installati: https://help.ubuntu.com/community/CheckInstall


3

Per OS X:

  • Come faccio a capire a quali argomenti passare ./configure?

./configure --help

  • Quali sono le effettive differenze tra una libreria condivisa e una collegata staticamente? Perché non riesco solo a collegare staticamente tutto (RAM e spazio su disco sono poco costosi in questi giorni) e quindi evitare strani conflitti di versione della libreria?

L'uso delle librerie condivise consente di aggiornare la libreria senza ricompilare tutto ciò che la utilizza.

  • Come funzionano le librerie condivise su OS X / Linux: dove vivono nel filesystem, come ./configure && make le trova, cosa succede realmente quando sono collegate

Le librerie di sistema vivono in / usr / lib.

Librerie compilate live in / usr / local / lib (/ usr / local è il flag --prefix predefinito per ./configure).

Le variabili di ambiente DYLD_FALLBACK_LIBRARY_PATH e LD_LIBRARY_PATH ti consentono di specificare in quali cartelle cercare, quindi / usr / local / lib dovrebbe essere presente all'inizio dell'elenco.

  • Come posso installare più di una versione di una libreria senza rompere il mio normale sistema?

Installa tutto su / usr / local - con le variabili di ambiente sopra, la versione in / usr / local / lib ha la precedenza sulla versione in / usr / lib nel tuo ambiente.

  • Se sto installando materiale dal sorgente su un sistema che altrimenti viene gestito usando i pacchetti, qual è il modo più pulito per farlo?

Installa in / usr / local. In Ubuntu, provo prima a utilizzare checkinstall, per creare un pacchetto deb.

  • Supponendo che riesco a compilare qualcosa di complicato dalla fonte, come posso quindi impacchettarlo in modo che altre persone non debbano saltare attraverso gli stessi cerchi? Soprattutto su OS X ....

Documenta i passaggi della compilazione in un post sul blog, direi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.