Функция оболочки
Функция shell отличается от любой другой функции, кроме функции wildcard (см. Функция wildcard), тем, что она взаимодействует с внешним миром за пределами make.
Функция shell обеспечивает make ту же возможность, что и обратные кавычки (‘`’) в большинстве оболочек: она выполняет расширение команд. Это означает, что она принимает в качестве аргумента команду оболочки и расширяется до результата выполнения этой команды. Единственная обработка, которую make выполняет над результатом, заключается в замене каждой новой строки (или пары возврат каретки/новая строка) на один пробел. Если присутствует заключительная (возврат каретки и) новая строка, она просто удаляется.
Команды, выполняемые вызовами функции shell, выполняются при расширении вызовов функции (см. Как make считывает Makefile). Поскольку эта функция предполагает запуск новой оболочки, вы должны тщательно продумать последствия производительности использования функции shell в рекурсивно расширяемых переменных по сравнению с просто расширяемыми переменными (см. Два типа переменных).
Альтернативой функции shell является оператор присваивания ‘!=’; он обеспечивает аналогичное поведение, но имеет незначительные отличия (см. Настройка переменных). Оператор присваивания ‘!=’ включён в новые стандарты POSIX.
После использования функции shell или оператора присваивания ‘!=’ её код возврата помещается в переменную .SHELLSTATUS.
Ниже приведены некоторые примеры использования функции shell:
contents := $(shell cat foo)
устанавливает contents в содержимое файла foo, при этом пробел (а не новая строка) разделяет каждую строку.
files := $(shell echo *.c)
устанавливает files в расширение ‘*.c’. Если make использует нестандартную оболочку, результат будет таким же, как у ‘$(wildcard *.c)’ (при условии, что существует хотя бы один файл ‘.c’).
Все переменные, помеченные как export, также будут переданы оболочке, запущенной функцией shell. Возможен цикл расширения переменных: рассмотрите этот makefile:
export HI = $(shell echo hi) all: ; @echo $$HI
Когда make хочет выполнить рецепт, он должен добавить переменную HI в среду; для этого она должна быть расширена. Значение этой переменной требует вызова функции shell, а для её вызова необходимо создать её среду. Поскольку HI экспортирована, её необходимо расширить, чтобы создать её среду. И так далее. В этом специфичном случае make будет использовать значение переменной из среды, предоставленной make, или пустую строку, если её не было, вместо цикла или выдачи ошибки. Это часто то, что вам нужно; например:
export PATH = $(shell echo /usr/local/bin:$$PATH)
Однако, было бы проще и эффективнее использовать здесь просто расширяемую переменную (‘:=’) с самого начала.
Copyright © 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Free Software Foundation, Inc.
Licensed under the GNU Free Documentation License.
https://www.gnu.org/software/make/manual/html_node/Shell-Function.html