Как изменить PATH для команд Makefile $(shell...)?

Когда я бегу

export PATH := mypath
$(error $(shell echo "$${PATH}"))

кажется, мой PATH не меняется при звонке на shell.

Почему это так и как мне изменить вызовы PATH на shell?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
439
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Это с помощью 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);
  */

Уф... Я боялся этого. Спасибо. +1 Как бы то ни было, я думаю, что даже разрешение export с расширенной задержкой переменной не имеет абсолютно никакого смысла, но кто я такой, чтобы судить GNU...

user541686 16.02.2019 20:41

Я не понимаю, почему это не имеет смысла. Переменная может быть чем-то вроде export TARGET = $@, чтобы заставить переменную окружения $TARGET быть установлена ​​на целевое имя, или что-то в этом роде. В любом случае, чтобы делать то, что вы хотите, вы должны включить настройку внутри вызова оболочки: $(shell PATH=$(PATH); run my command)

MadScientist 16.02.2019 23:12

@MadScientist: Хорошо, если я это сделаю export PATH = $(shell curl example.com)$(info $(shell foo ...))$(info $(shell bar ...)), сколько запросов я должен получить example.com? Один? два? три...? Вам не нужно находиться внутри правила, чтобы вызвать $(shell ...), это допустимо во время разбора Makefile (и, кстати, для этого оно мне и нужно).

user541686 17.02.2019 03:45

Э... что? Вы пытаетесь установить для PATH значение, возвращаемое запуском curl example.com? Я не понимаю вашего комментария, и я думаю, что вы не поняли мой. У вас есть $(error $(shell echo $$PATH)). Я говорю, что если вы хотите, чтобы сценарий оболочки имел вашу настройку PATH, вы должны включить его в сценарий; например, вместо этого напишите это как $(error $(shell PATH=$(PATH); echo $$PATH)) (да, я понимаю, что эхо — это не то, что вы хотите сделать: замените его любой командой, которую вы хотите запустить).

MadScientist 17.02.2019 15:23

Решение простое: никогда не используйте $(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-файл обычно улучшается.

bobbogo 20.02.2019 12:14

Другие вопросы по теме