gpt4 book ai didi

makefile - Makefile 中出现错误后如何清除?

转载 作者:行者123 更新时间:2023-12-02 12:02:03 26 4
gpt4 key购买 nike

foobar 即使失败也可能会创建输出文件,因此在这种情况下我需要将其删除。

我可以做到这一点:

foo: bar baz
foobar $^ -o $@ || (rm -f $@ && exit 1)

但这不会传播 foobar 返回的相同退出代码(然后由 make 输出)。有没有办法在 Makefile 中而不是在 shell 中捕获错误?

最佳答案

万一DELETE_ON_ERROR并没有削减它,你所看到的有点像 tearDown , @After ,或finally在 Java/JUnit 中,您可以执行以下操作:

  1. 使用.ONESHELL:在单个 shell 中执行所有 shell 命令。
  2. 安装 trap对于 EXIT完成清理工作。
  3. 通过设置 errexit 确保 shell 在出现任何错误时退出。当我们这样做时,我们还可以设置 pipefail马上。

例如,假设您要启动一个 docker 容器,进行测试,无论如何停止 docker 容器,但获取测试结果。操作方法如下:

export SHELL:=/bin/bash
export SHELLOPTS:=$(if $(SHELLOPTS),$(SHELLOPTS):)pipefail:errexit

.ONESHELL:

.PHONY: test
test:
function tearDown {
docker stop test-image
}
trap tearDown EXIT
docker run --name test-image …
testStep1…
testStep2…
testStep3…

它是如何工作的

  • export SHELL export 告诉 GNU make 使用 bash作为 shell,其占用空间比默认的 sh 更重但功能更多。
  • export SHELLOPTS设置pipefailerrexit bash 的标志壳。
    • pipefail确保管道的退出状态不是最后一个命令,而是最后一个非零退出状态。所以,false | true将返回1而不是0 .
    • errexit确保命令序列的退出状态不是最后一个命令,而是最后一个非零退出状态,并且后续命令不会被执行。所以,false ; true将返回1而不是0true不会被执行。
  • .ONESHELL:告诉 GNU make 在单个 shell 中运行所有命令。这意味着,您的食谱现在实际上是一个 shell 脚本。 (需要 GNU make 3.82 或更高版本。)
  • function tearDown { docker stop test-image }定义了一个名为 tearDown 的 shell 函数。在此示例中,它将停止 docker 容器。
  • trap tearDown EXIT 是此示例中所有内容中最关键的部分。它告诉为配方调用的 shell 运行 tearDown退出时起作用,即无论命令成功还是失败。

限制

这类似于 finally在 java 。不可能跨多个目标/测试重用。绝对不是@AfterClass这样的/@AfterAlltearDown()/@After/@AfterEach在 JUnit 中。

变得更好

但是如果您需要的话,您可以这样做。比如说,您想在同一个 docker 容器上运行多个测试,并无论如何将其拆除。这类似于 @AfterClass/@AfterAll在 JUnit 中。那么它可能看起来像这样:

export SHELL:=/bin/bash
export SHELLOPTS:=$(if $(SHELLOPTS),$(SHELLOPTS):)pipefail:errexit

.ONESHELL:

.PHONY: start
start:
docker run --name test-image …

.PHONY: stop
stop:
docker stop test-image

.PHONY: test
test: start
function tearDown {
$(MAKE) stop
}
trap tearDown EXIT
$(MAKE) -k testImpl

.PHONY: testImpl
testImpl: testCase1 testCase2 testCase3

.PHONY: testCase1
testCase1:


.PHONY: testCase2
testCase2:


.PHONY: testCase3
testCase3:

现在将运行所有测试,即使第一个测试失败,也会在所有测试完成后进行清理,并在任何测试失败时报告错误。

免责声明:这需要 .ONESHELL GNU make 的功能,在 GNU make 3.82 中引入。截至本次编辑,GNU make 的当前版本是 GNU make 4.2.1,Mac OS X 仍然附带 GNU make 3.81。

关于makefile - Makefile 中出现错误后如何清除?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28597794/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com