简体   繁体   English

如何重新启动GNU make(不引起错误)

[英]How to restart GNU make (without causing an error)

I need to restart the make process in case some intermediate target gets (re)build. 我需要重新启动make过程,以防某些中间目标被(重新)构建。

This is the case when a PIP requirements file gets (re)compiled, because the checksum of the resulting file is used in the path to the virtualenv that is used in the Makefile. 编译(重新)PIP需求文件时就是这种情况,因为生成文件的校验和用于Makefile中使用的virtualenv的路径中。 If the requirements file gets updated, the same $(MAKECMDGOALS) should get rebuild from the beginning. 如果需求文件得到更新,则应从头开始重建相同的$(MAKECMDGOALS)

I have come up with the following, but this requires to make the outer/inital make process fail ( exit 1 ), which I would like to avoid. 我提出了以下建议,但这需要使外部/初始make过程失败( exit 1 ),这是我想避免的。

foo:
    echo "foo"

    # Need to restart make if this has been used as intermediate target.
    if [ $(MAKECMDGOALS) != "$@" ]; then \
        echo "Restarting make..."; \
        touch $@; \
        $(MAKE) $(MAKECMDGOALS); \
        exit 1; \
    fi

bar: foo
    echo "bar"

.PHONY: bar

A makefile on the lines below might fit the bill. 下面几行中的makefile文件可能适合您。 bar and baz are goals that will be sabotaged if they intermediately make foo (aka tricky goals). barbaz是目标,如果它们中间产生foo (又是棘手的目标),就会被破坏。 There's no restarting involved: instead, it is arranged that the tricky goals are only made by a fresh $(MAKE) , after the top make has ensured foo is up-to-date. 不需要重新启动 :相反,安排在最重要的目标确保foo是最新的之后, 由新的$(MAKE)来确定棘手的目标。

.phony: all clean

tricky = bar baz

all:
    $(MAKE) $(tricky)

foo:
    echo "foo"
    touch $@

clean:
    rm -f foo

ifndef simple
tricky_goals = $(filter $(tricky),$(MAKECMDGOALS))
ifneq ($(tricky_goals),)
$(tricky_goals): foo
    $(MAKE) simple=y $@
endif

else # ifndef simple
# All tricky goals follow...

bar: foo
    echo "bar"

baz: foo
    echo "baz"

endif # ifndef simple

The behaviour depends on whether the variable simple is defined, which by default it is not. 行为取决于是否定义了simple变量,默认情况下未定义。

If simple is defined then the goals, whatever they are, will be made the obvious way - the way they'd be made if it weren't for the foo pitfall. 如果定义了simple目标,那么无论目标是什么,都会以显而易见的方式制定目标-如果不是为了foo陷阱而制定目标。

If simple is undefined then tricky_goals becomes the tricky members $(MAKECMDGOALS) . 如果未定义simple ,则tricky_goals会成为棘手的成员$(MAKECMDGOALS) If $(tricky_goals) is empty there is nothing tricky to do. 如果$(tricky_goals)为空,则没有棘手的事情。 Otherwise the target list $(tricky_goals) becomes dependent on foo . 否则目标列表$(tricky_goals)依赖于foo So if foo is out-of-date, it gets made now. 因此,如果foo是过时的,则可以立即生成。 Finally each tricky goal is made by calling a simple $(MAKE) for it, in which foo will be up-todate. 最后,每个棘手的目标都是通过调用一个简单的$(MAKE)来实现的,其中foo将是最新的。 Any non-tricky goals will be made the simple way. 任何简单的目标都将变得简单。

I've included all and clean goals for completeness. 为了完整性,我列出了all clean目标。 Note that all needs coded to go the tricky way. 请注意, all需求都经过编码才能完成。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM