2012-11-06 16 views
49

Sono nuovo al SO Linux. Sto cercando di compilare un file .c utilizzando un makefile. La biblioteca matematica deve essere collegata. Il mio makefile si presenta così:Come utilizzare LDFLAG nel makefile

CC=gcc 
CFLAGS=-Wall -lm 

all:client 

.PHONY: clean 
clean: 
    rm *~ *.o client 

Quando eseguo make, ottengo il seguente errore:

"undefined reference to rint" 

quindi non è in grado di collegare la libreria matematica.

Ma quando compilo in modo esplicito utilizzando

gcc client.c -lm -o client 

si compila con successo.

Quindi, come devo cambiare il mio makefile in modo che funzioni. Ho già provato ad aggiungere LDFLAGS=-lm. Ma ottengo lo stesso errore.

Dovrei anche aggiungere che quando ho eseguito make, si espande per

gcc -Wall -lm client.c -o client 

(si noti che quando ho eseguito gcc esplicitamente con -lm alla fine, funziona).

risposta

52

tuo linker (ld), ovviamente, non piace l'ordine in cui fanno organizza gli argomenti del GCC in modo da dovrete cambiare il vostro Makefile un po ':

CC=gcc 
CFLAGS=-Wall 
LDFLAGS=-lm 

OBJECTS=client.o 

client: $(OBJECTS) 
    $(CC) $(CFLAGS) $(OBJECTS) -o client $(LDFLAGS) 

all:client 

.PHONY: clean 
clean: 
    rm -f *~ *.o client 

Nella linea che definisce la cliente target cambia l'ordine di $ (LDFLAGS) secondo necessità.

+40

LDLIBS è per le biblioteche, LDFLAGS deve essere utilizzato per i percorsi bandiere/ricerca (-L) – falstaff

+3

[non c'è bisogno di definire in modo esplicito 'CC'.] (Http://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html) – 0xcaff

+3

Ho anche pensato che -lm dovrebbe essere in LDFLAGS ma come risulta (vedi la risposta di laindir e https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html), dovrebbe invece essere in LOADLIBES e quindi tutto funziona fuori dalla scatola (cioè senza definire regole esplicite) ! –

41

In scenari di compilazione più complicati, è comune interrompere la compilazione in fasi, con la compilazione e l'assemblaggio che avvengono per primi (l'output in file oggetto) e il collegamento di file oggetto in un eseguibile o libreria finale in seguito - questo impedisce di ricompilare tutti i file oggetto quando i loro file sorgente non sono cambiati. Ecco perché il flag di collegamento -lm non funziona quando lo inserisci in CFLAGS (CFLAGS viene utilizzato nella fase di compilazione).

La convenzione per le biblioteche per essere collegate è di metterli in entrambi i LOADLIBES o LDLIBS (GNU make include entrambi, ma la vostra situazione potrebbe essere diversa):

LDLIBS=-lm 

Ciò dovrebbe consentire di continuare a utilizzare l'incorporato nelle regole piuttosto che dover scrivere la propria regola di collegamento. Per altre marche, dovrebbe essere presente un flag per generare regole incorporate (per GNU make, questo è -p). Se la versione di make non ha una regola built-in per il collegamento (o se non ha un segnaposto per -l direttive), avrete bisogno di scrivere il proprio:

client.o: client.c 
    $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c -o [email protected] $< 

client: client.o 
    $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o [email protected] 
1

Sembra come l'ordine di i flag di collegamento non erano un problema nelle versioni precedenti di gcc. Ad esempio, gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-16) viene fornito con Centos-6.7 soddisfatto dell'opzione linker prima del file di input; ma gcc con ubuntu 16.04 gcc (Ubuntu 5.3.1-14ubuntu2.1) 5.3.1 20160413 non consente.

non la sua la versione gcc da sola, mi ha qualcosa per le distribuzioni

Problemi correlati