获取Makefile中源代码结构

3
我正在进行一个 C 项目的开发,我决定将源代码和它所生成的目标文件放在不同的目录中。根目录大致如下:
SmartC  ▶ tree -L 1
.
├── built
├── doc
├── Makefile
├── README.md
├── src
├── tests
└── trash

因此,在src和built目录中,我放置了两个其他的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

“built”指的是同样的结构,但它旨在存储编译生成的所有对象。
我的问题是关于我的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)                               

您可能对这个问题感兴趣。 - Diego
谢谢。我会查一下通配符的相关信息,之前并不知道这个! - user4713908
@Diego。谢谢你,兄弟。通配符太棒了。 - user4713908
1
不要把答案放在问题中,而是将其作为自己问题的答案单独发布并接受它。 - dbush
不错的 @dbush。谢谢! - user4713908
显示剩余2条评论
1个回答

1

编辑【已解决】

我想要做以下事情。

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

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目录中的文件,但它也可用于其他目的,例如将SRCDIR镜像到OBJDIR中,因为STRUCTURE仅存储内部子目录。在执行完清理操作后,它非常有用:
clean:
    -rm -r $(OBJDIR)/*

注意:编译规则只有在每个*.c文件都有对应的*.h文件(名称相同)时才能正常工作。


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