如果另一个配方在Makefile

时间:2018-03-21 04:29:57

标签: makefile gnu-make target recipe

我有一个Makefile,如下:

all: build

build:
ifdef USE_CACHE
        @printf ":sigh: failure  :(\nThis should have been skipped by cache's recipe.\n"
endif
        @printf "Building ...\n"
    touch $@

ifdef USE_CACHE
build: cache

cache:
        @printf "Installing cache ...\n"
    touch $@
        @printf "Trying to skip build because cache satisfied it ... \n"
    touch build
endif

默认"构建"会产生:

$ rm build cache; make
Building ...
touch build

这是直截了当的预期,但如果定义了USE_CACHE参数,则仍会执行构建配方,如下所示:

$ rm build cache; make USE_CACHE=1
Installing cache ...
touch cache
Trying to skip build because cache satisfied it ...
touch build
:sigh: failure  :(
This should have been skipped by cache's recipe.
Building ...
touch build

我理解这种情况正在发生,因为在解析所有文件之后以及在执行任何配方之前建立了Make的构建图,因此在我的&#34之后重新评估所需的构建配方已经太晚了;高速缓存"食谱被执行。

但是,我想要"缓存"目标的配方另外满足"构建"目标,跳过" build"假设已定义USE_CACHE目标,则执行配方。

有没有办法实现这一点,或者在GNU Make中是不可能的?

顺便说一句,我的真实情况比上面的玩具复杂得多。为了这个问题,请假设" build"的定义。目标的配方存在于我无法编辑的另一个文件中。我必须"包括"它就像拾取必要的,无关的陈述一样。

1 个答案:

答案 0 :(得分:0)

我最终使用了类似下面的内容,这会触发重新读取Make文件并重新评估依赖项:

    .PHONY: all clean

    all: build
            @true

    clean:
            rm -f build cache sync

    build:
    ifdef USE_CACHE
            @printf ":sigh: failure  :(\nThis should have been skipped by cache's recipe.\n"
    endif
            @printf "Building ...\n"
            touch $@

    ifdef USE_CACHE

    include sync

    cache:
            @printf "Installing cache ...\n"
            touch $@
            @printf "Trying to skip build because cache satisfied it ... \n"
            touch build

    sync: cache
            @printf "Creating cache synchronization file ...\n"
            @printf '$$(info Loading build cache ...  If this works, it should be the last line printed ...)\n' >| $@

    endif

进行重新分析会产生明显的性能影响(如果创建包含文件的目标,GNU Make总是重新分析并重新评估所有内容),但我认为不可能避免重新评估。