如何在 GNU make 中捕获错误和中断?
题
我想知道是否有办法实现 trap
在 GNU 中 make
, ,类似于内置的 BASH
?
如果用户按下 CTRL-C
, , 或者如果 make
本身失败(非零退出),我想调用特定的目标或宏。
解决方案
不。GNU make 的信号处理已经有很多不足之处。从其信号处理程序中,它调用如下函数 printf
从信号处理程序中调用是不安全的。我见过这会导致问题,例如 .DELETE_ON_ERROR
规则并不总是运行,如果 stderr
被重定向到 stdout
.
例如,在 CentOS 7.4 机器上:
创建以下内容
Makefile
:.DELETE_ON_ERROR: foo: touch $@ sleep 10
打开它在
vim
并运行:make
,- 趁它睡觉的时候,敲一下 控制键-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脚本里面?