View Full Version : [C] GCC linker, come funziona?
buongiorno a tutti,
mi sto cimentando per la prima volta a creare un piccolo gioco in OPENGL utilizzando le librerie allegro e allegroGL ...ovviamente scritto in linguaggio C
mi sto divertendo un mondo ed i risultati sono già arrivati, mi manca da inserire la musica nel mio giochino, e per far questo ho scelto di utilizzare la libreria dumb:
http://dumb.sourceforge.net/
aggiungo l'include, aggiungo le funzioni all'interno del gioco, ma alla compilazione con gcc mi restituisce "undefined reference" per ogni funzione della libreria dumb utilizzata
questi sono i miei include:
#include <stdio.h>
#include <aldumb.h>
#include <allegro.h>
#include <alleggl.h>
tutti i file si trovano correttamente in /usr/include/
questa è la riga per la compilazione
gcc -laldmb -ldumb `allegro-config --libs` -lagl -lGL -lGLU -o campostellato campostellato.c
con `allegro-config --libs` importo i percorsi per le librerie allegro il comando restituisce:
-L/usr/lib -Wl,--export-dynamic -lalleg-4.2.0 -lalleg_unsharable
-lagl -lGL -lGLU mi linkano tutto l'occorrente per l'OPENGL e funzionano correttamente
le righe incriminate sono -laldmb -ldumb, che il compilatore accetta ma alla fine non linka
non vi sto chiedendo se dumb funziona o meno, come ho detto è la prima volta che mi cimento con il C e volevo capire "che cosa andare a guardare" per controllare che il linker possa compretare correttamente il suo lavoro
grazie! :help: :help:
Non conosco questa libreria e non so come l'hai installata nel sistema ma ti posso dire questo: se hai specificato -laldmb -ldumb allora va a cercare nella directory che contiene le librerie (in genere /usr/lib) due file libaldmb.a e libdumb.a.
l'ho installata con un semplice make + make config
al make mi ha chiesto il percorso di installazione ed io l'ho spostato da quello proposto /usr/local/ a /usr/
posso dirti che i file sono presenti in:
[giacomo@Jarchy lib]$ pwd
/usr/lib
[giacomo@Jarchy lib]$ ls -la |grep libaldmb.a
-rw-r--r-- 1 root root 17112 1 mar 12:52 libaldmb.a
[giacomo@Jarchy lib]$ ls -la |grep libdumb.a
-rw-r--r-- 1 root root 327230 1 mar 12:52 libdumb.a
:mbe:
ho ricercato nei sorgenti di dumb ed ho trovato le funzioni che ho usato all'interno del mio programma :)
ho ricompilato e reinstallato la libreria dumb!
[root@Jarchy dumb-0.9.3]# make install
cp lib/unix/libdumb.a /usr/lib
cp lib/unix/libdumbd.a /usr/lib
cp examples/dumbout examples/dumb2wav /usr/bin
cp include/dumb.h /usr/include
cp lib/unix/libaldmb.a /usr/lib
cp lib/unix/libaldmd.a /usr/lib
cp examples/dumbplay /usr/bin
cp include/aldumb.h /usr/include
DUMB has been installed.
See readme.txt for details on the example programs.
When you're ready to start using DUMB, see docs/howto.txt.
Enjoy!
Edit:
avevo scritto una cavolata
al punto di prima...
trallallero
02-03-2007, 08:05
Edit:
avevo scritto una cavolata
al punto di prima...
quindi da ancora errore ?
se si prova con
gcc -v <poi tutto il resto>
per attivare il verbose mode cosí vedi dove il gcc si va a prendere gli headers e libs varie ;)
EDIT:
altra dritta: prova a mettere la lib col percorso completo:
anziché -laldmb gli metti /usr/lib/libaldmb.a
guarda ho studiato un po il funzionamento del GCC e del linker, ho provato sia con i percorsi completi delle librerie sia spostando tutto l'occorrente manualmente nella cartella del progetto... risultati zero
ho cambiato libreria, ho scelto "fmod" e adesso senza alcun problema ho la musica nel mio giochino
una domanda: vorrei compilare il mio programma integrandone tutte le librerie necessarie, ossia compilare staticamente
ho letto di aggiungere -static al gcc, ma ho bisogno delle librerie che utilizzo in versione statica ( .a ) che non sempre vengono fornite assieme alla libreria stessa... nel mio caso la libreria allegroGL è stata installata nel file /usr/lib/libagl.so (libreria condivisa)
quando cerco di compilare con -static mi dice:
/usr/bin/ld: cannot find -lagl
penso che cerchi /usr/lib/libagl.a
cercando in rete ho letto che è molto facile convertire da una libreria statica a una dinamica, ma non ho trovato il contrario!
ne sapete qualcosa? :help:
trallallero
02-03-2007, 15:41
da me (ma ho Sun) cercherebbe prima /usr/lib/libagl.so e poi /usr/lib/libagl.a
Infatti da man ld:
On systems which support shared libraries, ld may also search for
libraries with extensions other than ".a". Specifically, on ELF
and SunOS systems, ld will search a directory for a library with an
extension of ".so" before searching for one with an extension of
".a". By convention, a ".so" extension indicates a shared library.
Comunque devi passare -L<direttorio> se la lib si trova in un direttorio non standard ;)
da me (ma ho Sun) cercherebbe prima /usr/lib/libagl.so e poi /usr/lib/libagl.a
Infatti da man ld:
Comunque devi passare -L<direttorio> se la lib si trova in un direttorio non standard ;)
SunOS? che figo!!!! com'è?
ma infatto io ho il .so ed io voglio il .a, perchè voglio compilare staticamente
il percorso della libreria è esatto (ho creato anche un makefile apposito), è il .a che vuole ma non trova (perchè non c'è)
volevo convertire il .sa in .a se possibile
trallallero
02-03-2007, 16:23
SunOS? che figo!!!! com'è?
figo ? :rotfl:
scherzo, diciamo che potrebbe essere figo se aggiornassero il SO e qualche programma vetuserrimo.
Di certo non é vero che non s'impianta mai. Se vuoi qualche info piú dettagliata chiedi pure :cool: :D
ma infatto io ho il .so ed io voglio il .a, perchè voglio compilare staticamente
il percorso della libreria è esatto (ho creato anche un makefile apposito), è il .a che vuole ma non trova
se la libreria é compilata in un certo modo non é che puoi snaturarla. Se hai un .so é dinamica e non puoi linkarla staticamente, dovresti avere il sorgente e ricompilarla.
Mi ricordo che aveva un problema del genere una ragazza qui (non ricordo il nick) e mi sono fatto mandare tutto il sorgente. Le ho cambiato (se non ricordo male) proprio la compilazione della libreria da dinamica a .a e linkato l'eseguibile staticamente. O forse al contrario. Comunque poi andava :)
Potrei aver detto una marea di cazzate, non mi prendo responsabilitá, sono svelgio dalle 3:30, sto aspettando che sto cazzo di clearcase mi mandi la richiesta in beta :muro:
penso tu abbia ragione :D ho spulciato fra i sorgenti di allegroGL e sono riuscito a creare il .a che mi serve
adesso mi chiede un'altro .a che non trovo,parlo della libreria fmod
a dir la verità non trovo nemmeno i sorgenti in rete...sul sito ufficiale danno solo la libreria :(
aaaaaaaaaaaahh!! ho scoperto perchè la debian è tanto osannata!
dentro i pacchetti *-dev ci stanno le librerie statiche!!!
:mad: :mad: :mad: :mc: :mc: :mad: :mad:
trallallero
02-03-2007, 19:22
aaaaaaaaaaaahh!! ho scoperto perchè la debian è tanto osannata!
dentro i pacchetti *-dev ci stanno le librerie statiche!!!
:mad: :mad: :mad: :mc: :mc: :mad: :mad:
non ho capito :stordita:
nico88desmo
03-03-2007, 14:17
una domanda un pò out dal discorso...
a me servirebbe generare tramite il gcc un codice oggetto che contenga, oltre alle funzioni che ho scritto io nel file .c, anche le funzioni contenute nelle librerie da esso incluse (per esempio la printf nel caso di #include <stdio.h>)
c'è un modo per fare questo?
spero di essere stato chiaro...
trallallero
03-03-2007, 15:36
una domanda un pò out dal discorso...
a me servirebbe generare tramite il gcc un codice oggetto che contenga, oltre alle funzioni che ho scritto io nel file .c, anche le funzioni contenute nelle librerie da esso incluse (per esempio la printf nel caso di #include <stdio.h>)
c'è un modo per fare questo?
spero di essere stato chiaro...
cioè tu vorresti creare un .o che contenga anche le librerie standard del C ? se è così temo che non si possa perchè sono dinamiche. Ma potre sbagliarmi, non ci ho mai pensato e provato
EDIT: puoi provare a scaricarti la GNU C Library (gratis)
http://sourceware.org/ml/libc-announce/2005/msg00000.html
nico88desmo
03-03-2007, 16:00
Vorrei questo in quanto sto chiamando delle funzioni C all'interno di delphi, però al momento del link del progetto delphi mi dà errore in quanto non trova le funzioni del c scritte nel file .c appunto (tipo printf)
per chiarire...sto facendo questo...
http://www.hwupgrade.it/forum/showthread.php?t=1420924
in quel caso non mi ha dato problemi perchè, nel file .c, ho fatto solo una return; però se inserisco una banale strcpy per esempio, non mi trova la funzione.
Quindi per risolvere il problema, o faccio un file oggetto che contenga le librerie standard del c, oppure trovo un linker adeguato che in qualche modo mi trova le librerie. Ovviamente la seconda soluzione sarebbe molto meglio.
C'è qualche linker adatto a questo?
trallallero
03-03-2007, 16:29
non saprei, mi spiace ma non ho nessun tipo di esperienza di delphi.
Prova ad aggiungere -lc ai parametri del gcc
l'ho sparata così ... è la prima cosa che proverei :stordita:
Altrimenti potresti usare un'altra direttiva
- {$L <libreria C>}
nico88desmo
03-03-2007, 16:46
provato...niente da fare...è più ostico del previsto far questa cosa. :rolleyes:
trallallero
03-03-2007, 17:32
provato...niente da fare...è più ostico del previsto far questa cosa. :rolleyes:
scusa ma tu puoi linkare un tuo .o fatto in C e non puoi linkare una libreria dinamica fatta in C ?
Se te la cavi in inglese prova qui ;)
www.delphiforums.com
nico88desmo
04-03-2007, 09:51
quello posso farlo, il problema è che insieme devo linkare anche i file oggetto del delphi (lazarus);
Ora guardo il link, per l'inglese...ormai se non si sà questa lingua si è tagliati fuori per ricercare queste cose; se non si capisce si impara :) ... quindi mi tocca imparare :D
nico88desmo
04-03-2007, 11:50
si può generare un file oggetto (.o) partendo da una libreria (.h)?
trallallero
04-03-2007, 14:58
si può generare un file oggetto (.o) partendo da una libreria (.h)?
No, il .h non è una libreria ma un file contenente definizioni, prototipi, dichiarazioni, macro etc.
L'implementazione delle funzioni è sempre nel sorgente .c
nico88desmo
04-03-2007, 20:52
mi è venuto un dubbio...ma i file header .h vengono collegati al sorgente al momento del link giusto?
trallallero
04-03-2007, 21:13
mi è venuto un dubbio...ma i file header .h vengono collegati al sorgente al momento del link giusto?
no, è un discorso un pò lungo ... c'è il preprocessore di mezzo. Il linker è ciò che incolla le librerie statiche all'eseguibile (per le dinamiche meglio ti risponda qualcuno più esperto) controllando che le funzioni (e altro) ci siano fisicamente mentre il preprocessore controlla (tra le varie cose) che le funzioni chiamate siano dichiarate. E' ben diverso. Infatti mentre compili un .c che ha una printf il preprocessore controlla che tu abbia dichiarato tale funzione (il prototipo che è dentro stdio.h) ma non controlla che esista; in seguito il linker cerca la funzione fisicamente e se non la trova dentro le librerie che hai specificato (o quelle standard) da errore.
nico88desmo
05-03-2007, 20:41
quindi se ho capito bene, solo il linker inserisce il codice delle funzioni chiamate da un programma all'interno del programma stesso mentre il preprocessore fa una "scansione" del codice per verificare che tutte le funzioni siano state da qualche parte dichiarate.
trallallero
06-03-2007, 08:13
quindi se ho capito bene, solo il linker inserisce il codice delle funzioni chiamate da un programma all'interno del programma stesso mentre il preprocessore fa una "scansione" del codice per verificare che tutte le funzioni siano state da qualche parte dichiarate.
Si, hai capito bene. Il linker "inserisce" se la libreria é statica quindi l'eseguibile sará di dimensioni maggiori perché conterrá la libreria, mentre controlla che ci sia fisicamente se dinamica e la cerca o nei direttori standard o dove dici tu con -L<direttorio> -l<lib>.
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.