2012-12-01 5 views
8

Makefile (및 일반적으로)에서 컴파일 및 링킹에 관한 질문이 있습니다.Makefile, Compiling and Linking

나는 main() 기능을 가진 메인 프로그램으로 구성된 server.c 파일을 가지고있다. server.c에는 rio.c가 포함됩니다. 나는 rio.crio.h으로 구성된 rio이라는 모듈을 가지고있다. 그것은 main() 기능이 없습니다.

나는 실제로 Makefile을 작성하는 방법과 그러한 일을하는 가장 좋은 방법이있다.

Q1 :

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
    $(CC) $(CFLAGS) -c server.c 

rio.o: rio.c rio.h 
    $(CC) $(CFLAGS) -c rio.c 

clean: 
    rm -f *~ *.o sysstatd 

나는이 문제를 연결하는 데 : 메이크

나는 다음 메이크 파일을 작성하는 방법. 그것은 C에서 사용되는 모든 함수에 대해 여러 정의를 가지고 있다고 말합니다. server.c가 -c 플래그로 컴파일되어 아무 것도 실제로 링크되지 않으므로 이것이 가능한지 잘 모르겠습니다. all 룰이 두 오브젝트 파일을 함께 컴파일하고 모든 것이 링크 된 단일 오브젝트 파일을 생성 할 때까지 실제로는 링크가없는 함수가 있음을 알아야합니다.

무엇이 문제입니까?

Q2 : 모범 사례 내가 메인 프로그램을 포함하는 모듈 다음 다른 파일을 가지고 있기 때문에, 나는 별도의 모듈로, 주요 프로그램, server.c을 컴파일해야하고 all 함께 모두 컴파일, 또는 서버를 컴파일 .c를 모두 추가하고 거기에 rio.o 모듈을 추가하십시오. 이것은 여전히 ​​위의 링크 문제와 동일한 결과를 생성하므로 내 문제가 다른 곳에 있다는 것을 확신합니다.

+0

당신은 어떤 외부 라이브러리를 사용하고 또한 프로그램 이름의 반복을 방지하기 위해 매크로를 사용할 수 있을까? – zeboidlund

+0

예. 하지만 그것은 server.c가 먼저 정의한 함수라는 오류를 호출합니다. server.c와 rio.h 둘다 import : stdio.h, stdlib.h, unistd.h, errno.h – darksky

+3

"server.c는 rio.c를 포함하고있다"라고 말할 때,'server.c'와 같이,'#include "rio.c와 같은 줄이 있습니다."'? 그렇다면 잘못된 접근 방법과 오류의 원인이 될 수 있습니다. 대신에'rio.h '를 포함해야합니다. –

답변

13

당신은 약간의 구조를 수정해야합니다

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: sysstatd 

sysstatd: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
    $(CC) $(CFLAGS) -c server.c 

rio.o: rio.c rio.h 
    $(CC) $(CFLAGS) -c rio.c 

clean: 
    rm -f *~ *.o sysstatd 

의 차이는 위선자 규칙 allsysstatd 최신 상태로 존재에 의존하고 날짜 WRT 객체까지 때 sysstatd가 최신이다 파일.

이제 컴파일 동작을 명시 적으로 작성하는 것이 다소 장황합니다. 그것은 충분한 사용하는 것입니다 :

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 

all: sysstatd 

sysstatd: $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o sysstatd 

server.o: server.c 
rio.o: rio.c rio.h 

clean: 
    rm -f *~ *.o sysstatd 

당신은 또한 토론 수 : server.crio.h를 사용하지 않는 이유는 무엇입니까? 그렇다면 종속성이 나열되어야합니다. 그렇지 않다면 rio.h은 왜 존재합니까? makeserver.oserver.c에 달려 있다고 가정하므로이를 지정할 필요는 없습니다 (그러나 헤더에 대해서는 가정하지 않습니다).

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 
PROG = sysstatd 

all: $(PROG) 

$(PROG): $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o [email protected] 

server.o: rio.h 
rio.o: rio.h 

clean: 
    rm -f *~ *.o $(PROG) core a.out 

다른 라이브러리를 필요로하는 경우에, 당신은 사용할 수 있습니다 :

CC = gcc 
CFLAGS = -Wall -Werror -Wmissing-prototypes 
OBJS = server.o rio.o 
PROG = sysstatd 
LOCALLIBDIR = /usr/local/lib 
LDFLAGS = -L$(LOCALLIBDIR) 
LDLIBS = -lone -ltwo 

all: $(PROG) 

$(PROG): $(OBJS) 
    $(CC) $(CFLAGS) $(OBJS) -o [email protected] $(LDFLAGS) $(LDLIBS) 

server.o: rio.h 
rio.o: rio.h 

clean: 
    rm -f *~ *.o $(PROG) core a.out 
+1

이와 같이 단계적으로 개선되어 상당히 유용합니다. 고맙습니다. –