Прерывание или завершение make
Если make получает фатальный сигнал во время выполнения оболочки, оно может удалить целевой файл, который рецепт должен был обновить. Это делается, если время последней модификации целевого файла изменилось с момента, когда make впервые проверил его.
Цель удаления целевого файла заключается в том, чтобы убедиться, что он пересоздается с нуля, когда make будет запущен повторно. Почему это так? Предположим, вы нажимаете Ctrl-c во время работы компилятора, и он начал записывать объектный файл foo.o. Ctrl-c убивает компилятор, что приводит к неполному файлу, время последней модификации которого новее, чем исходного файла foo.c. Но make также получает сигнал Ctrl-c и удаляет этот неполный файл. Если make не сделает этого, следующий вызов make посчитает, что foo.o не требует обновления, что приведет к странному сообщению об ошибке от компоновщика при попытке связать объектный файл, половина которого отсутствует.
Вы можете предотвратить удаление целевого файла таким образом, сделав специальную цель .PRECIOUS зависимой от него. Перед пересозданием целевого файла make проверяет, появляется ли он в предпосылках .PRECIOUS, и на основе этого решает, следует ли удалить цель, если произойдет сигнал. Некоторые причины, по которым вы можете это сделать, заключаются в том, что цель обновляется атомарно, или она существует только для записи времени модификации (ее содержимое не имеет значения), или она должна существовать всегда, чтобы предотвратить другие виды проблем.
Хотя make делает все возможное, чтобы произвести очистку, существуют определенные ситуации, в которых очистка невозможна. Например, make может быть убит неперехватываемым сигналом. Или один из программ make может быть убит или аварийно завершен, оставив позади обновленный, но поврежденный целевой файл: make не поймет, что для очистки цели требуется эта неудача. Или сам make может столкнуться с ошибкой и аварийно завершиться.
По этим причинам лучше всего писать защитные рецепты, которые не оставят поврежденных целей даже в случае сбоя. Чаще всего эти рецепты создают временные файлы вместо непосредственного обновления целевого файла, а затем переименовывают временный файл в имя конечной цели. Некоторые компиляторы уже ведут себя таким образом, поэтому вам не нужно писать защитный рецепт.
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/make/manual/html_node/Interrupts.html