Makefile:使用多个Makefile

11
我有一个项目,里面有很多makefile。因为有时我只需要编译项目的部分,所以我决定在每个目录中都有一个makefile。但是当我想要运行包含所有其他文件的主makefile来编译我的项目时,它会给我很多错误信息。 这是我的项目树:
根目录 'makefile' - 文件夹1 'foo1.c foo2.c makefile' - 文件夹2 'makefile' -- 文件夹2-1 'foo3.c foo4.c makefile' -- 文件夹2-2 'foo5.c makefile'
每个最后一个目录中的makefile都已被包含到上一级makefile中。但它不会运行主makefile。我对GNU make非常陌生,我想要像这样的东西,但我不知道如何实现。我只是写了一些make脚本,但它们不起作用。 我只想要一个可以单独编译项目部分或使用多个makefile编译整个项目的东西。

1
你可以在TOP的makefile中使用“-C”选项来编译每个目录。 - How Chen
你能详细解释一下吗? - MadZarx
你提到了很多错误,但你从未说明它们是什么或提供任何makefile的部分。对于每个文件夹,您都想使用$(MAKE) -C folder_name,就像@How所提到的那样。此外,您确定正在使用正确的格式吗?任何要制作的目标都应出现在第一列,而实际制作这些目标的规则应缩进一个制表符(不是空格;即使您按下制表键,您的编辑器也可能使用空格)。 - user539810
谢谢。make -C DIRECTORY 解决了我的问题。我以为如果包含子 makefile 并调用目标,它会编译它们。但是这是错误的。我使用了 -C 现在它可以工作了。谢谢。 :) - MadZarx
1个回答

21

无论如何,我向您展示了一些内容,希望可以帮助您:

all:
    @$(MAKE) -C subfolder

如果您想使用 *.mk 作为子 Makefile,您可以编写:

all:
    @$(MAKE) -C busfolder -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 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

在编译过程中,它将调用子目录下的*.mk文件。对于子目录的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)"

对于生成最终目标文件(如a.out)的makefile,稍微有点不同,因为我使用子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 $@
    @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))"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接