2013-07-26 2 views
2

하위 디렉토리 Makefile의 모든 대상을 호출하는 최상위 Makefile을 만드는 방법은 무엇입니까?하위 디렉토리 메이크 파일에서 메이크 파일 찾기 대상을 만드는 방법

내 폴더 구조는 다음과

/Makefile 
/src/Makefile 

I 코드처럼 /src/Makefile 모든 대상이지만, 지금은 내 작품을 쉽게하기 위해 다른 /Makefile 쓰고 싶어요. 이 최상위 Makefile을 작성하는 방법?

+0

TOP'makefile' 호출 하위'makefile'을 원하십니까? –

+1

모든 대상 또는 '모두'대상을 의미합니까? – Beta

답변

4
당신은

all: 
    @$(MAKE) -C src 

를 사용하고 하위 디렉토리에서 makefile을 사용하지 않는 경우, 예를 들어, 당신은 somename.mk 사용, 당신은

all: 
    @$(MAKE) -C src -f somename.mk 

I을 사용할 수 있습니다 귀하의 TOP 메이크 파일에 쓸 수

당신이 내 예를 보여, 내 DIR 보이는 같은 :

TOPDIR-- Makefile 
| 
|-- debug 
| |-- debug.c 
| |-- debug.h 
| |-- debug.mk 
| |-- instrument.c 
| `-- uart_print.c 
|-- driver 
| |-- driver.c 
| |-- driver_ddi.c 
| |-- driver_ddi.h 
| |-- driver.h 
| `-- driver.mk 
|-- include 
| `-- common.h 
|-- Makefile 
|-- mw 
| |-- manager.c 
| `-- mw.mk 
|-- root 
| |-- main.c 
| `-- root.mk 

내 TOP 메이크 파일은 다음과 같습니다

MAKE_DIR = $(PWD) 

ROOT_DIR := $(MAKE_DIR)/root 
DRV_DIR  := $(MAKE_DIR)/driver 
INCLUDE_DIR := $(MAKE_DIR)/include 
DEBUG_DIR := $(MAKE_DIR)/debug 

INC_SRCH_PATH := 
INC_SRCH_PATH += -I$(ROOT_DIR) 
INC_SRCH_PATH += -I$(DRV_DIR) 
INC_SRCH_PATH += -I$(INCLUDE_DIR) 
INC_SRCH_PATH += -I$(DEBUG_DIR) 

LIB_SRCH_PATH := 
LIB_SRCH_PATH += -L$(MAKE_DIR)/libs 


COLOR_ON = color 
COLOR_OFF = 
CC = $(COLOR_ON)gcc 
#CC = $(COLOR_OFF)gcc 
LD = ld 

LINT = splint 

LIBS := -ldriver -ldebug -lmw -lm -lpthread 

CFLAGS := 
CFLAGS += $(INC_SRCH_PATH) $(LIB_SRCH_PATH) 
CFLAGS += -Wall -O -ggdb -Wstrict-prototypes -Wno-pointer-sign -finstrument-functions -fdump-rtl-expand 
CFLAGS += -DDEBUG -D_REENTRANT 

LDFLAGS := 

export MAKE_DIR CC LD CFLAGS LDFLAGS LIBS LINT INC_SRCH_PATH 

all: 
    @$(MAKE) -C debug -f debug.mk 
    @$(MAKE) -C driver -f driver.mk 
    @$(MAKE) -C mw -f mw.mk 
    @$(MAKE) -C root -f root.mk 

.PHONY: clean 
clean: 
    @$(MAKE) -C debug -f debug.mk clean 
    @$(MAKE) -C driver -f driver.mk clean 
    @$(MAKE) -C mw -f mw.mk clean 
    @$(MAKE) -C root -f root.mk clean 

.PHONY: lint 
lint: 
    $(MAKE) -C debug -f debug.mk lint 

컴파일 중 하위 DIR * .mk를 호출합니다. 하위 디렉터리 메이크, 나는 당신이 참조에 대한 간단한 예 쓰기 : 나는 LIB 파일을 생성 서브 메이크 파일을 사용하기 때문에 대상 파일이 조금 다르다 생성 메이크위한

LIB = $(MAKE_DIR)/libs/yourmodulename.a 
SRCS = $(wildcard *.c) 
OBJS = $(patsubst %.c, %.o, $(SRCS)) 

$(LIB): $(OBJS) 
    @mkdir -p ../libs 
    @$(AR) cr [email protected] $^ 
    @echo " Archive $(notdir [email protected])" 

$(OBJS): $(SRCS) 
    @$(CC) $(CFLAGS) -c $^ 
    @echo " CC  $(OBJS)" 

.PHONY: clean 
clean: 
    @$(RM) -f $(LIB) $(OBJS) 
    @$(RM) -f *.expand 
    @echo " Remove Objects: $(OBJS)" 
    @echo " Remove Libraries: $(notdir $(LIB))" 

.PHONY: lint 
lint: 
    $(LINT) $(INC_SRCH_PATH) $(SRCS) 

를, 내가 사용 목표를 생성하는 root.mk :

PROG = ../prog/DEMO 

SRCS = $(wildcard *.c) 
OBJS = $(patsubst %.c, %.o, $(SRCS)) 

$(PROG): $(SRCS) 
    @mkdir -p ../prog 
    @$(CC) $^ $(CFLAGS) -Wl,-Map=$(PROG).map $(LIBS) -o [email protected] 
    @echo " Generate Program $(notdir $(PROG)) from $^" 

.PHONY: clean 
clean: 
    @$(RM) -f $(OBJS) $(PROG) 
    @$(RM) -f *.expand 
    @$(RM) -rf ../prog ../libs 
    @echo " Remove Objects: $(OBJS)" 
    @echo " Remove Libraries: $(notdir $(PROG))" 
+0

고마워,하지만 '모든'모든 목표와 일치합니까? 또는'모두'는 목표 중 하나의 예일뿐입니다. –

+0

@guilin 桂林, 내'makefile'에서'모든 것'이 내 프로젝트의 모든 타겟과 일치한다고 생각합니다. –

2

주의 할 점은 적어도 두 가지 방법이 있습니다.

all: 
    make -C dir 

make 설명서를 말한다 :

GNU Changedir 옵션

한 가지 방법은 -C 옵션은 컴파일 디렉토리를 변경하고 다른 하나에 도달 할 수 있도록 GNU의 특정 기능이 있는지 확인하여이다 :

-C dir, --directory=dir 
    Change to directory dir before reading the makefiles or doing anything 
    else. If multiple -C options are specified, each is interpreted relative 
    to the previous one: -C/-C etc is equivalent to -C /etc. This is 
    typically used with recursive invocations of make. 

대상 디렉토리에서 특정 대상을 호출하여이 옵션을 결합 할 수도 있습니다. 예를 들어, 다음 목표는 src/ 디렉토리가 표시되고 clean 목표 make를 호출하고의 GNU 방법의 문제는 단지 GNU와 함께 작동한다는 것입니다

clean: 
     @rm -f *.o 
     make -C src/ clean 

POSIX 방법

표준 Make가 아닌 Make. 어떤 이유로 든 다른 Make를 사용할 수 있다면 POSIX 방식으로 더 잘 수행하는 것이 좋습니다.POSIX에서

는이처럼 cd 명령에 더 의존해야, 확인하십시오, 나는 &&하지 ;을 사용

all: 
     cd src/ && make 

참고. 무한 재귀 호출을 make으로 피하는 것이 중요합니다. 실제로 cmd1 ; cmd2cmd1cmd2을 순차적으로 실행합니다. cmd1 && cmd2cmd1을 순차적으로 실행하고 은 EXIT_SUCCESS을 반환하는 경우에만 cmd2이 실행됩니다. 이 경우 디렉토리가 제거 되었기 때문에 처음으로 cd이 실패했다고 상상해보십시오. 그런 다음 초기 메이크 파일이 무한 재귀 루프에서 반복적으로 실행됩니다.

어쨌든이 POSIX 방식은 하위 디렉토리에서 내림차순으로 내려가 다른 Makefile을 실행하는보다 강력한 방법입니다. GNU Make에 링크 된 옵션에 의존하는 것보다 그것을 사용하는 것이 좋습니다.