1 1.5 rillig # $NetBSD: cmd-interrupt.mk,v 1.5 2024/07/13 15:10:06 rillig Exp $ 2 1.1 rillig # 3 1.1 rillig # Tests for interrupting a command. 4 1.1 rillig # 5 1.1 rillig # If a command is interrupted (usually by the user, here by itself), the 6 1.1 rillig # target is removed. This is to avoid having an unfinished target that 7 1.1 rillig # would be newer than all of its sources and would therefore not be 8 1.1 rillig # tried again in the next run. 9 1.1 rillig # 10 1.2 rillig # This happens for ordinary targets as well as for .PHONY targets, even 11 1.2 rillig # though the .PHONY targets usually do not correspond to a file. 12 1.2 rillig # 13 1.2 rillig # To protect the target from being removed, the target has to be marked with 14 1.2 rillig # the special source .PRECIOUS. These targets need to ensure for themselves 15 1.2 rillig # that interrupting them does not leave an inconsistent state behind. 16 1.2 rillig # 17 1.2 rillig # See also: 18 1.2 rillig # CompatDeleteTarget 19 1.1 rillig 20 1.5 rillig all: clean-before 21 1.5 rillig all: interrupt-ordinary 22 1.5 rillig all: interrupt-phony 23 1.5 rillig all: interrupt-precious 24 1.5 rillig all: interrupt-compat 25 1.5 rillig all: clean-after 26 1.1 rillig 27 1.2 rillig clean-before clean-after: .PHONY 28 1.5 rillig @rm -f cmd-interrupt-ordinary cmd-interrupt-phony 29 1.5 rillig @rm -f cmd-interrupt-precious cmd-interrupt-compat 30 1.1 rillig 31 1.3 rillig interrupt-ordinary: 32 1.2 rillig @${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-ordinary || true 33 1.2 rillig # The ././ is necessary to work around the file cache. 34 1.2 rillig @echo ${.TARGET}: ${exists(././cmd-interrupt-ordinary) :? error : ok } 35 1.2 rillig 36 1.2 rillig interrupt-phony: .PHONY 37 1.2 rillig @${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-phony || true 38 1.2 rillig # The ././ is necessary to work around the file cache. 39 1.4 sjg @echo ${.TARGET}: ${exists(././cmd-interrupt-phony) :? ok : error } 40 1.2 rillig 41 1.2 rillig interrupt-precious: .PRECIOUS 42 1.2 rillig @${.MAKE} ${MAKEFLAGS} -f ${MAKEFILE} cmd-interrupt-precious || true 43 1.2 rillig # The ././ is necessary to work around the file cache. 44 1.2 rillig @echo ${.TARGET}: ${exists(././cmd-interrupt-precious) :? ok : error } 45 1.1 rillig 46 1.5 rillig interrupt-compat: 47 1.5 rillig @${MAKE} -f ${MAKEFILE} cmd-interrupt-compat || true 48 1.5 rillig @echo ${.TARGET} ${exists(././cmd-interrupt-compat) :? expected-fail : unexpected-ok } 49 1.5 rillig 50 1.1 rillig cmd-interrupt-ordinary: 51 1.1 rillig > ${.TARGET} 52 1.2 rillig @kill -INT ${.MAKE.PID} 53 1.1 rillig 54 1.1 rillig cmd-interrupt-phony: .PHONY 55 1.1 rillig > ${.TARGET} 56 1.2 rillig @kill -INT ${.MAKE.PID} 57 1.2 rillig 58 1.2 rillig cmd-interrupt-precious: .PRECIOUS 59 1.2 rillig > ${.TARGET} 60 1.2 rillig @kill -INT ${.MAKE.PID} 61 1.5 rillig 62 1.5 rillig # When the make process (and not the process group) is interrupted in compat 63 1.5 rillig # mode, it first tries to interrupt the process group of the currently running 64 1.5 rillig # child command, but that fails since there is no such process group, rather 65 1.5 rillig # the child command runs in the same process group as make itself. The child 66 1.5 rillig # command then continues, and after sleeping a bit creates the target file. 67 1.5 rillig cmd-interrupt-compat: 68 1.5 rillig @kill -INT ${.MAKE.PID} && sleep 1 && > ${.TARGET} 69