2013-12-11 22 views
7

Makefile'm hata yapmadan çalışmaya başlamasında sorun yaşıyorum. Sahip olduğum ilk konu, ana tanımlanmamış bir referanstır. Produc.c dosyasında bir işlev olarak ana var. İkinci sorun, SearchCustomer() için tanımlanmamış bir referanstır.(.text + 0x20): "ana" ve tanımsız başvuru referansı için tanımsız başvuru

hatası:

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

Kod ** çok ** uzun. Sorununuzu daraltın ve bir [Kısa, Kendini İçeren, Doğru (Tamamlayıcı), Örnek] (http://sscce.org/) sağlayın. –

+0

Bir kaç öneri: "ana" tarifinde: $ (COMPILER) -o $ @ $^$ (LDFLAGS) yazıp 'LDPLAGS'de' -pthread' yazabilirsiniz. Diğer kurallarda ** bir kez ** yazabilirsiniz: '% .o:% .c' ve tarif olarak: $ (COMPILER) $ (CCFLAGS) -c -o $ @ $ <' (ve ** değil * * .h'yi derleyiciye verin!) ve daha sonra özel hedeflere bağımlılık ekleyin, örneğin: "producer.o: shared.h other_header.h" ve "consumer.o: shared.h yet_another_header.h" vb. – Shahbaz

+1

Diğer birkaç öneri: Sadece make yapmak yerine 'make' yerine' $ (MAKE) 'işlevini kullanın. Ayrıca, gereksiz çıktıların çift satırlarını önlemek için '--no-print-directory 'vermek isteyebilirsiniz. Ayrıca, C için CFLAGS'yi kullanın (C++ ile karıştırılabilecek 'CCFLAGS' yerine). – Shahbaz

cevap

10

Bu kural

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

yanlıştır. Producer.o adlı bir dosya oluşturduğunu, ancak main adlı bir dosya oluşturmak istediğinizi söylüyor. bağırarak mazur görün ama her zaman hedef REFERANS İÇİN $ @ KULLANIMI: Lütfen

+4

Ayrıca, tüm bağımlılıklarına başvurmak için '$ ^' kullanın. – Shahbaz

4

Bu hata bağlarken, derleyici yerde main() fonksiyonun tanımını bulmak mümkün değildir, anlamına gelir.

Makefileinizde main kuralı bu gibi bir şeye genişler. gccmanual page uyarınca

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

, -o anahtarın kullanımı Bu şu anlama gelir

-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.

aşağıdaki gibi, gcc -o anahtarı yanında hemen temin dosya çıkışı verecek olan. Yani, burada tüm .o dosyalarının birbirine bağlanması ve ikilinin [main, sizin durumunuzda] oluşturulması yerine, diğer .o dosyalarını birbirine bağlayarak, binary'yi producer.o olarak kodlaması. Lütfen bunu düzeltin.