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

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

有帮助吗?

解决方案

不。GNU make 的信号处理已经有很多不足之处。从其信号处理程序中,它调用如下函数 printf 从信号处理程序中调用是不安全的。我见过这会导致问题,例如 .DELETE_ON_ERROR 规则并不总是运行,如果 stderr 被重定向到 stdout.

例如,在 CentOS 7.4 机器上:

  1. 创建以下内容 Makefile:

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

  3. 趁它睡觉的时候,敲一下 控制键-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 仍然存在。

其他提示

目前,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) 因此 cmdline 会覆盖并将选项传递给 submake。

陷阱上:

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

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

代替 <DO CLEANUP HERE> 使用有效的 CMD。

@ kevinf的答案的简化版本,这似乎不够好基本情况:

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

(这个例子是一个原因:docker-compose up不说

  

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

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

请不支持它,但使用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

在“卸载”,将后的“制造”运行结束。这通常是一个令人满意的解决方案,如果您正试图在生成过程中可能发生的,但是,“制造”出不清理正常清理操作。

没有。据我知道有没有这样的功能。

请产生返回代码。至于我现在还记得,则返回0成功,2失败(请查看文档)。因此,这将是够你换做例如一个shell脚本里面?

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top