Экранирование переменных 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
Другие вопросы по тегам