Подтвердить что ты не робот

Как получить статус выхода команды оболочки, используемой в GNU Makefile?

У меня есть правило make файла, пока я выполняю инструмент Linux. Мне нужно проверить состояние завершения команды инструмента, и если эта команда не удалась, make должен быть прерван.

Я пытался проверить с помощью $?, $$?\$? и т.д. в make файле. Но они дают мне синтаксическую ошибку при запуске makefile.

Как правильно это сделать?

Вот соответствующее правило в Makefile

    mycommand \
    if [ $$? -ne 0 ]; \
    then \
        echo "mycommand failed"; \
        false; \
    fi
4b9b3361

Ответ 1

В файле makefile -:

mycommand || (echo "mycommand failed $$?"; exit 1)

Каждая строка в действии makefile вызывает новую оболочку - ошибка должна быть проверена в строке действия, где команда не удалась.

Если mycommand завершает работу, логические ветки к выражению echo затем завершаются.

Ответ 2

Вот несколько других подходов:


shell & .SHELLSTATUS

some_recipe:
    @echo $(shell echo 'doing stuff'; exit 123)
    @echo 'command exited with $(.SHELLSTATUS)'
    @exit $(.SHELLSTATUS)

Выход:

$ make some_recipe

doing stuff
command exited with 123      
make: *** [Makefile:4: some_recipe] Error 123

У него есть предостережение о том, что выходные данные команды shell не передаются в потоковом режиме, поэтому вы просто получите дамп stdout после его завершения.


$?

some_recipe:
    @echo 'doing stuff'; exit 123;\
    EXIT_CODE=$$?;\
    echo "command exited with $$EXIT_CODE";\
    exit $$EXIT_CODE

Выход:

$ make some_recipe

doing stuff                  
command exited with 123      
make: *** [Makefile:2: some_recipe] Error 123

Это по сути одна строка команд оболочки, разделенных точкой с запятой.  Исключать любые новые строки, которые вы хотите, раздражает, и легко забыть точки с запятой, но я использовал этот подход исключительно из-за оговорки, упомянутой выше.

Ответ 3

Если вы хотите, чтобы make был прерван, если инструмент выходит с ненулевым статусом, make уже сделает это по умолчанию.

Пример Makefile:

a: b
    @echo making [email protected]
b:
    @echo making [email protected]
    @false
    @echo already failed

. Это то, что происходит с моим make:

$ make
making b
make: *** [Makefile:6: b] Error 1

Убедитесь, что частично или полностью созданные цели удалены в случае неудачи. Например, этот

a: b
    @gena $+ > [email protected]
b:
    @genb > [email protected]

неверно: если при первой попытке genb не удастся, он, вероятно, оставит неправильный b, который при второй попытке make будет считать правильным. Поэтому вам нужно сделать что-то вроде

a: b
    @gena $+ > [email protected] || { rm [email protected]; exit 1; }
b:
    @genb > [email protected]