我正在尝试从git克隆存储库并在本地进行编译。 Makefile的相关部分粘贴在下面。
BUILDDIR = $(PWD)/build
# rest of the Makefile
...
all: release
release: $(BUILDDIR)/buildr/Makedir $(BUILDDIR)/depqbf
$(BUILDDIR)/buildr/Makedir:
mkdir -p $(BUILDDIR)/buildr
$(BUILDDIR)/depqbf:
cd $(BUILDDIR); rm -rf depqbf; git clone git@github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
问题是,如果我使用 rm -rf depqbf ,则每次运行make都会发生编译过程。
如果我将其删除,然后再次执行制作
致命:目标路径'depqbf'已经存在,并且不是空目录。
是否可以仅在目录不存在的情况下进行克隆和编译。
答案 0 :(得分:2)
每次运行make都会进行编译过程
您的食谱目标
$(BUILDDIR)/depqbf/depqbf:
cd $(BUILDDIR); rm -rf depqbf; git clone git@github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
是文件$(BUILDDIR)/depqbf/depqbf
。您是在告诉Make,如果目标$(BUILDDIR)/depqbf/depqbf
不存在,那么Make是通过运行以下命令来建立目标:
cd $(BUILDDIR); rm -rf depqbf; git clone git@github.com:lonsing/depqbf.git
cd $(BUILDDIR)/depqbf;./compile.sh
但是这些命令从不创建名为$(BUILDDIR)/depqbf/depqbf
的文件。他们
永远不要成为目标。
因此,每次Make考虑目标时,都会通过以下方式决定必须制造的目标: 运行这些命令。
如果您删除rm -rf depqbf
,则在Make尝试将目标作为目标时
fatal: destination path 'depqbf' already exists and is not an empty directory.
自然,因为您不能克隆到现有的非空目录中。这是 与配方始终在运行的事实无关。它一直在运行 因为它永远不会成为目标。
您的其他食谱:
$(BUILDDIR)/buildr/Makedir:
mkdir -p $(BUILDDIR)/buildr
同样,永远不会成为目标。命令:
mkdir -p $(BUILDDIR)/buildr
将永远不会创建文件$(BUILDDIR)/buildr/Makedir
。我看不出目的
这个食谱,所以我假设它只是应该创建文件
$(BUILDDIR)/buildr/Makedir
(由于某种原因不存在)。
然后,当且仅当目标不存在时,此makefile才会尝试建立目标:
制作文件
BUILDDIR := $(PWD)/build
.PHONY: all release
all: release
release: $(BUILDDIR)/buildr/Makedir $(BUILDDIR)/depqbf
$(BUILDDIR)/buildr/Makedir: | $(BUILDDIR)/buildr
touch $@
$(BUILDDIR)/depqbf: | $(BUILDDIR)
cd $(dir $@); git clone git@github.com:lonsing/depqbf.git
cd $@; ./compile.sh
$(BUILDDIR) $(BUILDDIR)/buildr:
mkdir -p $@
The GNU Make manual中的有用参考:-