使用 Make 的多个嵌套目录
Multiple Nested Directories with Make
我有这个 Makefile。
# Variables
CC = gcc
CFLAGS = -Wall -g -c
ODUMP = objdump
ODFLAGS = -d
# Directories
OBJDIR := obj
TGTDIR := target
SRCDIR := src
DMPDIR := dump
# Sources list
SRCS := main.c kernel.c
# Sources location
VPATH := src:../headers
# Objects list
objects = $(notdir $(patsubst %.c,%.o,$(addprefix $(SRCDIR)/,$(SRCS))))
# Objects list with prefix
prefix_objs = $(addprefix $(OBJDIR)/, $(objects))
# Target name
target = main
$(target) : $(prefix_objs)
$(CC) -o $(TGTDIR)/$@ $(prefix_objs)
$(OBJDIR)/%.o: %.c | folders
$(CC) $(CFLAGS) -o $@ $<
$(ODUMP) $(ODFLAGS) $@ > $(DMPDIR)/$@
folders:
mkdir -p $(OBJDIR)
mkdir -p $(TGTDIR)
mkdir -p $(DMPDIR)/$(OBJDIR)
.PHONY: clean
clean:
rm -rf $(OBJDIR) $(TGTDIR) $(DMPDIR) *.o
我希望能够支持至少一层嵌套在 src 目录下的“模块或功能”。我还希望能够不再需要手动构建 # Sources list
SCRS := main.c kernel.c
我的文件夹结构如下
| dump
| obj
| src ----
| kernel.c
| kernel.h
| main.c
| target
| .gitignore
| Makefile
| README.md
不过,我希望能够支持。
| dump
| obj
| src ----
| kernel ----
| kernel.h
| thing.c
| kernel.c
| any.c
| feature1 ----
| ...whatever files
| main.c
| target
| .gitignore
| Makefile
| README.md
如果你看看我的 folders
规则。我必须显式创建 $(DMPDIR)/$(OBJDIR)
因为 $(OBJDIR)/%.o
目标会添加前缀,即使对于转储文件也是如此。如果我开始为我的“功能”添加文件夹,我也需要为这些功能支持 mkdir,因为它将是 obj/kernel/kernal.o
。我还需要列出 SRCS 中的每个文件...现在推荐的使用 VPATH
的方式也已经崩溃,因为它不再只是 src
。似乎添加一项新要求已经增加了扩展此 Makefile 的难度。是否有任何 GNU Make 技巧可以帮助支持嵌套目录?
找到子目录下的所有源文件和sub-subdirectories:
SRCS := $(wildcard $(SRCDIR)/*.c $(SRCDIR)/*/*.c)
为什么要做“对象”/“prefix_objects”这件事?只需制作目标文件:
OBJS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
编写一条规则,从 src
中的源文件在 obj
中创建目标文件。创建目标目录:
$(OBJDIR)/%.o : $(SRCDIR)/%.c
@mkdir -p $(@D) $(DMPDIR)/$(@D)
$(CC) $(CFLAGS) -o $@ $<
$(ODUMP) $(ODFLAGS) $@ > $(DMPDIR)/$@
修复您的 link 行:
$(TGTDIR)/$(target) : $(OBJS)
$(CC) -o $@ $^
如果你真的不想做规则中的mkdir
,你可以使用这个:找到所有包含对象的目录,然后创建它们:
OBJDIRS := $(sort $(dir $(OBJS)))
folders :
mkdir -p $(TGTDIR) $(OBJDIRS) $(addprefix $(DMPDIR)/,$(OBJDIRS))
我有这个 Makefile。
# Variables
CC = gcc
CFLAGS = -Wall -g -c
ODUMP = objdump
ODFLAGS = -d
# Directories
OBJDIR := obj
TGTDIR := target
SRCDIR := src
DMPDIR := dump
# Sources list
SRCS := main.c kernel.c
# Sources location
VPATH := src:../headers
# Objects list
objects = $(notdir $(patsubst %.c,%.o,$(addprefix $(SRCDIR)/,$(SRCS))))
# Objects list with prefix
prefix_objs = $(addprefix $(OBJDIR)/, $(objects))
# Target name
target = main
$(target) : $(prefix_objs)
$(CC) -o $(TGTDIR)/$@ $(prefix_objs)
$(OBJDIR)/%.o: %.c | folders
$(CC) $(CFLAGS) -o $@ $<
$(ODUMP) $(ODFLAGS) $@ > $(DMPDIR)/$@
folders:
mkdir -p $(OBJDIR)
mkdir -p $(TGTDIR)
mkdir -p $(DMPDIR)/$(OBJDIR)
.PHONY: clean
clean:
rm -rf $(OBJDIR) $(TGTDIR) $(DMPDIR) *.o
我希望能够支持至少一层嵌套在 src 目录下的“模块或功能”。我还希望能够不再需要手动构建 # Sources list
SCRS := main.c kernel.c
我的文件夹结构如下
| dump
| obj
| src ----
| kernel.c
| kernel.h
| main.c
| target
| .gitignore
| Makefile
| README.md
不过,我希望能够支持。
| dump
| obj
| src ----
| kernel ----
| kernel.h
| thing.c
| kernel.c
| any.c
| feature1 ----
| ...whatever files
| main.c
| target
| .gitignore
| Makefile
| README.md
如果你看看我的 folders
规则。我必须显式创建 $(DMPDIR)/$(OBJDIR)
因为 $(OBJDIR)/%.o
目标会添加前缀,即使对于转储文件也是如此。如果我开始为我的“功能”添加文件夹,我也需要为这些功能支持 mkdir,因为它将是 obj/kernel/kernal.o
。我还需要列出 SRCS 中的每个文件...现在推荐的使用 VPATH
的方式也已经崩溃,因为它不再只是 src
。似乎添加一项新要求已经增加了扩展此 Makefile 的难度。是否有任何 GNU Make 技巧可以帮助支持嵌套目录?
找到子目录下的所有源文件和sub-subdirectories:
SRCS := $(wildcard $(SRCDIR)/*.c $(SRCDIR)/*/*.c)
为什么要做“对象”/“prefix_objects”这件事?只需制作目标文件:
OBJS := $(patsubst $(SRCDIR)/%.c,$(OBJDIR)/%.o,$(SRCS))
编写一条规则,从 src
中的源文件在 obj
中创建目标文件。创建目标目录:
$(OBJDIR)/%.o : $(SRCDIR)/%.c
@mkdir -p $(@D) $(DMPDIR)/$(@D)
$(CC) $(CFLAGS) -o $@ $<
$(ODUMP) $(ODFLAGS) $@ > $(DMPDIR)/$@
修复您的 link 行:
$(TGTDIR)/$(target) : $(OBJS)
$(CC) -o $@ $^
如果你真的不想做规则中的mkdir
,你可以使用这个:找到所有包含对象的目录,然后创建它们:
OBJDIRS := $(sort $(dir $(OBJS)))
folders :
mkdir -p $(TGTDIR) $(OBJDIRS) $(addprefix $(DMPDIR)/,$(OBJDIRS))