为什么这个makefile重启/重新分配多次?

时间:2017-04-03 16:50:37

标签: makefile

我想保留以前编译的代码的日志,以便在设置编译选项时保持一致。我设计了以下方案,但它有一种奇怪的行为,我不太完全理解。这是一个重现错误的简化版本:

生成文件:

.DEFAULT_GOAL = final

MKFILES = Makefile Makefile.checks
include Makefile.checks

.PHONY: final
final: info.txt results.txt
    @cat $^

results.txt: $(MKFILES) | .PRELIM
    @echo 'First file with opt=$(opt)' > $@

info.txt: info.src $(MKFILES) | .PRELIM
    @cat $< > $@
    @echo 'Internal record of opt=$(opt)' >> $@

.PHONY: .FORCE
.FORCE:

.PHONY: .PRELIM
.PRELIM: Makefile.log

.PHONY: clean
clean:
    rm -rf *.txt *.log

Makefile.checks:

# SETUPS & CHECKS

opt ?= 0
BUILDSTAT := 0

ifneq ($(MAKECMDGOALS),clean)
ifneq ("$(wildcard Makefile.log)","")

    include Makefile.log
    ifneq ($(opt),$(oldopt))
        $(warning Previously compiled opt = $(oldopt))
        $(warning Currently requested opt = $(opt))
        BUILDSTAT := 1
    endif

endif
endif

# RESOLUTION SECTION
ifneq ($(BUILDSTAT),0)

info.txt: .FORCE
Makefile.log: .FORCE

    $(warning The build is not consistent, a clean make is recomended. )
    ifneq ($(MAKECMDGOALS),anyway)
        $(warning To force compilation, run 'make anyway opt=X' )
        $(error Aborting compilation)
    endif

endif

.PHONY: anyway
anyway: $(.DEFAULT_GOAL)

Makefile.log:
    @echo 'Creating new Makefile.log'
    @echo '########################################' > Makefile.log
    @echo 'oldopt    := $(opt)' >> Makefile.log
    @echo 'BUILDSTAT := $(BUILDSTAT)' >> Makefile.log
    @echo '########################################' >> Makefile.log

Makefile创建日志并检查以前的选项:make后跟make opt=1通过发出警告并停止按预期行事。但是,当我make anyway opt=1时,makefile似乎在实际编译之前多次解析Makefile.checks

Makefile.checks:12: Previously compiled opt = 0
Makefile.checks:13: Currently requested opt = 1
Makefile.checks:26: The build is not consistent, a clean make is recomended. 
Creating new Makefile.log
Makefile.checks:26: The build is not consistent, a clean make is recomended. 
Creating new Makefile.log
(...repeated many times...)
Makefile.checks:26: The build is not consistent, a clean make is recomended. 
Creating new Makefile.log
This is a personal log
Internal record of opt=1
First file with opt=0

怀疑这可能与修改Makefile.log之后Makefile重新解析自身的方式有关,该Makefile.log本身包含在导致整个目标列表重新编译的MKFILES中。我尝试使用-d选项,但它对我帮助不大。这个设计最终变得非常复杂,但我不知道如何简化它,而且我不太了解makefile如何解释我自己发生的事情。

我真的很感谢这个错误的解释。哪个依赖项导致循环以及为什么它最终离开它并继续完成编译?您认为有更好的方法来记录编译选项吗?

编辑:我将在这里添加进一步要求的信息/解释。我修改了一些代码来简化它。

我尝试做的是存储上一次构建中使用的编译选项,以便在重新编译代码的一部分时不混合选项(或者至少要警告这是我和# 39;做的事)。我实现此方法的方法是Makefile.checks:选项是从Makefile.log写入/加载的,BUILDSTAT是一种布尔值来检查是否存在差异并跟踪它在后续构建中。

Makefile.checks首先设置默认值,然后检查日志是否存在并加载&#34; old&#34;分离变量中的选项,然后比较两者以检查差异。如果找到任何一个,它会在此处发出警告,然后再次检查并停止(当您有多个选项时,这种分离更有意义),除非明确要求使用目标anyway忽略它们。在最后一种情况下,日志和文件info.txt(这是存储选项的另一种方式)需要使用最后的构建信息(特别是BUILDSTAT=1)进行更新,以保留构建可能具有的记录a&#34;混合编译&#34;)。

编辑 - &#34;解决方案&#34;:显然,如果不是&#34;强迫&#34;重新编译日志,我使日志本身成为虚假目标(在if内),它可以防止这种行为。我仍然没有发现这种方法有任何缺点,但它确实感觉有点&#34;脏&#34;。

0 个答案:

没有答案