prereqisites的searchpath,如vpath,但仅适用于某些模式规则

时间:2014-12-28 14:34:53

标签: makefile gnu-make

我正在尝试在一个make实例中构建多个可执行文件,如下所述 Recursive Make Considered Harmful。 该论文的论点适用于我的项目,因为我的一些源文件已生成,并进入多个可执行文件。

每个可执行文件的目标文件都进入不同的目录,因为它们使用不同的预处理程序标志进行编译。

如何为每个可执行文件指定单独的vpath设置,以便在不同目录中具有重复文件名的源文件进入我希望它们到达的可执行文件中?

在规则之前设置vpath以构建一个可执行文件的目标文件,然后删除它(通过不提供任何目录)不具有所需的效果。显然,最后一个设置用于所有规则。

我目前看到的解决方案:

  • 重命名源文件名以使用唯一名称,以便我可以使用全局vpath设置
  • 而不是vpath,对每个源目录使用单独的规则,前缀模式中的源目录(*)
  • 递归制作,在每个vpath实例中使用单独的make设置,并以某种方式处理由此产生的问题。
  • 使用与make不同的内容。

是否有更好的解决方案,或者您更喜欢上述哪一种?

(*)具有单独规则的解决方案如下所示:

build/$(PROGRAM)/%.o: %.c
    $(COMPILE_RECIPE)

build/$(PROGRAM)/%.o: $($(PROGRAM)_SOURCE_DIR)/%.c
    $(COMPILE_RECIPE)

确定我当前的项目,但如果在可执行文件的源路径中有多个目录不同,那么会变得很难看

修改:测试@Etan的建议,当先决条件仅出现在模式规则($^)中时,显示y/y.c为空 - 这仅适用于直接给出每个依赖关系,如x/x.c

.PHONY: all

all: build/x.o build/y.o

build/x.o: x/x.c
# the following rule is ignored:
build/%.o: y/%.c
# because there is a matching pattern rule with a recipe:
build/%.o:
    @echo \"$@\" from \"$^\"
    @touch $@

文件x/x.cy/y.c和目录build存在。

输出:

"build/x.o" from "x/x.c"
"build/y.o" from ""

使用GNU Make 3.82.90

进行测试

1 个答案:

答案 0 :(得分:2)

首先,使用VPATH或vpath来查找派生文件(由make构建的文件)...它包括"生成的源文件" (如果它们是由make生成的,而不是在以某种方式调用make之前)。 VPATH / vpath只能用于查找源文件(不是由make构建的文件)。有关详细信息,请参阅How not to use VPATH

其次,vpath是全局设置,而不是每个目标设置。每当make想要找到先决条件并且先决条件不存在时,#34;通常",make将使用vpath设置来查找它。在vpath中没有设施说"对于这个目标使用这些vpath设置,对于该目标使用那些"。在理想的世界中,您可以将VPATH设置为特定于目标的变量,但这不起作用。

有多种方法可以根据目标生成先决条件:您可能会在metaprogramming in make上找到一些有用的建议。

最后,您提供的关于$^的makefile示例不正确:

# the following rule is ignored:
build/%.o: y/%.c
# because there is a matching pattern rule with a recipe:
build/%.o:
        @echo \"$@\" from \"$^\"
        @touch $@

你不能在没有任何食谱的情况下指定一个模式规则,并且可以使用#34;添加"某些其他现有模式规则的先决条件模式。它适用于显式规则,为目标添加更多先决条件,但仅指定不含配方的模式规则{。{3}}。

因此,$^的{​​{1}}为空,因为模式规则中没有定义任何先决条件,并且您没有像build/y.o那样为build/y.o定义任何明确的先决条件{1}}。

ETA:对元编程的引用是建议您可以使用它来制作第二个选项,即我会使用的选项,更少打字和更容易维护。选择您喜欢的方法并自动生成各种模式规则。这可能被称为"第五个选项"。

除此之外,你建议的四个中的任何一个都没问题,并且我没有其他选择,你知道我不知道。