如何讓頂層Makefile調用子目錄Makefile中的所有目標?如何使makefile在子目錄makefile中找到目標
我的文件夾結構是這樣的
/Makefile
/src/Makefile
我的代碼/src/Makefile
所有目標,但現在我要再寫/Makefile
緩解我的工作。如何編寫這個頂級Makefile?
如何讓頂層Makefile調用子目錄Makefile中的所有目標?如何使makefile在子目錄makefile中找到目標
我的文件夾結構是這樣的
/Makefile
/src/Makefile
我的代碼/src/Makefile
所有目標,但現在我要再寫/Makefile
緩解我的工作。如何編寫這個頂級Makefile?
你可以在你的頂層Makefile編寫使用
all:
@$(MAKE) -C src
,如果你不子目錄使用的makefile,例如,你可以使用somename.mk,你可以使用
all:
@$(MAKE) -C src -f somename.mk
我告訴你我的例子,我的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
和我頂層Makefile的樣子:
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
它將在編譯期間調用子目錄* .mk。子DIR的makefile,我只寫你引用一個簡單的例子:
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)
的Makefile文件生成目標文件是有點不同,因爲我用的是子生成文件生成LIB文件,我用一個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))"
非常感謝,但是「全部」匹配任何目標?或者「全部」只是一個目標的例子? –
@guilin桂林,在我的'makefile'中,我想'all'匹配我的項目的任何目標 –
請注意,至少有兩種方法來做到這一點。
GNU Changedir選項
一種方法是使用GNU的特定功能時許,-C
選項允許改變你的編譯目錄,並達到另一個問題:
all:
make -C dir
的make
手冊說:
-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/
目錄並調用make
與clean
目標:
clean:
@rm -f *.o
make -C src/ clean
POSIX路
與做的GNU方式的問題是,它只能與GNU工程製作,而不是標準的製作。如果您可能使用其他品牌(無論出於何種原因),您最好考慮以更POSIX的方式進行。
在POSIX做,你必須更多地依靠cd
命令,就像這樣:
all:
cd src/ && make
需要注意的是,我用&&
,而不是;
。避免對make
進行無限遞歸調用非常重要。實際上,cmd1 ; cmd2
將按順序執行cmd1
和cmd2
,無論每個命令的結果如何,其中cmd1 && cmd2
將按順序執行cmd1
和cmd2
將僅在cmd1
返回EXIT_SUCCESS
時執行。在我們的例子中,想象第一個cd
因爲目錄已被刪除而失敗。然後,最初的makefile將在無限遞歸循環中一次又一次地執行。
無論如何,這種POSIX方式,是在子目錄中下降並執行其他Makefile的更健壯的方式。我建議你比使用與GNU Make相關的選項更好地使用它。
你想要'makefile'調用子'makefile'嗎? –
你是指所有目標,還是「全部」目標? – Beta