2013-12-11 17 views
7

Ho problemi a far funzionare il makefile senza errori. Il primo problema che ho è con un riferimento non definito a main. Ho una parte principale nel mio file producer.c come una funzione. Il secondo problema è un riferimento non definito a SearchCustomer().(.text + 0x20): riferimento non definito a "main" e riferimento non definito alla funzione

errore:

bash-4.1$ make 
gcc -Wall -c producer.c shared.h 
gcc -Wall -c consumer.c shared.h 
gcc -Wall -c AddRemove.c shared.h 
gcc -pthread -Wall -o producer.o consumer.o AddRemove.o 
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start': 
(.text+0x20): undefined reference to `main' 
AddRemove.o: In function `AddRemove': 
AddRemove.c:(.text+0xb1): undefined reference to `SearchCustomer' 
AddRemove.c:(.text+0x1e9): undefined reference to `SearchCustomer' 
AddRemove.c:(.text+0x351): undefined reference to `SearchCustomer' 
collect2: ld returned 1 exit status 
make: *** [producer] Error 1 

makefile:

COMPILER = gcc 
CCFLAGS = -Wall 
all: main 

debug: 
    make DEBUG=TRUE 


main: producer.o consumer.o AddRemove.o 
    $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o 
producer.o: producer.c shared.h 
    $(COMPILER) $(CCFLAGS) -c producer.c shared.h 
consumer.o: consumer.c shared.h 
    $(COMPILER) $(CCFLAGS) -c consumer.c shared.h 
AddRemove.o: AddRemove.c shared.h 
    $(COMPILER) $(CCFLAGS) -c AddRemove.c shared.h 


ifeq ($(DEBUG), TRUE) 
    CCFLAGS += -g 
endif 

clean: 
    rm -f *.o 
+0

Il codice è ** troppo lungo. Restringi il tuo problema e fornisci [Breve, Autonomo, Corretto (Compilabile), Esempio] (http://sscce.org/). –

+0

Un paio di suggerimenti: nella ricetta 'main', puoi scrivere:' $ (COMPILER) -o $ @ $^$ (LDFLAGS) 'e inserisci' -pthread' in 'LDFLAGS'. Nelle altre regole puoi scrivere ** una volta **: '% .o:% .c' e come ricetta:' $ (COMPILER) $ (CCFLAGS) -c -o $ @ $ <'(e ** non * * dai '.h' al compilatore!) e successivamente aggiungi la dipendenza per target speciali, ad esempio:' producer.o: shared.h other_header.h' e 'consumer.o: shared.h yet_another_header.h' ecc. – Shahbaz

+1

Un paio di altri suggerimenti: Usa '$ (MAKE)' invece di solo 'make' per mantenere i flag della riga di comando per il make invocato. Si potrebbe anche voler dare '--no-print-directory' per evitare coppie di righe di output inutili. Inoltre, usa 'CFLAGS' per C (invece di' CCFLAGS' che potrebbe essere scambiato per C++). – Shahbaz

risposta

10

Questa regola

main: producer.o consumer.o AddRemove.o 
    $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o 

è sbagliato. Dice di creare un file denominato producer.o, ma si desidera creare un file denominato main. Chiedo scusa per le urla, ma uso sempre $ @ per fare riferimento al TARGET:

+4

Usa anche '$ ^' per fare riferimento a tutte le dipendenze di esso. – Shahbaz

4

Questo errore significa che, durante il collegamento, il compilatore non è in grado di trovare la definizione della funzione di main() ovunque.

Nel tuo makefile, la regola main si espanderà a qualcosa di simile.

main: producer.o consumer.o AddRemove.o 
    gcc -pthread -Wall -o producer.o consumer.o AddRemove.o 

Come per la gccmanual page, l'uso di -o interruttore è come sotto

-o file Place output in file file. This applies regardless to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code. If -o is not specified, the default is to put an executable file in a.out.

Significa, gcc metterà l'uscita nel nome del file disponibile immediatamente accanto -o interruttore. Quindi, qui invece di collegare tutti i file .o insieme e creare il file binario [main, nel tuo caso], il suo binario è in codice come producer.o, che collega gli altri file .o. Per favore, correggilo.