【问题标题】:reevaluate wildcard in make重新评估make中的通配符
【发布时间】:2017-02-01 14:55:56
【问题描述】:

在我的 Makefile 中,我想检查某个文件是否存在,做一些事情,然后再次检查。使用 gnu make,我不能。这是一个简单的例子:

$(info $(wildcard OK))
$(shell touch OK)
$(info $(wildcard OK))

如果我运行一次make,我会看到两个空行。如果我再次运行make,这两行都是OK

我想,也许$(eval) 会让我得到更新的答案。唉,

$(eval $$(info $$(wildcard OK)))

产生相同的答案,好像make 在开始评估其他命令之前有某种方法可以预测所有通配符计算。

我需要这个来满足 Android NDK 执行的检查:我必须即时生成 prebuilt shared library

【问题讨论】:

  • 这在 4.2.1 中运行良好 :-)
  • 查看了 git 日志,但找不到确凿证据。在 3.81 中失败。适用于 3.82、4.0、4.1、4.2 和 4.2.1。是的,我知道,要多出去走走。

标签: android-ndk gnu-make


【解决方案1】:

这不起作用,因为为了性能,make 维护目录内容的内部缓存。目前该缓存仅在 make 运行规则时更新:然后定义规则创建的目标将被添加到缓存中。在您的情况下,make 无法知道文件系统已被修改,因此它不会更新缓存。

你必须使用shell,而不是wildcard; shell 不知道 make 的内部缓存:

$(info $(wildcard OK))
$(shell touch OK)
$(info $(shell [ -f OK ] && echo OK))

显然这是一个虚假的示例,但我确信您的真实代码与此有很大不同。

唯一的另一种选择是将您需要运行的命令变成规则。但同样,由于这个问题与您真正想要做的事情几乎没有关系,我无法提出一个可行的解决方案。

【讨论】:

  • 我的目标是利用 Android NDK 中的 prebuilt_shared_library.mk 脚本作为我必须自己构建的库。 NDK 框架使用 $(wildcard) 函数来验证库文件是否存在,但我想自己构建它。
  • 看起来,缓存是每个目录的;它是在第一次为此目录评估 $(wildcard) 函数时创建的。这可能足以让我产生一种解决方法。
  • 我将与您的示例完全相反:首先,使用$(shell) 而不涉及缓存;然后,我会让 NDK 运行通配符,但我的逻辑将有机会准备 post-truth。
  • 只要您确定在执行此操作之前没有任何东西会尝试缓存目录,这将起作用。我觉得有点摇摇晃晃,但是...
  • 是的,这是一个真正的问题。但就我而言,NDK 将在其中查找文件的目录是在我明确指出之前它没有机会偶然发现的目录。
猜你喜欢
  • 2019-05-14
  • 2020-10-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-19
  • 1970-01-01
  • 2019-06-23
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多