Когда я бегу
export PATH := mypath
$(error $(shell echo "$${PATH}"))
кажется, мой PATH не меняется при звонке на shell.
Почему это так и как мне изменить вызовы PATH на shell?





Это с помощью GNU make? Есть давний GNU делает запрос функции, чтобы учитывать экспортированные переменные с помощью $(shell …). Это вообще не относится к PATH, оно влияет (или не влияет) на все export переменные.
Согласно источникам GNU make, это сложно реализовать:
/* Using a target environment for 'shell' loses in cases like:
export var = $(shell echo foobie)
bad := $(var)
because target_environment hits a loop trying to expand $(var) to put it
in the environment. This is even more confusing when 'var' was not
explicitly exported, but just appeared in the calling environment.
See Savannah bug #10593.
envp = target_environment (NULL);
*/
Я не понимаю, почему это не имеет смысла. Переменная может быть чем-то вроде export TARGET = $@, чтобы заставить переменную окружения $TARGET быть установлена на целевое имя, или что-то в этом роде. В любом случае, чтобы делать то, что вы хотите, вы должны включить настройку внутри вызова оболочки: $(shell PATH=$(PATH); run my command)
@MadScientist: Хорошо, если я это сделаю export PATH = $(shell curl example.com)$(info $(shell foo ...))$(info $(shell bar ...)), сколько запросов я должен получить example.com? Один? два? три...? Вам не нужно находиться внутри правила, чтобы вызвать $(shell ...), это допустимо во время разбора Makefile (и, кстати, для этого оно мне и нужно).
Э... что? Вы пытаетесь установить для PATH значение, возвращаемое запуском curl example.com? Я не понимаю вашего комментария, и я думаю, что вы не поняли мой. У вас есть $(error $(shell echo $$PATH)). Я говорю, что если вы хотите, чтобы сценарий оболочки имел вашу настройку PATH, вы должны включить его в сценарий; например, вместо этого напишите это как $(error $(shell PATH=$(PATH); echo $$PATH)) (да, я понимаю, что эхо — это не то, что вы хотите сделать: замените его любой командой, которую вы хотите запустить).
Решение простое: никогда не используйте $(shell) или export.
Переменные среды должны быть частью рецепта, который в них нуждается.
Для $(shell) вызовов, которые должны заполнить переменную makefile, которую вы можете использовать вместо этого.
$(shell) всегда выполняется, либо при анализе make-файла, либо при расширении рекурсивно расширяемой переменной.$(shell) может сделать жизнь инженеров DevOp живой ч...PATH := mypath
Makefile.variables:
@PATH=$(PATH) echo "This my path '$${PATH}'"
echo >$@ "MY_DYNAMIC_CONTENT := abcd"
include Makefile.variables
$(info MY_DYNAMIC_CONTENT '$(MY_DYNAMIC_CONTENT)')
Пример запуска:
$ make
MY_DYNAMIC_CONTENT ''
This my path 'mypath'
echo >Makefile.variables "MY_DYNAMIC_CONTENT := abcd"
MY_DYNAMIC_CONTENT 'abcd'
make: 'Makefile.variables' is up to date.
Я согласен, что $(shell) злоупотребляют :-). Да, есть места, где это правильно, но их очень мало. Я обычно воспринимаю это как запах, после удаления make-файл обычно улучшается.
Уф... Я боялся этого. Спасибо. +1 Как бы то ни было, я думаю, что даже разрешение
exportс расширенной задержкой переменной не имеет абсолютно никакого смысла, но кто я такой, чтобы судить GNU...