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

时间:2014-07-25 15:32:16

标签: makefile gnu-make

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

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

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

但我想将所有目标文件输出到目录./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

但似乎我无法结合两个人做我想要的东西。我已经尝试了secondexpansion的东西(thoguht我不确定为什么我会在这种情况下需要它)并且永远不会得到任何工作方式。

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

因为我们的真实世界示例包含大量文件,所以维护较少会很好。我觉得我非常接近它。

我正在使用Cygwin和GNU Make 4.0。

1 个答案:

答案 0 :(得分:3)

经过几次google搜索后,我终于遇到了解决方法:

http://lists.gnu.org/archive/html/help-make/2010-09/msg00062.html

我仍然不知道为什么我需要使用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 $@

现在构建source1.c,source2.c和source3.c,并将目标文件输出到objs /目录中。

我在我的问题中没有提到但我一直都知道,只有你拥有所有源文件的唯一文件名才能使用。但是我们可以接受这个限制(显然)。