Makefile 从列表生成所有源文件的通用目标/规则,将对象输出到一个目录

Makefile 从列表生成所有源文件的通用目标/规则,将对象输出到一个目录,makefile,gnu-make,Makefile,Gnu Make,我试图在我的makefile中创建一个通用目标,它将从混合目录构建源代码,并将对象文件输出到单个目录 我们有一个混合在不同目录中的源结构(如上所述,下面只是一个示例) 但是我希望所有的对象文件都输出到目录。/objs(与'b'相同的目录级别) 为此,我尝试了以下方法 OBJS = $(addprefix objs/, $(notdir $(SRCS:.c=.o))) $(OBJS): %.o : $(filter %/$(basename $(notdir %)).c, $(SRCS))

我试图在我的makefile中创建一个通用目标,它将从混合目录构建源代码,并将对象文件输出到单个目录

我们有一个混合在不同目录中的源结构(如上所述,下面只是一个示例)

但是我希望所有的对象文件都输出到目录。/objs(与'b'相同的目录级别)

为此,我尝试了以下方法

OBJS  = $(addprefix objs/, $(notdir $(SRCS:.c=.o)))

$(OBJS): %.o : $(filter %/$(basename $(notdir %)).c, $(SRCS))
    echo "dependencies: $^" # shows up empty
    $(CC) $(filter %/$(basename $(notdir $@)).c, $(SRCS)) -o $@ # This works and finds the proper source file
    $(CC) $^, $(SRCS)) -o $@ # I would like to use this, but as I said the dependencies show up blank
然而,这有一个奇怪的问题,我不明白问题在哪里

在依赖项中,它与任何内容都不匹配,但在配方中,它确实正确匹配

现在是奇怪的部分(至少对我来说)。如果我尝试通过硬编码其中一个路径进行测试,那么它将匹配该路径中的所有文件

$(OBJS): %.o : $(filter ../a/b/$(basename $(notdir %)).c, $(SRCS)) # matches for all files in "../a/b" directory
但是使用SECONDEXPANSION和硬编码目录,它可以工作

.SECONDEXPANSION:
$(OBJS): %.o : $$(filter ../a/b/$$(basename $$(notdir %)).c, $(SRCS))
而且不使用SECONDEXPANSION和硬编码源文件名也可以工作

$(OBJS): %.o : $(filter %source1.c, $(SRCS)) # Hardcoding source1.c works for source1.c
但似乎出于某种原因,我不能将两者结合起来做我想做的事情。我尝试过第二次扩展的东西(虽然我不确定为什么我会在这种情况下需要它),但也无法让任何东西以这种方式工作

我试图避免手动单独声明每个文件的目标,即。 objs/source1.o:../a/b/source1.c

因为我们的现实世界的例子有大量的文件,所以最好少维护一些。我觉得我很快就要得到它了


我正在将Cygwin与GNU Make 4.0一起使用。

在谷歌搜索了几次之后,我终于在这里找到了解决方案:

我仍然不知道为什么我需要使用SECONDEXPANSION($$-ness),但实际上没有它它是不行的。但基本上我需要为“%”符号创建一个变量。为我做以下工作

SRCS = ../a/b/source1.c \
       b/source2.c \
       ../c/source3.c

OBJS  = $(addprefix objs/, $(notdir $(SRCS:.c=.o)))

.SECONDEXPANSION:
PERCENT = %

$(OBJS): %.o : $$(filter $$(PERCENT)/$$(notdir %).c, $(SRCS))
    $(CC) $< -o $@
SRCS=../a/b/source1.c\
b/source2.c\
../c/source3.c
OBJS=$(addprefix OBJS/,$(notdir$(SRCS:.c=.o)))
.第二次扩展:
百分比=%
$(OBJS):%.o:$$(过滤器$$(百分比)/$$(notdir%).c,$(SRCS))
$(CC)$<-o$@
现在,它将构建source1.c、source2.c和source3.c,并将对象文件输出到objs/目录中


我在问题中没有提到,但我一直都知道,只有当所有源文件都有唯一的文件名时,这才有效。但我们同意这一限制(显然)。

您应该将您的编辑移到答案中并接受它,即使它是您自己的,也请接受。另外,不要修改问题标题以表明其状态,因为它与标记是多余的。我按照您的建议修改了标题,但我在8小时内无法添加自己的答案(直到今晚11点),并且它告诉我在此之前只需编辑原始问题。但当我可以的时候,我会把答案作为答案加上。谢谢你。这是我的第一篇帖子(如果你没有注意到的话)。
SRCS = ../a/b/source1.c \
       b/source2.c \
       ../c/source3.c

OBJS  = $(addprefix objs/, $(notdir $(SRCS:.c=.o)))

.SECONDEXPANSION:
PERCENT = %

$(OBJS): %.o : $$(filter $$(PERCENT)/$$(notdir %).c, $(SRCS))
    $(CC) $< -o $@