如何在GNU make中捕获错误和中断?

时间:2009-06-10 07:06:54

标签: makefile signals gnu-make bash-trap

我想知道是否有办法在GNU trap中实现make,类似于内置于BASH的内容?

如果用户按CTRL-C,或者make本身失败(非零退出),我想调用特定目标或宏。

6 个答案:

答案 0 :(得分:9)

目前,GNU make还没有原生支持。

但是有一个可靠的解决方法:

$(MAKE)

这可以捕获中断,终止和任何非零退出代码。

请注意mktemp -d所以cmdline覆盖并将选项传递给submake。

关于陷阱:

  • 清除陷阱处理程序(带 - )
  • 进行清理
  • 以非零退出状态退出,因此构建自动化工具会报告失败的构建。

DELETE_ON_ERROR不适用于目录,因此这是<DO CLEANUP HERE>后清理的关键,例如

<button id="something"> <i class="fa fa-refresh"></i> Some button text </button> 替换为有效的CMD。

答案 1 :(得分:7)

@ kevinf答案的简化版本,对于基本案例来说似乎已经足够了:

run:
    bash -c "trap 'docker-compose down' EXIT; docker-compose up --build"

(这个例子是有原因的:docker-compose up确实说

  

当   命令退出,所有容器都停止。

rm不会docker run --rm已停止的容器,因此您仍然可以使用docker ps -a看到它们。)

答案 2 :(得分:3)

没有。 GNU make的信号处理已经有很多不足之处。在其信号处理程序中,它调用printf之类的函数,这些函数在信号处理程序中不可安全地调用。我已经看到了这种原因问题,例如.DELETE_ON_ERROR如果将stderr重定向到stdout,则规则并不总是运行。

例如,在CentOS 7.4盒子上:

  1. 创建以下Makefile

    .DELETE_ON_ERROR:
    
    foo:
            touch $@
            sleep 10
    
  2. vim中打开并运行:make

  3. 正在睡觉时,点击 Ctrl - C
  4. Vim / make prints

    Press ENTER or type command to continue
    touch foo
    sleep 10
    ^C
    shell returned 130
    
    Interrupt: Press ENTER or type command to continue
    

    向Make发送了一个中断信号,但foo仍然存在。

答案 3 :(得分:2)

Make不支持它,但使用BASH技巧你可以完成类似的事情。

default: complete

complete: do_mount
        echo "Do something here..."

do_mount:
        mkdir -p "$(MOUNTPOINT)"
        ( while ps -p $$PPID >/dev/null ; do \
                sleep 1 ; \
        done ; \
        unmount "$(MOUNTPOINT)" \
        ) &
        mount "$(MOUNTSOURCE)" "$(MOUNTPOINT)" -o bind

“卸载”将在“make”完成后运行。如果您尝试清理构建期间可能发生的操作但在“make”退出时没有正常清理,这通常是一个令人满意的解决方案。

答案 4 :(得分:1)

没有。据我所知,没有这样的功能。

答案 5 :(得分:1)

make产生返回码。据我现在记得,它成功返回0,失败返回2(请查看文档)。因此,您是否足以将make包装在shell脚本中?例如?