Можно ли использовать аргументы оболочки внутри функции makefile? например
mywords:=hello there neighbour
myrecipe:
for ((i = 0 ; i < 3 ; i++)); do \
this_word=$(word $${i}, $(mywords)); \
done
За исключением того, что myrecipe
выдает ошибку non-numeric first argument to 'word' function: '${i}'. Stop
Нет, любые аргументы оболочки расширяются после выполнения функции makefile. Однако то, что вы представляете, - это функция оболочки. Вы можете использовать строку с for this_word in $mywords; do \
, и у вас будет переменная оболочки this_word
, установленная для каждой итерации.
Помните, что делать сначала расширяет весь рецепт (да, это все строки рецепта), прежде чем что-либо делать с оболочкой. Только после этого полного расширения делать ищет отдельные строки рецептов, запуская каждую из них по очереди.
Таким образом, делать ведет себя разумно, когда у вас есть макрос, который расширяется более чем на одну строку.
Это также намекает на то, что вы должны использовать функциональность делать везде, где это возможно.
mywords := hello there neighbour
define mkcommand
echo $1
something $1
endef
myrecipe:
$(foreach _,${mywords},$(call mkcommand,$_))
Теперь, когда вы просите делать построить мой рецепт, делать видит что-то вроде:
myrecipe:
echo hello
something hello
echo there
something there
⋮
ИМХО, это почти всегда ошибка, если вы пишете циклы оболочки в make-файле.
Я согласен с вашим описанием работы make
, но не обязательно с вашей рекомендацией. Если кто-то заинтересован в написании переносимых (то есть не специфичных для GNU) make-файлов, то сам make
иногда не предоставляет то, что вам нужно. Более того, даже когда нацеливается GNU make
, я считаю, что гораздо понятнее зарезервировать make
функции для кода высшего уровня и использовать в рецептах только шелл-код. Можно избежать зацикливания вообще, но если цикл должен появиться в рецепте, я бы предпочел, чтобы он был выражен на языке оболочки.
Я с уважением не согласен. Делая это в делать, по моему опыту, неизменно получаются более чистые файлы сборки, охватывают больше угловых случаев и их легче рефакторить. По общему признанию, я хорошо знаю делать. Например, большинство циклов не проверяют ненулевые коды выхода должным образом. Параллельные сборки также начинают работать, и в настоящее время у всех нас более одного процессора (ваш make-файл не работает, если он не работает при параллельной сборке). Циклы оболочки обычно являются признаком того, что автор не знаком с делать. Аналогичные проблемы возникают при чрезмерном использовании $(shell … )
. YMMV применяется, конечно.
Вы пытаетесь использовать функцию Делать внутри функции ракушка, и нет, это не сработает. Это просто исследование, или вы действительно пытаетесь что-то сделать?