在Makefile中获取源代码结构

我正在研究一个C项目,我决定将源代码及其对象放在不同的目录中。 根目录有类似的东西:

SmartC ▶ tree -L 1 . ├── built ├── doc ├── Makefile ├── README.md ├── src ├── tests └── trash 

因此,在src和内置目录中,我将另外两个Makefile用于编译和链接作业。

src目录(我放置源代码的地方)具有以下结构:

 src ├── graph.c ├── graph.h ├── list.c ├── list.h ├── main.c ├── Makefile ├── node.c ├── node.h ├── tree.c ├── tree.h └── types ├── complex.c ├── complex.h ├── matrix.c └── matrix.h 

并且构建具有相同的结构,但它旨在存储由编译产生的所有对象。

我的问题是关于我的src / Makefile:

 BINDIR = ../built/src CC = gcc CFLAGS = -g -Wall -O3 OBJECTS = \ $(BINDIR)/main.o \ $(BINDIR)/node.o \ $(BINDIR)/list.o \ $(BINDIR)/graph.o \ $(BINDIR)/tree.o \ $(BINDIR)/types/complex.o \ $(BINDIR)/types/matrix.o \ compile: $(OBJECTS) $(BINDIR)/%.o: %.c $(CC) -c $< -o $@ $(CFLAGS) 

这个Makefile在src目录中创建源代码的所有对象,并将它们移动到built / src。 但是,每次我创建一个新的源代码文件(* .c)时,我都必须将其对象的名称放在这个makefile中,这样就可以编译它。 我想在src目录中进行自动搜索,并使用此搜索填充“OBJECTS”变量。

有人知道如何实现这一目标吗? 我的意思是,自动搜索特定目录中的源代码?

我甚至接受任何其他策略而不是我正在制作的策略。

===========答案===============

我得到了关于通配符的提示(在评论中)。 所以我做了。 这是我找到的解决方案。

SRC / Makefile文件

 BINDIR = ../built/src CC = gcc CFLAGS = -g -Wall -O3 OBJECTS := $(patsubst %.c,$(BINDIR)/%.o,$(wildcard *.c */*.c)) compile: $(OBJECTS) $(BINDIR)/%.o: %.c $(CC) -c $< -o $@ $(CFLAGS) 

编辑[已解决]

我喜欢做以下事情。

为项目的每个目录创建变量

 SRCDIR = src OBJDIR = obj LIBDIR = lib DOCDIR = doc HDRDIR = include CFLAGS = -g -Wall -O3 

仅递归获取SRCDIR的内部结构

 STRUCTURE := $(shell find $(SRCDIR) -type d) 

获取STRUCTURE变量中的所有文件

 CODEFILES := $(addsuffix /*,$(STRUCTURE)) CODEFILES := $(wildcard $(CODEFILES)) 

仅筛选出特定文件

 # Filter Only Specific Files SRCFILES := $(filter %.c,$(CODEFILES)) HDRFILES := $(filter %.h,$(CODEFILES)) OBJFILES := $(subst $(SRCDIR),$(OBJDIR),$(SRCFILES:%.c=%.o)) # Filter Out Function main for Libraries LIBDEPS := $(filter-out $(OBJDIR)/main.o,$(OBJFILES)) 

现在是创建规则的时候了

 compile: $(OBJFILES) $(OBJDIR)/%.o: $(addprefix $(SRCDIR)/,%.c %.h) $(CC) -c $< -o $@ $(CFLAGS) 

使用这种方法,您可以看到我只使用STRUCTURE变量来获取SRCDIR目录中的文件,但它也可以用于其他目的,例如,一旦STRUCTURE仅存储内部子,则镜像OBJDIR内的SRCDIR。目录。 在清洁操作之后它非常有用,例如:

 clean: -rm -r $(OBJDIR)/* 

注意:编译规则只适用于每个* .c都有相应的* .h文件(具有相同的基本名称,我的意思)。