Проблема и решение
Я сам столкнулся с той же проблемой. Я нашел способ обойти это, но это определенно не идеально.
Как описано, проблема сводится к тому, когда выполняется команда $(shell)
. Он выполняется, когда оцениваются переменные make-файла, то есть до того, как любая из целей была решена или обработана. Чтобы обойти это, вы можете отключить команду $(shell)
для отдельного вызова make-файла. Чтобы запутаться, я просто создал «скрытую» цель для всей моей работы по созданию постфайла в одном и том же файле и сделал рекурсивный вызов make для моего же make-файла. Результат выглядит примерно так:
override MY_MAKEFILE:=$(MAKEFILE_LIST)
override MY_MAKE_INVOCATION_CMD_LINE:=$(MAKE) -C $(CURDIR) $(if $(MY_MAKEFILE),-f $(MY_MAKEFILE),) --no-print-directory
all: minify_css.php
@echo "Compiling CSS"
@$(MY_MAKE_INVOCATION_CMD_LINE) all_hid
minify_css.php:
<create the minify_css.php file here>
all_hid:
@$(MY_MAKE_INVOCATION_CMD_LINE) print_css_hid CSS_OUTPUT=$(shell php minify_css.php )
print_css_hid :
echo $(CSS_OUTPUT)
Объяснение
Команды переопределения
Первая строка этой команды принудительно устанавливает переменную, которая не может быть переопределена из командной строки для сбора имени make-файла. Первая строка ДОЛЖНА называться абсолютной первой строкой в вашем make-файле, поскольку включение других make-файлов может изменить это, и оно не работает изнутри включенных make-файлов. Следует отметить тот факт, что это будет пустым, если вы не указали make-файл в командной строке, что должно означать, что он может быть вызван таким же образом, когда вызывается из make-файла.
Вторая строка просто создает вызов make-файла, устанавливая некоторые параметры по умолчанию, такие как изменение текущего каталога, из которого была вызвана командная строка make-файла, и включающего только спецификацию make-файла для использования, если он был включен в исходный файл. звоните.
Обратите внимание, что эти первые две строки в настоящее время реализованы в моей системе сборки, поэтому они действительно работают для нескольких вложенных рекурсивных вызовов одного и того же файла сборки.
Рекурсивный вызов
Следующие две строки являются важными, отвечающими на ваш исходный запрос. Чтобы продемонстрировать создание файла, а не просто использование возврата команды оболочки, я притворился, что вашему файлу также необходимо создать файл minify_css.php
. Когда я делаю рекурсивный вызов make-файла для цели all_hid
, я знаю, что цель all
оценивается. Это означает, что зависимость minify_css.php
уже обработана, поэтому я могу гарантировать, что она уже существует, что позволяет оценивать команду $(shell php minify_css.php)
при первом рекурсивном обращении к make-файлу и работать с созданным файлом. Следующим шагом было собрать значение CSS_OUTPUT
и передать его в другой рекурсивный вызов. Чтобы сделать это, я снова вызвал make-файл рекурсивно из уже рекурсивного вызова и передал его в командной строке. Помните, что во время вызова make-файла в под-марках доступны только те переменные, которые вы явно экспортировали, поэтому мы не можем просто установить его, а затем сделать рекурсивный вызов на следующей строке, он должен фактически передаваться как часть команды -линия. В рекурсивном make-файле следующего уровня, когда мы вызываем цель print_css_hid
, переменная будет установлена в командной строке и может использоваться.
Подкомпоненты
В этом случае вы на самом деле рекурсивно вызываете свой собственный make-файл, поэтому нужно учитывать, что все остальные переменные установлены неправильно. К счастью, этого не происходит. Любые значения командной строки для параметров, передаваемых исходной командной строке, автоматически передаются при каждом вызове make, вызываемом из файла. Поскольку единственными источниками ввода, которые могут повлиять на построение ваших переменных в make-файле, является содержимое каталогов, с которыми вы работаете, параметры командной строки, каталог, из которого был вызван make-файл, и параметры в самом make-файле, у вас просто есть чтобы убедиться, что вы не делаете что-то вроде случайного включения вновь созданного файла в список «источников» во время вложенных вызовов, и вы можете гарантировать, что среда будет настроена так же.