Introduzione alla compilazione dei programmi sotto linux

Mer, 03/10/2007 - 23:51

Introduzione alla compilazione dei programmi sotto linux

Inviato da orion 3 commenti

Breve guida alla configurazione di SUSE per la compilazione di driver/programmi e risoluzione dei problemi più comuni in compilazione.

Introduzione alla compilazione dei programmi sotto linux

Questa guida vuole essere un breve vademecum sulla configurazione di SUSE (e di linux in generale) per poter installare un programma o un driver a partire dal codice sorgente.

Per gli esempi di questa guida ci si basa sui pacchetti di openSUSE 10.2 e si usa YaST come gestore degli rpm. Per entrambi si usa la versione in inglese.
Se si usa la localizzazione italiana oppure si usano altri gestori di rpm o altra versione di openSUSE, adattare le indicazioni alla propria configurazione del sistema.

Questa guida presuppone una conoscenza basilare dei comandi bash, come ad esempio cambiare directory con cd e assumere i permessi di root con su
Installazione del compilatore

La prima, fondamentale, operazione che bisogna compiere quando si vuole compilare un programma (sia esso un driver o un applicativo) è quella di installare un compilatore.

Per fare questo, lanciamo YaST e selezioniamo Software Management.

Prima di installare il compilatore, assicurarsi che tra le sorgenti di YaST sia presente il dvd di SUSE o, in alternativa, il repository oss della propria versione di SUSE.

Nella finestra che compare, impostiamo come Filter: il filtro Search e cerchiamo gcc.
Tra tutti gli rpm che vengono proposti, selezioniamo da installare i seguenti pacchetti:

cpp41
gcc
gcc41
gcc41-g++
gcc-g++
libgcc41

Una volta selezionati i vari pacchetti indicati e spuntati per l'installazione, clicchiamo su Accept e accettiamo i pacchetti indicati come necessari da installare per soddisfare le dipendenze.

Al termine dell'installazione del compilatore gcc, per verificare che l'installazione sia avvenuta correttamente, è sufficiente aprire un terminale e lanciare il seguente comando:

$ gcc -v

Se l'installazione è avvenuta correttamente, dovremmo ottenere il seguente output: Using built-in specs.
Target: i586-suse-linux
Configured with: ../configure --enable-threads=posix --prefix=/usr --with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/share/man --libdir=/usr/lib --libexecdir=/usr/lib --enable-languages=c,c++,objc,fortran,obj-c++,java,ada --enable-checking=release --with-gxx-include-dir=/usr/include/c++/4.1.2 --enable-ssp --disable-libssp --disable-libgcj --with-slibdir=/lib --with-system-zlib --enable-shared --enable-__cxa_atexit --enable-libstdcxx-allocator=new --program-suffix=-4.1 --enable-version-specific-runtime-libs --without-system-libunwind --with-cpu=generic --host=i586-suse-linux
Thread model: posix
gcc version 4.1.2 20061115 (prerelease) (SUSE Linux)

Se non si ottiene un output simile o, peggio, un messaggio bash: gcc: command not found bisogna assicurarsi di aver installato correttamente i pacchetti indicati ed eventualmente provare a reinstallarli. Se ancora non si riesce a usare gcc, conviene chiedere sul forum.

Per essere sicuri che gcc funzioni, si può usare il comando
$ echo -e "#include nmain(){printf("gcc funziona\\n");}n"|gcc -x c -o /tmp/prova -;/tmp/prova

Se gcc funziona correttamente, dovremmo avere come output sul terminale gcc funziona

Prima di procedere alla compilazione di un programma, abbiamo bisogno di altri tool di supporto che vengono usati per la gestione della compilazione. Per la loro installazione, torniamo al Software Management di YaST e cerchiamo make.
Tra i pacchetti proposti, selezioniamo ed installiamo

autoconf
automake
make
Pacchetti per l'installazione di un driver

Dopo aver installato il compilatore gcc, potremmo aver bisogno di installare un driver, di cui abbiamo scaricato l'installer.

Dato che l'installazione di un driver è un'operazione che riguarda il kernel di SUSE, la compilazione del driver richiede che siano installati i file necessari per interfacciarsi al kernel. Tali file sono detti kernel headers.

Per installare i kernel headers, torniamo al Software Management di YaST e cerchiamo kernel. Tra i pacchetti proposti, selezionamo e spuntiamo come da installare il pacchetto linux-kernel-headers.
Dopo averlo selezionato, procediamo alla sua installazione.

Le ultime versioni di driver richiedono solamente di installare i kernel headers. Alcune versioni più vecchie di driver richiedono l'installazione dell'intero sorgente del kernel per poter essere compilate. Per installare il sorgente del kernel, è sufficiente selezionare il pacchetto kernel-source oltre a linux-kernel-headers.
Anche se non è più richiesto, personalmente preferisco installare sia gli header che il sorgente del kernel, così evito qualsiasi problema legato al kernel il fase di compilazione del driver.

Se il driver che vogliamo installare è distribuito per mezzo di un installer, ora possiamo procedere alla sua installazione seguendo le istruzioni relative all'uso dell'installer o a una delle guide che si possono trovare in rete a riguardo.

Se, invece, il driver è fornito come codice sorgente, lo compiliamo allo stesso modo di un programma qualsiasi.

Compilazione di un programma a partire dai file sorgente

Come programma di riferimento, utilizziamo KNemo, scaricabile da http://www.kde-apps.org
Anche in questo caso, adattare i nomi dei file e delle directory in base a quelli con cui si ha effettivamente a che fare.

Abbiamo scaricato i sorgenti di un programma e ora vogliamo installarlo e usarlo.

La prima cosa da fare è scompattare il file che abbiamo scaricato tramite il comando

$ tar xfj 12956-knemo-0.4.8.tar.bz2

Se il file è un tar.gz, si usa xfz al posto di xfj

e poi entriamo nella directory knemo-0.4.8

Dopo essere entrati nella directory knemo-0.4.8, la sequenza standard di comandi da eseguire da terminale per la compilazione e l'installazione di un programma è

$ ./configure
$ make
$ su
# make install

Quando si esegue su sul terminale compare Password: A questo punto digitiamo la password di root e diamo invio, anche se non c'è alcuna risposta del terminale mentre immettiamo la password. Se la password di root è corretta, vedremo il prompt terminare con #
All'interno della directory dei sorgenti di un programma solitamente troviamo due file che forniscono tutte le informazioni necessarie per la corretta compilazione ed installazione del programma stesso: README e INSTALL.
Questi file sono presenti in tutti i sorgenti dei programmi a parte in alcuni, rari, casi.
Conviene sempre guardare questi due file, per essere sicuri di come procedere.

Se siamo fortunati, tutto procede senza intoppi e, dopo aver eseguito il comando make install, possiamo usare il nostro programma senza problemi.

Di solito, però, c'è sempre qualche intoppo che non ci permette di completare l'installazione del programma in modo semplice. Vediamo ora come risolvere alcuni dei problemi classici che si presentano durante la compilazione di un programma a partire dai sorgenti.

Problemi durante l'esecuzione di configure

La maggior parte degli problemi che sorgono durante la compilazione di un programma avviene durante l'esecuzione dello script configure presente nella directory dei sorgenti che vogliamo compilare.
configure è un'utility che raccoglie informazioni sullo stato del sistema (che programmi sono installati, che librerie sono disponibili, ...) in modo da ottimizzare la compilazione del sorgente e avere la certezza che tutte le dipendenze siano soddisfatte prima di procedere alla compilazione effettiva del programma.

Questa verifica preliminare è di fondamentale importanza, dato che non è raro che la compilazione di un programma richieda ore, se non giorni, per essere completata. Pensiamo ad esempio all'intero Kde o all'intero OpenOffice.org

Se configure si accorge che una dipendenza fondamentale non può soddisfatta, questa viene segnalata all'utente che deve provvedere a risolverla.

Vediamo ora una terminazione corretta di configure (sono riportate le prime due righe dell'output e le ultime): checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
...
config.status: creating config.h
config.status: executing depfiles commands

Good - your configure finished. Start make now
Siamo sicuri che configure ha terminato correttamente in quanto ha creato i file necessari per il prossimo passo di compilazione e ci indica di procedere con il make.

Non tutti i configure sono impostati in modo da essere così espliciti; a volte la terminazione corretta è rappresentata dalle semplici righe di output configure: creating ./config.status
config.status: creating Makefile
config.status: creating src/Makefile
config.status: creating config.h
config.status: executing depfiles commands

Vediamo ora un caso di terminazione non corretta di configure, a seguito di una dipendenza fondamentale non soddisfatta (di nuovo, una parte dell'output è stata eliminata): checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
...
checking for uic... /usr/lib/qt3/bin/uic
checking whether uic supports -L ... yes
checking whether uic supports -nounload ... yes
checking if Qt needs -ljpeg... no
checking for rpath... yes
checking for KDE... configure: error:
in the prefix, you've chosen, are no KDE headers installed. This will fail.
So, check this please and use another prefix!

Come si vede, configure cerca gli headers di Kde per poter compilare correttamente KNemo ma non è in grado di trovarli, almeno nella loro posizione standard.

Questo accade in quanto non sono stati installati nel sistema, quindi dobbiamo procedere alla loro installazione.

Come prima cosa, torniamo al Software Management di YaST, cerchiamo kde e concentriamo la nostra attenzione sui pacchetti -devel che sono quelli che contengono i file necessari per la compilazione.
Il pacchetto che interessa in questo caso è kdebase3-devel; lo selezioniamo e procediamo con la sua installazione, accettando anche i pacchetti necessari per la risoluzione delle dipendenze.

Capire che pacchetto contiene il file necessario è questione di esperienza.
Di norma, il pacchetto ha un nome simile alla dipendenza richiesta da configure e il nome termina con -devel

Dopo aver installato kdebase3-devel, ritorniamo al terminale e lanciamo di nuovo configure.

Come possiamo vedere, abbiamo scelto il pacchetto giusto, dato che il controllo è andato a buon fine: checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
...
checking for uic... /usr/lib/qt3/bin/uic
checking whether uic supports -L ... yes
checking whether uic supports -nounload ... yes
checking if Qt needs -ljpeg... no
checking for rpath... yes
checking for KDE... libraries /opt/kde3/lib, headers /opt/kde3/include
checking if UIC has KDE plugins available... yes
checking for KDE paths... defaults
...

Iteriamo questo procedimento fino a quando configure non termina con successo: ...
config.status: creating config.h
config.status: executing depfiles commands

Good - your configure finished. Start make now
A questo punto possiamo passare ad eseguire il comando make che, di norma, termina sempre in modo corretto. Nel caso dovesse terminare con un errore, la risoluzione dello stesso non è compito nostro ma dello sviluppatore del programma che vogliamo compilare, in quanto un errore durante il make vuol dire che c'è un errore nel codice sorgente del programma o negli script di compilazione.

Dopo aver terminato make correttamente, completiamo l'installazione assumendo i permessi di root ed eseguendo make install con i comand

$ su
Password:
# make install

Dopo aver dato make install, possiamo usare il programma appena compilato.





Commenti

Ritratto di orion
#1

Inviato da orion il Sab, 06/10/2007 - 09:14.

Correzione sul test del funzionamento del gcc

Il comando corretto per la verifica che il compilatore gcc funziona correttamente e` il seguente: echo -e "#include <stdio.h>\n main(){printf(\"gcc funziona\\\\n\");}"|gcc -x c -o /tmp/prova -; /tmp/prova
A quanto pare, <stdio.h> e` stato preso come un tag html invece che come testo normale.

Typo: i pacchetti sono gcc-c++ e gcc41-c++ e non gcc-g++ e gcc41-g++.

edit: cambiato programma di test.

openSUSE 12.1 on Acer Aspire 1810tz - LXDE ultima versione dal repo x11:/lxde



Ritratto di Roberto65
#2

Inviato da Roberto65 il Dom, 14/10/2007 - 18:30.

Re: Correzione sul test del funzionamento del gcc

Ciao
E' possibile generare un pacchetto .rpm per poi installarlo dopo.
Per questo bisogna utilizzare delle utility come: CHECKINSTALL, RPMPM, KRPMBUILDER oppure se in maniera piu' elaboriosa, si può usare il famoso comando: RPMBUILD o RPM -ba, ma bisogna creare e capire gli specfile prima.
Ciao



Ritratto di orion
#3

Inviato da orion il Lun, 15/10/2007 - 13:34.

Re: Correzione sul test del funzionamento del gcc

Vero, ma mi sembra sia un passo successivo rispetto alla semplice compilazione/installazione di un driver/programma a partire dai sorgenti.

openSUSE 12.1 on Acer Aspire 1810tz - LXDE ultima versione dal repo x11:/lxde