【问题标题】:Define order without imposing dependency in GNU Make在 GNU Make 中定义顺序而不强加依赖
【发布时间】:2021-01-01 21:21:14
【问题描述】:

我希望虚假的 clean 目标始终在 build 目标之前执行,但没有别的(比如 build 目标不会触发 clean)。

我知道不依赖 GNU Make 语言的解决方案:

  • 需要订购时按顺序启动它们:
make clean
make build
  • 将顺序执行编码为所需的配方:
.PHONY: install
install:
    $(MAKE) clean
    $(MAKE) build

上述“解决方法”受非泛型影响。我必须记住不要运行make clean build

我的问题是关于 GNU Make 语言的表达能力是否可以在不强加依赖的情况下定义顺序

其他构建系统有可选的依赖声明服从顺序,如 Gradle 的mustRunAfter

【问题讨论】:

  • 听起来你在找order only prerequisites
  • @G.M.不,order-only 强加了硬依赖,我只需要 order。当您不关心时间戳时,仅订购适用于目录。恐怕在 GNU Make 中不强加依赖就不可能表达顺序。可能.NOTPARALLEL 有什么黑客行为,谁知道呢……
  • 没有比您提供的更好的方法了。事实上,即使有这样的事情,它也不能按照你建议的方式工作:make 使用 depth-first 搜索目标,所以即使有办法说“如果两个目标都需要要构建,这个必须首先出现”,您必须将这种关系放在 所有 目标(所有 .o 文件等)上,而不仅仅是放在最顶层 构建目标。
  • 您能帮我们解释一下吗?您要解决的实际情况是什么?
  • @MadScientist 您可以将clean 目标动态添加到.EXTRA_PREREQS 来做到这一点,不是吗?

标签: makefile gnu-make


【解决方案1】:

实际上有一种方法可以做我认为你想做的事情,但请注意我上面关于深度优先顺序的警告。

您的问题并不完全清楚,但我想您想说的是,如果用户在命令行上同时要求cleanbuild,请确保在build 之前先执行clean

你可以这样做:

build: $(filter clean,$(MAKECMDGOALS))

这将导致 build 依赖于 clean IFF clean 被指定为要构建的命令行目标之一。

但是请注意我上面的评论:如果您在启用并行性的情况下调用 make 这将是不够的,因为它不会意识到所有目标文件等。还必须等待 clean 完成。为了使这真正万无一失,您必须将此先决条件添加到 EVERY 目标。

【讨论】:

  • 是的,并行化破坏了一切......似乎 Make 是一个文件依赖引擎,而不是一个通用/表达性任务依赖管理引擎。
  • 如果你的意思是,make 没有任何分组功能,那么这是真的。 makefile 中的每个单独的目标都被认为是一个单独的元素,没有办法创建一个目标“组”,然后用一个声明声明整个组的先决条件。如果您想要一组目标的先决条件,则必须在每个目标上单独声明该先决条件。或者,使用 make 的递归调用为您提供一些“分组”。
【解决方案2】:

我必须记住不要运行 make clean build!

您可以测试MAKECMDGOALS 变量是否存在cleanbuild,然后如果它们都存在则抛出错误:

ifeq (clean, $(filter clean, $(MAKECMDGOALS)))
  ifeq (build, $(filter build, $(MAKECMDGOALS)))
    $(error Cannot have clean and build goals at the same time)
  endif  
endif

【讨论】:

  • 昨天解决问题时,我独立编写了大部分精确的代码:hg.defun.work/dot-emacs/file/tip/Makefile 而不是ifeq something,我使用ifneq ''(非空检查)来减少重复。它表明 GNU Make 的用户志同道合))
猜你喜欢
  • 2023-02-07
  • 2015-05-09
  • 1970-01-01
  • 2010-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多