0

在开始之前,我会提到在这种情况下我没有使用 GNU Make 来构建 C/C++ 项目。

生成文件:

DEST_DIR = build/
SRC_DIR = src/

$(SRC_DIR)a/ : $(SOMETHING_ELSE)
    $(DO_SOMETHING_TO_GENERATE_A_DIR)

$(DEST_DIR)% : $(SRC_DIR)%
    cp -r $^ $@

ALL_DEPS += <SOMETHING>

... more code which appends to ALL_DEPS ...

.PHONY: all

all : $(ALL_DEPS)

我有一些文件不是通过 $(SRC_DIR) 中的 Make 规则生成的。(为了这个例子,假设有一个目录 $(SRC_DIR)b/ 和一个文件 $(SRC_DIR)c 。)

我想将代表 $(DEST_DIR) 中的文件或目录的所有目标附加到 ALL_DEPS,以便“make all”将运行所有可用的 $(DEST_DIR)% 规则。

我想做这样的事情:

ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(wildcard $(SRC_DIR)*)))

但是,当然,这并没有捕捉到任何尚未制作的东西。(即它不会将 $(DEST_DIR)a/ 附加到列表中,因为在评估 $(wildcard ...) 调用并且 shell 不将其包含在$(wildcard ...) 调用返回的结果。)

因此,我需要一个查找与模式匹配的所有目标的函数,而不是查找与模式匹配的所有(当前存在的)文件的函数。然后,我可以做这样的事情:

ALL_DEPS += $(addprefix $(DEST_DIR),$(notdir $(targetwildcard $(SRC_DIR)*)))

如果重要的话,我已经将大部分 GNU Make 代码拆分为多个文件,并包含在“主”Makefile 中。ALL_DEPS 变量被附加到这些文件中的任何一个要添加的文件中。这是为了保持构建过程模块化,而不是将其全部放在一个怪物 Makefile 中。

我肯定还在学习 GNU Make,所以我不太可能错过一些相当明显的东西。如果我只是把这一切都搞错了,请告诉我。

谢谢!

4

1 回答 1

2

根本不可能做你想做的事;你试图让 make 识别出不存在的东西。

这就是通配符通常不好的部分原因(另一个原因是您最终可能会包含您不打算包含的内容)。正确的做法是显式创建source文件列表 ( ls -1 | sed -e 's/\(.*\)/sources+=\1/' > dir.mk) 并在该列表上执行patsubst转换。

如果您有作为构建的一部分生成的其他文件,那么您可以将它们附加到该列表中,并且将按照您的预期找到它们的规则。

于 2014-02-02T02:52:34.767 回答