【问题标题】:GNU Make -- Append to a variable all targets matching a patternGNU Make -- 将所有匹配模式的目标附加到变量
【发布时间】:2013-08-13 00:05:43
【问题描述】:

在开始之前,我要提一下,在这种情况下我没有使用 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 ...) 调用返回的结果。)

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

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

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

我肯定还在学习 GNU Make,所以我很可能会遗漏一些相当明显的东西。如果我只是说这一切都错了,请告诉我。

谢谢!

【问题讨论】:

  • 那么像$(patsubst $(SRC_DIR)%,$(DEST_DIR)%,$(wildcard $(SRC_DIR)*)
  • 这是$(addprefix $(DEST_DIR),$(notdir $(wildcard $(SRC_DIR)*))) 的一种稍微简单的方法,但它并不能解决我的问题。 $(wildcard $(SRC_DIR)*) 不会捕获 $(SRC_DIR) 中尚不存在但是现有规则的目标并且可以构建的目录。所以,你的建议仍然不会导致make all 运行cp -r src/a/ build/a/。只有cp -r src/b/ build/b/cp -r src/c build/c

标签: makefile gnu-make


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    • 1970-01-01
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多