我正在尝试编写一个通用的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
目标运行,而不考虑
GNUmake
会在构建指定目标或默认目标之前自动尝试重建生成文件。其他make
实现不一定要这样做。GNUmake
手册包含关于您的特定问题的以下建议:
如果您知道一个或多个生成文件无法重新生成,并且你想阻止make对它们执行隐式规则搜索,也许出于效率的原因,您可以使用防止隐式规则查找执行此操作。例如,您可以编写一个以makefile为目标的显式规则,以及一个空配方[…]
空配方方法是添加这样的规则:
Makefile: ;
由于生成文件中存在该规则(文件名为Makefile
(,当make
查找用于重建Makefile
的规则时,它将选择该显式空规则,而不是匹配任何通配符规则。然而,这样写会更健壮一点:
$(MAKEFILE_LIST): ;
MAKEFILE_LIST
变量包含make
读取的所有生成文件的名称,因此即使您将include
指令添加到生成文件中,或者使用-f
命令行选项从不同的目录或通过不同的名称访问它,它也会覆盖您。