Visualizzazione post con etichetta gcc. Mostra tutti i post
Visualizzazione post con etichetta gcc. Mostra tutti i post

mercoledì 6 ottobre 2010

GCC: compilare codice a 32bit su sistemi a 64bit

Per riuscire a compilare correttamente codice a 32bit su sistemi a 64bit è necessario che siano disponibili sul sistema anche le versioni a 32bit delle librerie richieste.
Tale versione delle librerie (32bit) non vengono, di solito, installate di default sui sistemi a 64bit.

Per esperienza personale, quando si hanno problemi di compilazione, dovuti alla generazione di applicazioni 32bit su macchine a 64bit, nella maggior parte dei casi si può risolvere il problema installando i seguenti pacchetti su sistemi Ubuntu (con gcc già installato):
 sudo apt-get install libc6-dev-i386 
o in alternativa
 sudo apt-get install gcc-multilib 
e questi su sustemi Fedora/RedHat (con gcc già installato):
 yum install glibc-devel.i686 libgcc.i686 


Se i suddetti pacchetti non sono installati, tipici errori che si ottengono in fase di compilazione e linking sono (in assenza di libc6-dev-i386 o glibc-devel.i686):
 [...]
/usr/include/gnu/stubs.h:7:27: error:
gnu/stubs-32.h: No such file or directory
e (su sistemi Fedora/RedHat, in presenza di glibc-devel.i686 ma assenza di libgcc.i686):
 [...]/ld: cannot find -lgcc_s 
[...]
collect2: ld returned 1 exit status

martedì 15 dicembre 2009

C: Math.h e undefined reference to...

Imbattersi in un errore come il seguente è particolarmente pericoloso se non si sa di cosa si tratta, in questo caso la soluzione, banale, sarebbe ardua da identificare.

    /tmp/cctraBp0.o: In function `main': 
run.c:(.text+0x34): undefined reference to `sqrt'
collect2: ld returned 1 exit status
In questo esempio ho compilato un programma molto semplice:

 #include <stdio.h> 
#include <math.h>

int main()
{
double x = 2.0;

printf("Hello (%lf).\n", sqrt(x));

return 0;
}
Qui viene utilizzata una funzione della libreria matematica, sqrt, e viene opportunamente incluso l'header math.h, ma la libreria matematica del C appartiene ad una speciale categoria di librerie, quella delle librerie dinamiche o condivise (shared libraries).
Quando si usa una di queste librerie non è sufficiente includerla nel codice, si rende necessario utilizzare delle opzioni di compilazione. Per compilare correttamente questo programma senza ottenere errori dal linker (ld), dobbiamo aggiungere l'opzione -lm, in questo modo:
 gcc run.c -o run -lm 
In questo modo si otterrà un eseguibile perfettamente funzionante senza errori di linking.

ATTENZIONE: quando si usano versioni recenti di gcc (sicuramente dalla versione 4.3.1 in poi) l'utilizzo dell'opzione -lm è necessario soltanto se si utilizzano le funzioni matematiche insieme a variabili. Se invocassimo sqrt con una costante come argomento, il gcc sostituisce l'invocazione della funzione con il suo risultato ed il codice corrispondente alla invocazione della funzione matematica non viene generato. Per questo non c'è bisogno di aggiungere l'opzione del linker che permette il caricamento dinamico della libreria a run-time. Il seguente codice, ad esempio:

 #include <stdio.h> 
#include <math.h>

int main()
{
printf("Hello (%lf).\n", sqrt(2.0));

return 0;
}
può essere compilato correttamente con il seguente comando:
 gcc run.c -o run 

senza che il linker restituisca alcun errore.

giovedì 5 novembre 2009

C: compilare un semplice programma

Come compilare un semplice programma C in poche semplici mosse.

Innanzitutto abbiamo bisogno del semplice programma C, quindi ecco una versione personalizzata del solito "Hello World!".
 #include <stdio.h> 

int main()
{
printf("Hello Max!");

return 0;
}
Potete scrivere questo codice (o fare copia e incolla dello stesso) all'interno di un file chiamato hello.c, ad esempio. Il nome del file non è importante potete chiamare i vostri file come volete, purché siano nomi validi per il vostro sistema operativo.
Adesso vediamo come compilare tale programma con il compilatore gcc.
E' sufficiente digitare da riga di comando:
 gcc hello.c -o hello 
L'opzione -o permette di specificare il nome del file eseguibile che vogliamo generare, in questo caso hello. Se non viene specificato un nome tramite l'opzione -o gcc assegna un nome standard all'eseguibile: a.out.
Il gioco è fatto, adesso abbiamo a disposizione il nostro programma compilato che si chiama hello e si trova nella stessa cartella di hello.c, eseguendolo si otterrà in output sul terminale la stringa di testo che abbiamo chiesto di stampare tramite l'istruzione printf.
In GNU/Linux per eseguire il programma appena compilato è necessario digitare la seguente istruzione in un terminale e premere invio:
 ./hello 
Perché "semplice programma C"? Primo perché è costituito da un unica istruzione, secondo perché il programma qui presentato è costituito anche da un solo file. Di solito i programmi dei veri programmatori sono compilati a partire da diversi file sorgente (in alcuni casi centinaia o migliaia di file), ma in questi casi è un po' più complessa la procedura di compilazione tanto che a volte si ricorre ad un ottimo strumento, chiamato makefile, che permette di compilare grandi progetti in modo semplice, veloce ed efficiente. Spero di poter mostrare il funzionamento di un makefile in un prossimo post.