Makefile:避免重新编译克隆的存储库

时间:2019-02-23 01:12:39

标签: makefile directory gnu-make

我正在尝试从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'已经存在,并且不是空目录。

是否可以仅在目录不存在的情况下进行克隆和编译。

1 个答案:

答案 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中的有用参考:-