Как сделать сбой прерывания команды $ (shell) Make - PullRequest
20 голосов
/ 22 октября 2008

У меня есть Makefile, который запускается с запуска инструмента перед применением правил сборки (которые этот инструмент пишет для меня). Если этот инструмент, представляющий собой скрипт Python, завершает работу с ненулевым кодом состояния, я хочу, чтобы GNU Make сразу же остановилась и не продолжила сборку программы.

В настоящее время я делаю что-то вроде этого (верхний уровень, то есть столбец 1):

$(info Generating build rules...)
$(shell python collect_sources.py)
include BuildRules.mk

Но это не останавливает make, если collect_sources.py выходит с кодом состояния 1. Это также фиксирует стандартный вывод collect_sources.py, но не выводит его на печать, поэтому у меня такое ощущение, что я смотрю неправильно направление.

Если это вообще возможно, решение должно работать даже тогда, когда простая оболочка MS-DOS является стандартной системной оболочкой.

Есть предложения?

Ответы [ 5 ]

6 голосов
/ 22 октября 2008

Возможно, есть лучший способ, но я попробовал следующее, и оно работает:

$(if $(shell if your_command; then echo ok; fi), , $(error your_command failed))

Здесь я предположил, что your_command не дает никакого вывода, но не должно быть трудно обойти эту ситуацию.

Редактировать: Чтобы заставить его работать с оболочкой Windows по умолчанию (и, возможно, с любой подходящей оболочкой), вы можете написать your_command && echo ok вместо if в функции shell. Я не думаю, что это возможно для (более старых) оболочек DOS. Для них вы, вероятно, захотите адаптировать your_command или написать скрипт-обертку, чтобы печатать что-либо при ошибке (или успехе).

4 голосов
/ 23 октября 2008

Хорошо, вот мое собственное решение, которое, к сожалению, не основано на коде состояния скрипта collect_sources.py, но которое работает для меня (TM) и позволяет мне увидеть любой вывод, который генерирует скрипт:

SHELL_OUTPUT := $(shell python collect_sources.py 2>&1)
ifeq ($(filter error: [Errno %],$(SHELL_OUTPUT)),)
  $(info $(SHELL_OUTPUT))
else
  $(error $(SHELL_OUTPUT))
endif

Сценарий написан так, что любая ошибка приводит к выводу, начинающемуся с "collect_sources: error:". Кроме того, если python не может найти или выполнить данный скрипт, он выводит сообщение об ошибке, содержащее сообщение "[Errno 2]" или подобное. Так что этот маленький кусочек кода просто захватывает выходные данные (перенаправляет stderr на stdout) и ищет сообщения об ошибках. Если ничего не найдено, он просто использует $(info) для вывода на печать, в противном случае он использует $(error), что эффективно делает Make stop.

Обратите внимание, что отступ в ifeq ... endif делается с пробелами. Если используются вкладки, Make думает, что вы пытаетесь вызвать команду, и жалуется на это.

4 голосов
/ 22 октября 2008

Для создания BuildRules.mk:

вы должны использовать обычную цель
BuildRules.mk: collect_sources.py
        python $< >$@

include BuildRules.mk

Это стандартная уловка для автоматического создания зависимостей.

0 голосов
/ 22 апреля 2018

Крепление https://stackoverflow.com/a/226974/192373

.PHONY: BuildRules.mk

BuildRules.mk: collect_sources.py
        echo Generating build rules...)
        python $< >$@
        $(MAKE) -f BuildRules.mk
0 голосов
/ 22 октября 2008

Убедитесь, что вы не запускаете make / gmake с опцией -k.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...