Проблема с вашим Makefile в том, что он экранирует (
и )
, что заставляет оболочку интерпретировать их буквально.
Вторая проблема,
/bin/sh: -c: line 0: syntax error near unexpected token `('
, вызванаmake
с использованием sh
для выполнения команд, а не bash
.
Синтаксис с подстановочными знаками !(...)
(и extglob
) поддерживается только bash, но не sh.
Youможет вызвать bash
явно:
@bash -c 'cd ${ADIR}/exe; shopt -s extglob; rm -rf !(BDIR)'
Но это тоже не сработает, потому что extglob
не вступит в силу, пока не будет прочитана следующая строка ввода, поэтому !( )
по-прежнему выбрасываетсинтаксическая ошибка.
Нам нужен способ запуска многострочной команды с использованием одного вызова оболочки.К сожалению, make
делает это излишне сложным.
Одно из возможных решений:
SHELL = /bin/bash
...
@bash -c $$'cd ${ADIR}/exe; shopt -s extglob\nrm -rf !(BDIR)'
Это говорит make
использовать bash
для выполнения всех рецептов (не /bin/sh
).Затем мы снова запускаем bash
вручную, но используя $'...'
, чтобы заключить в строку команды.Это позволяет нам писать \n
для встраивания буквального перевода строки, что заставляет extglob
/ !( ... )
работать.
Нам нужно удвоить $$
, чтобы экранировать $
для make
, поэтому $'...'
становится $$'...'
.
Я не очень доволен этим решением.