我有一个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"的定义。目标的配方存在于我无法编辑的另一个文件中。我必须"包括"它就像拾取必要的,无关的陈述一样。答案 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总是重新分析并重新评估所有内容),但我认为不可能避免重新评估。