2013-12-11 2 views
7

오류없이 작동하도록 makefile을 가져 오는 데 문제가 있습니다. 내가 가진 첫 번째 문제는 main에 대한 정의되지 않은 참조입니다. 내 producer.c 파일에 main이 함수로 있습니다. 두 번째 문제는 SearchCustomer()에 대한 정의되지 않은 참조입니다.(.text + 0x20) : 'main'에 대한 정의되지 않은 참조 및 함수에 대한 정의되지 않은 참조

오류 :

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 

메이크 :

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

코드가 ** 너무 ** 길다. 문제를 줄이고 [짧은, 자기 포함, 올바른 (편집 가능한), 예] (http://sscce.org/)를 제공하십시오. –

+0

몇 가지 제안 사항 :'main' 제조법에서는'$ (COMPILER) -o $ @ $^(LDFLAGS)'라고 쓰고'LDFLAGS'에'-pthread '를 넣을 수 있습니다. 다른 규칙들에서는 ** once ** :'% .o : % .c'와 recipe :'$ (COMPILER) $ (CCFLAGS) -c -o $ @ $ <'를 쓸 수 있습니다. * 컴파일러에'.h '를 줘라.) 그리고 나중에 특별한 타겟을위한 의존성을 추가한다. 예를 들면 :'producer.o : shared.h other_header.h'와'consumer.o : shared.h yet_another_header.h' 등. – Shahbaz

+1

몇 가지 다른 제안 : 호출 된 make에 대한 명령 행 플래그를 유지하려면'make '대신'$ (MAKE)'를 사용하십시오. 또한'--no-print-directory'를 사용하여 몇 줄의 쓸모없는 출력을 방지 할 수 있습니다. 또한 C에 대해'CFLAGS'를 사용하십시오 (C++과 혼동을 줄 수있는'CCFLAGS' 대신에). – Shahbaz

답변

10

이 규칙

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

은 잘못된 것입니다. 그것은 producer.o라는 이름의 파일을 만들지 만, main이라는 파일을 생성하려고합니다. 고함을 용서하지만, 는 항상 대상에게를 참조하려면 $에 @를 사용하십시오 :

main: producer.o consumer.o AddRemove.o 
    $(COMPILER) -pthread $(CCFLAGS) -o [email protected] producer.o consumer.o AddRemove.o 
+4

또한'$ ^'를 사용하여 모든 의존성을 나타냅니다. – Shahbaz

4

이 오류는 연결하면서, 컴파일러는 어디 main() 함수의 정의를 찾을 수 없습니다 것을 의미한다.

메이크 파일에서 main 규칙은 다음과 같이 확장됩니다. gccmanual page으로 당

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

-o 스위치의 사용은 수단

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

아래와 같이 GCC가 -o 스위치 옆에 바로 제공 파일명 출력 넣을 것이다. 따라서 여기에 모든 .o 파일을 연결하고 바이너리 [main, 귀하의 경우]를 작성하는 대신 producer.o이라는 이진 파일을 작성하고 다른 .o 파일을 연결하십시오. 그것을 수정하십시오.

관련 문제