【问题标题】:Makefile % match-anything rule picks up "Makefile" targetMakefile % match-anything 规则选择“Makefile”目标
【发布时间】:2021-04-25 09:45:19
【问题描述】:

我正在尝试编写一个通用的 Makefile 来将源树与某个远程主机同步,通过 ssh 进入它并在那里执行 make,转发任何目标或变量覆盖

到目前为止,我想出了这个:

HOST ?= host
DIR ?= ~/dev

SRC = src

all:

.PHONY: sync
sync:
    rsync -azP --exclude ".*/" --exclude ".*" $(SRC)/ $(HOST):$(DIR)

%: sync
    ssh $(HOST) 'cd $(DIR) && make $@ MAKEFLAGS=$(MAKEFLAGS)'

只要我在% 目标的依赖列表中省略sync,它就可以很好地工作。一旦我重新添加它,Makefile 目标由于某种原因被拾取,导致它通过 ssh 进入远程机器并运行make Makefile,这不是一个有效的目标或预期的行为

为了澄清,我自己并没有将Makefile 指定为目标。我愿意

make
make clean

所有这些都会导致 Makefile 目标运行,而不管

【问题讨论】:

  • 也许将Makefile 添加为显式目标,配方为空且无依赖关系?
  • Make 通常会尝试将 Makefile 构建为目标,以及包含在 makefile 中的任何文件。这可用于在源更改时更新 Makefile,例如保持自动依赖正确。它通常什么都不做,就像它在远程运行 make 命令时会做的那样。
  • 没有sync 假依赖,make 会看到Makefile 存在并且没有依赖,因此不需要重新制作,因此它不会运行配方。但是一旦它有一个虚假的依赖,它似乎总是需要重新制作,因为它的依赖 (sync) 总是重新制作,并且运行配方。您可以像@HolyBlackCat 所说的那样避免这种情况,因为这样可以防止使用模式规则。

标签: makefile gnu-make


【解决方案1】:

GNU make automatically attempts to rebuild the makefile(s) before building the designated targets or default target。其他make 实现不一定这样做。 GNU make 手册包含有关您的特定问题的建议:

如果您知道您的一个或多个 makefile 无法重新制作并且 您想阻止 make 对它们执行隐式规则搜索, 也许出于效率原因,您可以使用任何正常的方法 防止隐式规则查找这样做。例如,你可以写 以生成文件为目标的显式规则和空配方 [...]

空配方方法是添加如下规则:

Makefile: ;

在你的 makefile 中存在该文件(并且文件名是 Makefile),当 make 查找用于重建 Makefile 的规则时,它将选择该明确的空规则而不是 match-anything 通配符规则。但是,这样写会更健壮一些:

$(MAKEFILE_LIST): ;

MAKEFILE_LIST 变量包含 make 读取的所有 makefile 的名称,因此即使您将 include 指令添加到您的 makefile 或者您从不同的目录或通过不同的目录访问它,它也会覆盖您使用-f 命令行选项命名。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多