2013-09-12 1 views
0

Я пытаюсь лениво оценить вариант конфигурации. Я хочу выпустить ошибку Make, только если эта переменная фактически используется (заменена).Определение рекурсивно расширенной переменной с тем же именем, что и переменная среды

Рассмотрим следующий Makefile:

VAR = $(error "E") 

NFS_DIR = NFS_DIR is $(VAR) 

T = $(NFS_DIR) is 1 

all: 
    echo Test 

Если я запускаю его с моей средой (которая имеет /srv/nfs значение), вывод следующий:

➜ ~ make 
echo Test 
Makefile:3: *** "E". Stop. 

поэтому определение актов рекурсивных как простое определение ,

Если очистить окружающую среду, она работает, как ожидалось:

➜ ~ env -i make 
echo Test 
Test 

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

Так вопросы:

  1. Почему наблюдаемое поведение?
  2. Как реализовать желаемое поведение?

Обновление: уточнить - я не хочу использовать ?=, поскольку параметры - это параметры конфигурации. Я хочу, чтобы они были строго из Makefile, а не из среды.

ответ

1

Любая переменная, находящаяся в среде при запуске make, будет экспортирована в среду любого запуска команды make (как часть рецепта и т. Д.). Чтобы make отправил значение переменной в команду , сначала нужно расширить его. Он не действует как просто расширенная переменная. Просто запуск команды приводит к расширению.

Это своего рода неприятный побочный эффект, но я не уверен, что есть что-то, что можно сделать напрямую: это поведение традиционно и подпадает под действие POSIX, и множество make-файлов будет ломаться, если оно будет изменено.

У вас есть два выбора, о которых я могу думать. Первый заключается в использовании команды unexport make, чтобы сказать make, чтобы не отправлять эту переменную в среду команды.

Во-вторых, чтобы изменить имя переменной в make на то, что не является допустимой переменной окружения: make будет экспортировать только переменные, имена которых являются законными переменными оболочки (содержат только буквенно-цифровые плюс _). Так что, используя это имя, как VAR-local, вместо VAR это сделало бы.

+0

Извините, я не вижу, какая команда вызывает расширение '$ NFS_DIR'. Я не использую его ни в одной команде –

+0

Я не сказал, что он использовался в команде. Я сказал, что это в вашей среде. Если вы запускаете «env | grep NFS_DIR» из приглашения командной оболочки, видите ли вы? Поэтому при запуске make он импортирует это значение в переменную make и помещает ее для экспорта в команды, выполняющие прогоны. Затем вы устанавливаете его в make-файле, но он по-прежнему помечен как экспортированный. Поэтому, когда make хочет запустить команду, сначала нужно получить среду для этой команды, и она расширяет все экспортированные переменные make. Вот когда вы это видите. Измените имя переменной make на то, что не является допустимой переменной окружения. – MadScientist

+0

Вы сказали, что передача переменной в команду вызывает расширение переменной. О какой команде вы говорили? –

Смежные вопросы