18

我想知道是否有一种方法可以trap在 GNU中实现make,类似于内置的BASH

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

4

6 回答 6

22

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

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

.PHONY: internal-target external-target

external-target:
  bash -c "trap 'trap - SIGINT SIGTERM ERR; <DO CLEANUP HERE>; exit 1' SIGINT SIGTERM ERR; $(MAKE) internal-target"

internal-target:
  echo "doing stuff here"

这会捕获中断、终止和任何非零退出代码。

注意$(MAKE)so cmdline 覆盖和 make 选项被传递给 submake。

陷阱上:

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

DELETE_ON_ERROR 不适用于目录,因此这是清理之后的关键mktemp -d,例如

替换<DO CLEANUP HERE>为有效的 CMD。

于 2015-09-25T18:33:56.237 回答
17

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

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

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

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

但它不像rm停止的容器那样docker run --rm,所以你仍然可以看到它们docker ps -a。)

于 2016-09-02T21:15:15.217 回答
4

不。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

Vim/制作打印

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仍然存在。

于 2009-07-22T14:54:27.657 回答
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”退出时未正常清理的操作,这通常是一个令人满意的解决方案。

于 2010-04-13T18:32:24.977 回答
1

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

于 2009-06-10T07:31:19.147 回答
1

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

于 2009-06-10T07:38:48.523 回答