サブディレクトリ Makefile 内のすべてのターゲットを呼び出す最上位の Makefile を作成する方法は?
私のフォルダ構造はこのようなものです
/Makefile
/src/Makefile
すべてのターゲットを でコーディングしていますが、作業を容易にするために/src/Makefile
別のターゲットを記述したいと考えています。/Makefile
この最上位 Makefile の書き方は?
サブディレクトリ Makefile 内のすべてのターゲットを呼び出す最上位の Makefile を作成する方法は?
私のフォルダ構造はこのようなものです
/Makefile
/src/Makefile
すべてのターゲットを でコーディングしていますが、作業を容易にするために/src/Makefile
別のターゲットを記述したいと考えています。/Makefile
この最上位 Makefile の書き方は?
TOP 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
私の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
コンパイル中に sub DIR *.mk を呼び出します。サブ DIR の makefile です。参照用に簡単な例を書きます。
LIB = $(MAKE_DIR)/libs/yourmodulename.a
SRCS = $(wildcard *.c)
OBJS = $(patsubst %.c, %.o, $(SRCS))
$(LIB): $(OBJS)
@mkdir -p ../libs
@$(AR) cr $@ $^
@echo " Archive $(notdir $@)"
$(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ファイルを生成し、aを使用してターゲットを生成するため、ターゲットファイルを生成するmakefileは少し異なります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 $@
@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))"
これには少なくとも 2 つの方法があることに注意してください。
GNU Changedir オプション
1 つの方法は、GNU Make の特定の機能を使用することです。この-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 Make でのみ機能し、標準の Make では機能しないことです。(何らかの理由で) 別の Make を使用する可能性がある場合は、より POSIX の方法で行うことを検討することをお勧めします。
cd
POSIX Make では、次のように、コマンドにもっと依存する必要があります。
all:
cd src/ && make
注意してください、私は&&
and ではありません;
。への無限再帰呼び出しを避けることは非常に重要make
です。実際、cmd1 ; cmd2
は順番に実行cmd1
されcmd2
、各コマンドの結果が何であれ、 はcmd1 && cmd2
順番cmd1
に実行され、 が返されたcmd2
場合にのみ実行されます。私たちの場合、ディレクトリが削除されたために最初が失敗したと想像してください。その後、最初のメイクファイルが無限再帰ループで何度も実行されます。cmd1
EXIT_SUCCESS
cd
とにかく、この POSIX の方法は、サブディレクトリに降りて他の Makefile を実行するためのより堅牢な方法です。GNU Make にリンクされたオプションに依存するよりも、より適切に使用することをお勧めします。