簡體   English   中英

makefile:在每個配方中重新分配變量以存儲步驟名稱

[英]makefile: Reassign variable in each recipie to store the step name

我有一個makefile,它在失敗時運行規則。 我在下面寫了一個小例子:

temp = "start"

run:
    make run_all || make run_failed

run_all: step1
run_all: step2
run_all: step3
run_all: ;

step1:
    echo temp = "step1"

step2:
    echo temp = "step2"
    $(error fail test)

step3:
    echo temp = "step3"

run_failed:
    @echo "failed on step ${temp}"

我用$(error ...)命令強制此小示例在步驟2中失敗。 我的問題是我想在每個步驟中設置變量temp。 但是我不知道該怎么做。

如果在每個步驟中刪除temp =之前的“ echo”,我只會得到一個shell錯誤(找不到temp)。

如何設置變量,以便打印出makefile失敗的步驟?

注意:您不應該在食譜中使用make 使用$(MAKE)代替。 您可以在GNU make手冊中找到許多很好的理由。

使變量和外殼變量不同。 當你寫:

temp = "start"

它是make語法,而temp是一個make變量。 當你寫:

step1:
    temp = "step1"

temp是一個shell變量,您會遇到語法錯誤,因為shell變量的分配是temp="step1"=周圍沒有空格)。

但這還不是全部。 配方的每一行都由單獨的外殼程序運行(除非特殊目標.ONESHELL出現在makefile中),並且不同的配方不能由同一外殼程序實例運行(無論.ONESHELL )。 因此,您不能期望run_failed規則的配方可以訪問與step2配方的一行指定的相同的shell變量temp

無論如何,當配方失敗時,它會告訴您哪里出了問題,包括什么規則失敗了。 如果這還不夠,最好的選擇是為每個配方配備一條錯誤消息:

$ cat fail
#!/usr/bin/env bash
exit 1

$ cat Makefile
run: step1 step2 step3

step1 step3:
    @echo "doing $@" || echo "$@ failed"

step2:
    @./fail || echo "$@ failed"

$ make step1
doing step1

$ make run
doing step1
step2 failed
doing step3

如果由於某種原因無法做到這一點,您將必須:

  1. 將故障信息從一個配方( step2 )傳遞到另一個( run ),
  2. 將失敗信息從一個子make調用( run-all )傳遞給另一個sub-make( run_failed )。

除非您使用日志文件並告訴make不要以並行模式運行,否則所有這些操作將非常困難。

$ cat Makefile
.NOTPARALLEL:

FAILED  := failed.txt

run:
    @{ rm -f $(FAILED) && $(MAKE) run_all; } || $(MAKE) run_failed

run_all: step1 step2 step3

step1 step3:
    @echo "doing $@" || { echo "$@ failed" >> $(FAILED) && exit 1; }

step2:
    @./fail || { echo "$@ failed" >> $(FAILED) && exit 1; }

run_failed:
    @cat $(FAILED)

$ make --no-print-directory
doing step1
Makefile:14: recipe for target 'step2' failed
make[1]: *** [step2] Error 1
step2 failed

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM