Мой Makefile очень прост:
all:
[ -f MyFile ] && echo "MyFile exists"
Конечно, строка рецепта начинается с табуляции. Если файл MyFile действительно существует, то все в порядке. Но если этого файла нет в текущем каталоге, я получаю:
Makefile:2: рецепт для цели «все» не выполнен make: *** [все] Ошибка 1
Я могу избавиться от этой ошибки, используя оператор if:
all:
if [ -f MyFile ]; then echo "MyFile exists"; fi
Оба оператора отлично работают в sh и bash вне make. Мне неясно, в чем причина ошибки make при использовании условного оператора. Есть идеи, что происходит?
решение1
[ -f MyFile ] && echo "MyFile exists"
завершается с ненулевым кодом состояния, если MyFile
не существует, тогда как
if [ -f MyFile ]; then echo "MyFile exists"; fi
завершается с успешным (нулевым) кодом статуса, если не MyFile
существуети echo
завершается ошибкой записи.
Make полагается на коды состояния, чтобы определить, были ли команды неудачными, и останавливает выполнение по умолчанию, если какая-либо команда не удалась. Вы можете отключить это для отдельных командных строк, добавив к ним префикс -
, или для всех команд, запустив make -i
или указав специальную .IGNORE
цель. Таким образом
-[ -f MyFile ] && echo "MyFile exists"
Оба варианта позволят Make продолжить работу, но при этом выведут сообщение, если MyFile
объект не существует:
make: [Makefile:14: test] Ошибка 1 (игнорируется)
Шаблон|| true
также будет работать в этом конкретном случае, но он будет игнорировать ошибки в echo
. if condition; then command; fi
не приведет к остановке Make, если condition
равно false, но учтет command
ошибки , тогда как condition && command || true
будет игнорировать все ошибки.