5

サブディレクトリ Makefile 内のすべてのターゲットを呼び出す最上位の Makefile を作成する方法は?

私のフォルダ構造はこのようなものです

/Makefile
/src/Makefile

すべてのターゲットを でコーディングしていますが、作業を容易にするために/src/Makefile別のターゲットを記述したいと考えています。/Makefileこの最上位 Makefile の書き方は?

4

3 に答える 3

7

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))"
于 2013-07-26T04:48:02.903 に答える
3

これには少なくとも 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/ディレクトリに入りmakecleanターゲットを呼び出します。

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

POSIX ウェイ

GNU の方法の問題点は、GNU Make でのみ機能し、標準の Make では機能しないことです。(何らかの理由で) 別の Make を使用する可能性がある場合は、より POSIX の方法で行うことを検討することをお勧めします。

cdPOSIX Make では、次のように、コマンドにもっと依存する必要があります。

all:
        cd src/ && make

注意してください、私は&&and ではありません;。への無限再帰呼び出しを避けることは非常に重要makeです。実際、cmd1 ; cmd2は順番に実行cmd1されcmd2、各コマンドの結果が何であれ、 はcmd1 && cmd2順番cmd1に実行され、 が返されたcmd2場合にのみ実行されます。私たちの場合、ディレクトリが削除されたために最初が失敗したと想像してください。その後、最初のメイクファイルが無限再帰ループで何度も実行されます。cmd1EXIT_SUCCESScd

とにかく、この POSIX の方法は、サブディレクトリに降りて他の Makefile を実行するためのより堅牢な方法です。GNU Make にリンクされたオプションに依存するよりも、より適切に使用することをお勧めします。

于 2013-07-26T07:45:15.490 に答える