GNU Makefile эквивалент командной оболочки TRAP для краткой идентификации сбоя сборки при выходе

Критерии: Makefile - это GNU Make Makefile. Меня не интересуют makepp, qmake, cmake и т.д. Они все хороши (особенно cmake), но это для работы и на работе мы используем GNU Make. Оптимальным решением является чистое решение Makefile, а не оболочка script, которая анализирует для вас.

Я также не хочу делать решение "продолжить сбой" - если он сломан, он сломан и нуждается в исправлении.

Ситуация такова: у меня есть makefile, который строит несколько каталогов параллельно - если один из них терпит неудачу, конечно, вся сборка выходит из строя, но только до тех пор, пока все запуски не завершится (или сбой). Это означает, что причина, по которой действительно произошел сбой, похоронили где-то произвольно далеко от конца вывода make.

Вот пример того, что у меня есть:

all: $(SUBDIRS)

SUBDIRS = \
  apple \
  orange \
  banana \
  pineapple \
  lemon \
  watermelon \
  grapefruit

$(SUBDIRS):
  cd [email protected] && $(MAKE) $(MFLAGS) 2>&1 | sed -e "s/^/$(notdir $(@)): /g"

Если я запустил make -j 5 и "оранжевый", произойдет неудача - я бы хотел увидеть таблицу, подобную этой в конце процесса make

  apple     - passed
  orange    - FAILED
  banana    - passed
  pineapple - passed
  lemon     - passed

Я подумал, что у меня есть && эхо "прошло" > .result || echo "FAILED" > .result, но для выполнения команды TRAP или __onexit() необходимо выполнить некоторую команду очистки, чтобы печатать на них при выходе.

В любом файле makefile ninjas есть решение для чистого make файла для этого?

un-edit - мое решение на самом деле не работало так, как я надеялся.. STYMIED!

Ответ 1

Если вы хотите сделать прервать при первом провале, немедленно прекратите работу и убейте все задания на полете, а не дожидаясь их завершения, вам нужно исправить GNU Сделать так http://lists.gnu.org/archive/html/bug-make/2009-01/msg00035.html

Затем вам нужно установить ловушку для каждой оболочки, которая вызывает вызовы (а также set -o pipefail, если вы используете канал), как описано в этом сообщении http://lists.gnu.org/archive/html/help-make/2009-02/msg00011.html

В двух словах:

target1:
    trap 'kill $$(jobs -p)'; command && something || something-else
target2:
    trap 'kill $$(jobs -p)'; set -o pipefail; command | sed '...'

Ответ 2

Единственный способ, который я вижу, - это самоисполнение с суб-make:

all : subdirs

subdirs : 
    $(MAKE) -f $(lastword $(MAKEFILE_LIST)) subdirs-recursive || cat log

subdirs-recursive: $(SUBDIRS)