Экранирование переменных make-файла (для внутреннего использования в make-файле)
Можно ли "безопасно" развернуть переменную в make-файле, избегая всех символов, которые make-файл считает специальными?
В качестве примера предположим, что переменная используется в качестве цели:
${external_chaos}:
dd if=/dev/zero of=${external_chaos}
(драма в примере преднамеренная)
Если external_chaos
содержит пробелы, ;
, #
, :
, ,
или другие важные для makefile символы, тогда все правило будет испорчено.
В качестве решения я представляю некоторую встроенную функцию Make, которая должна делать это, например: ${escape external_chaos}
(мнимая роскошь).
${value external_chaos}
не делает этого
1 ответ
В общем, вам не удастся (без большой боли, если вообще) использовать цели с пробелами в них. Просто брось это. Если вы должны поддерживать цели с пробелами в них, тогда выберите другой инструмент сборки, а не make.
Краткий ответ - нет, встроенной функции нет. Вы можете написать один, используя subst
; например, в мишенях вы должны бежать по крайней мере %
а также :
:
TESCAPE = $(subst :,\:,$(subst %,\%,$1))
С другой стороны, обратите внимание, что ;
а также ,
не являются особенными по целям, поэтому вам не нужно вообще их избегать; на самом деле, если вы это сделаете, вы получите неправильные результаты, потому что \
останется в имени цели: обратная косая черта удаляется только в том случае, если в ней указан специальный символ.
#
особенный, когда вы определяете переменную, но не когда переменная раскрывается: к тому времени парсер уже закончил поиск комментариев. Так что вам придется написать:
external_chaos = foo\#bar,biz;baz:boz%bin
чтобы получить #
во-первых, в переменную, но как только она появится, вам не нужно избегать ее при использовании переменной.
Следующая интересная вещь заключается в том, что вам нужно по-разному убегать для целей и предпосылок. Так, например, в цель вы не должны убежать ;
, но в обязательном порядке вы должны бежать ;
, Итак, вам нужны разные макросы:
PESCAPE = $(subst :,\:,$(subst ;,\;,$1))
TESCAPE = $(subst :,\:,$(subst %,\%,$1))
all: $(call PESCAPE,${external_chaos})
$(call TESCAPE,${external_chaos}): ; echo '$@'
дает:
foo#bar,biz;baz:boz%bin