On Fri, 2021-06-04 at 12:31 +0900, Masahiro Yamada wrote: > GNU Make cleans up partially updated targets if the user interrupts > before the build rules complete. > > If GNU Make does not do this, they will not be updated in the next > run of 'make' because their timestamps are new while the contents are > incomplete. > > This issue was asked in the Linux kernel ML [1], but I can reproduce > it in simple test code. Please see the following case.
It's pretty easy to see what's happening if you use strace. The thing to remember is that when you use ^C you're sending the signal to the entire process group. That means that not only does make get a SIGINT, but also your "cat" program gets a SIGINT, and dies. When the SIGINT signal handler is called in GNU make, it tries to clean up IN THE SIGNAL HANDLER. This is a long-standing problem, since the very first version of GNU make as far as I know: it does all kinds of things in its signal handler which are not really valid in a signal handler context. I have a partial solution to fix it, but it's actually extremely difficult due to the really crappy signal handling model that POSIX provides and my current solution still suffers from race conditions that need to be resolved before it can be used. I haven't had time to get back to this. Anyway: one of the things make will do in its signal handler is try to write error messages to stderr. If you are piping the output of stderr to a program, and that program has died, then writing to it will generate a SIGPIPE. Because the write is inside the SIGINT signal handler, make is no longer catching signals like SIGPIPE, so when it receives that SIGPIPE it will simply exit immediately. A workaround for your situation, until this whole signal handler thing can be resolved, is to ignore SIGINT in the program receiving the piped data so it doesn't die when you hit ^C. This will work for example: $ make 2>&1 | (trap "" 2; cat) echo hello > test.txt sleep 10 ^Cmake: *** Deleting file 'test.txt' make: *** [/tmp/x10.mk:3: test.txt] Interrupt