Да, вы можете использовать ключевое слово define для объявления многострочной переменной, например:
define ANNOUNCE_BODY
Version $(VERSION) of $(PACKAGE_NAME) has been released.
It can be downloaded from $(DOWNLOAD_URL).
etc, etc.
endef
Сложная часть - вернуть вашу многострочную переменную из make-файла. Если вы просто сделаете очевидную вещь, используя "echo $ (ANNOUNCE_BODY)", вы увидите результат, опубликованный здесь другими - оболочка пытается обработать вторую и последующие строки переменной как сами команды.
Однако вы можете экспортировать значение переменной как есть в оболочку как переменную среды, а затем ссылаться на нее из оболочки как переменную среды (НЕ переменную make). Например:
export ANNOUNCE_BODY
all:
@echo "$$ANNOUNCE_BODY"
Обратите внимание на использование $$ANNOUNCE_BODY
, указывающего на ссылку на переменную среды оболочки, а не $(ANNOUNCE_BODY)
на обычную ссылку на переменную make. Также не забудьте заключить ссылку на переменную в кавычки, чтобы убедиться, что новые строки не интерпретируются самой оболочкой.
Конечно, этот конкретный трюк может зависеть от платформы и оболочки. Я тестировал его на Ubuntu Linux с GNU bash 3.2.13; YMMV.
export ANNOUNCE_BODY
устанавливает только переменную внутри правил - это не позволяет ссылаться на $$ ANNOUNCE_BODY для определения других переменных.ANNOUNCE_BODY
в других определениях переменных, просто укажите его, как любую другую переменную make. Например,OTHER=The variable ANNOUNCE_BODY is $(ANNOUNCE_BODY)
. Конечно, вам все равно понадобитсяexport
трюк, если вы хотите выйтиOTHER
в команде.Другой подход к «получению вашей многострочной переменной обратно из make-файла» (отмеченный Эриком Мельски как «сложная часть») состоит в том, чтобы спланировать использование
subst
функции для заменыdefine
символов новой строки, представленных в многострочной строке, на\n
. Затем используйте -e с,echo
чтобы интерпретировать их. Вам может потребоваться установить .SHELL = bash, чтобы получить эхо, которое делает это.Преимущество этого подхода в том, что вы также добавляете в текст другие подобные escape-символы и уважаете их.
Это своего рода синтез всех упомянутых подходов ...
Вы получаете:
Обратите внимание, что одиночные кавычки в финальном эхо имеют решающее значение.
источник
=
после,define ANNOUNCE_BODY
чтобы он заработал.Предполагая, что вы хотите только распечатать содержимое своей переменной на стандартном выводе, есть другое решение:
источник
make: 'do-echo' is up to date.
. Используя команду «no op», я смог заглушить его:@: $(info $(YOUR_MULTILINE_VAR))
.PHONY
чтобы сообщить своему Makefile, что нечего проверять по этому правилу. Файлы Makefile изначально предназначались для компиляторов, если я не ошибаюсь, поэтомуmake
творит некую магию, которую я не понимаю, чтобы предвидеть, что правило ничего не изменит, и поэтому предполагает, что это «сделано». Добавление.PHONY do-echo
в ваш файл укажет вамmake
игнорировать это и в любом случае запустить код.$(info ...)
вне правила make. Он по-прежнему будет генерировать вывод.Да. Вы экранируете символы новой строки
\
:Обновить
Ах, вы хотите новые строки? Тогда нет, я не думаю, что в vanilla Make что-то есть. Однако вы всегда можете использовать здесь-документ в командной части.
[Это не работает, см. Комментарий MadScientist]
источник
Просто постскриптум к ответу Эрика Мельски: вы можете включать вывод команд в текст, но вы должны использовать синтаксис Makefile «$ (shell foo)», а не синтаксис оболочки «$ (foo)». Например:
источник
Вы должны использовать конструкцию Make "define / endef":
Затем вы должны передать значение этой переменной в команду оболочки. Но если вы сделаете это с помощью подстановки переменной Make, это приведет к разделению команды на несколько:
Qouting тоже не поможет.
Лучший способ передать значение - передать его через переменную окружения:
Примечание:
источник
Здесь нет документа, но он отображает многострочное сообщение способом, подходящим для каналов.
=====
=====
Вы также можете использовать вызываемые макросы Gnu:
=====
=====
Вот результат:
=====
=====
источник
Почему бы вам не использовать символ \ n в своей строке для определения конца строки? Также добавьте дополнительную обратную косую черту, чтобы добавить ее в несколько строк.
источник
$(subst \n ,\n,$(TEXT))
хотя хотел бы, чтобы был способ получше!Руководство GNU `make ', 6.8: Определение многострочных переменных
источник
echo
.В духе .ONESHELL в сложных средах .ONESHELL можно подобраться довольно близко:
Пример использования будет примерно таким:
Это показывает результат (при условии, что pid 27801):
Такой подход позволяет использовать некоторые дополнительные функции:
Эти параметры оболочки будут:
Скорее всего, напрашиваются другие интересные возможности.
источник
Мне больше всего нравится ответ Альхадиса. Но чтобы сохранить форматирование столбцов, добавьте еще одну вещь.
Выходы:
источник
make
, он обычно ожидает запуска процесса сборки.Не полностью связано с OP, но, надеюсь, это поможет кому-то в будущем. (поскольку этот вопрос чаще всего встречается при поиске в Google).
В моем Makefile я хотел передать содержимое файла команде сборки docker, после долгого испуга я решил:
см. пример ниже.
nb: В моем конкретном случае я хотел передать ключ ssh во время сборки образа, используя пример из https://vsupalov.com/build-docker-image-clone-private-repo-ssh-key/ (используя многоступенчатая сборка докеров для клонирования репозитория git, а затем удаление ключа ssh из окончательного образа на 2-м этапе сборки)
Makefile
Dockerfile
источник
С GNU Make 3.82 и выше эта
.ONESHELL
опция станет вашим другом, когда дело доходит до многострочных фрагментов оболочки. Собирая подсказки из других ответов, я получаю:При копировании и вставке приведенного выше примера в редактор убедитесь, что все
<tab>
символы сохранены, в противном случаеversion
цель сломается!Обратите внимание, что это
.ONESHELL
приведет к тому, что все цели в Makefile будут использовать одну оболочку для всех своих команд.источник
make version printf "Version 1.2.3 of foo-bar has been released. /bin/sh: 1: Syntax error: Unterminated quoted string make: *** [version] Error 2
(GNU make 3,81)@printf ...
оператором - похоже, что TAB всегда отображаются как 4 пробела ....ONESHELL
это новинка в версии 3.82.*** missing separator. Stop.
.Не совсем полезный ответ, но просто чтобы указать, что 'define' не работает, как ответил Ax (не вписывается в комментарий):
Выдает ошибку, что команду «Оно» не может быть найдено, поэтому пытается интерпретировать вторую строку ANNOUNCE BODY как команду.
источник
У меня сработало:
источник
GNU Makefile может делать следующее. Это уродливо, и я не скажу, что вы должны это делать, но я делаю это в определенных ситуациях.
make .profile
создает файл .profile, если он не существует.Это решение использовалось там, где приложение будет использовать только GNU Makefile в среде оболочки POSIX. Проект не является проектом с открытым исходным кодом, где совместимость платформ является проблемой.
Целью было создать Makefile, который упростил бы настройку и использование рабочего пространства определенного типа. Makefile приносит с собой различные простые ресурсы, не требуя таких вещей, как другой специальный архив и т. Д. Это, в некотором смысле, архив оболочки. Затем процедура может сказать такие вещи, как перетащить этот Makefile в папку для работы. Настройте рабочее пространство, введите
make workspace
, затем, чтобы сделать бла, введитеmake blah
и т. Д.Что может быть непросто, так это выяснить, что указать в оболочке. Вышеупомянутое делает свою работу и близко к идее указания здесь документа в Makefile. Другой вопрос, подходит ли это для общего использования.
источник
Я считаю, что самым безопасным ответом для кроссплатформенного использования было бы использование одного эха на строку:
Это позволяет избежать каких-либо предположений о доступной версии эха.
источник
Использовать подстановку строк :
Затем в свой рецепт положите
Это работает, потому что Make заменяет все вхождения
|
(обратите внимание на пробел) и меняет их местами на символ новой строки ($$'\n'
). Вы можете думать об эквивалентных вызовах сценария оболочки как о чем-то вроде этого:Перед:
После:
Я не уверен, если
$'\n'
доступен ли он в системах, отличных от POSIX, но если вы можете получить доступ к одному символу новой строки (даже путем чтения строки из внешнего файла), основной принцип тот же.Если у вас много таких сообщений, вы можете уменьшить шум с помощью макроса :
Где бы вы его вызывали так:
Надеюсь, это кому-то поможет. знак равно
источник
В качестве альтернативы вы можете использовать команду printf. Это полезно на OSX или других платформах с меньшим количеством функций.
Чтобы просто вывести многострочное сообщение:
Если вы пытаетесь передать строку в качестве аргумента другой программе, вы можете сделать это следующим образом:
источник