Могу ли я передавать переменные в GNU Makefile в качестве аргументов командной строки? Другими словами, я хочу передать некоторые аргументы, которые в конечном итоге станут переменными в Makefile.
Передача дополнительных переменных из командной строки для
Ответ 1
У вас есть несколько параметров для настройки переменных вне вашего make файла:
-
Из среды - каждая переменная среды преобразуется в переменную makefile с тем же именем и значением.
Вы также можете установить параметр
-e
(aka--environments-override
), а переменные среды переопределите назначения, сделанные в makefile (если сами эти назначения не используютoverride
. Однако это не рекомендуется, и гораздо лучше и гибко использовать назначение?=
(оператор присваивания условных переменных, оно действует только в том случае, если переменная еще не определена)FOO?=default_value_if_not_set_in_environment
Обратите внимание, что некоторые переменные не наследуются от среды:
-
MAKE
получен от имени script -
SHELL
либо задается в make файле, либо по умолчанию используется/bin/sh
(логическое: команды задаются в файле makefile и зависят от оболочки).
-
-
Из командной строки -
MAKE
может принимать назначения переменных как часть его командной строки, смешанные с целями:make target FOO=bar
Но тогда все назначения переменной
FOO
в make файле будут проигнорированы, если вы не используете директивуoverride
при назначении. (Эффект такой же, как с параметром-e
для переменных среды). -
Экспорт из родителя Make - если вы вызываете Make из Makefile, вы обычно не должны явно писать назначения переменных следующим образом:
# Don't do this! target: $(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Вместо этого лучшим решением может быть экспорт этих переменных. Экспортируя переменную, она попадает в среду каждого вызова оболочки, а вызовы из этих команд выбирают эту переменную среды, как указано выше.
# Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C target
Вы также можете экспортировать все переменные, используя
export
без аргументов.
Ответ 2
Самый простой способ:
make foo=bar target
Затем в вашем файле makefile вы можете обратиться к $(foo)
. Обратите внимание, что это не будет автоматически распространяться на суб файлы.
Если вы используете подзапросы, см. эту статью: Передача переменных в суб файл
Ответ 3
Скажем, у вас есть make файл, подобный этому:
action:
echo argument is $(argument)
Тогда вы бы назвали его make action argument=something
Ответ 4
Из manual:
Переменные в make могут исходить из среды, в которой выполняется make. Каждая переменная среды, которая видна при ее запуске, преобразуется в переменную make с тем же именем и значением. Однако явное назначение в make файле или с аргументом команды переопределяет среду.
Итак, вы можете сделать (от bash):
FOOBAR=1 make
приводит к переменной FOOBAR
в вашем файле Makefile.
Ответ 5
Если вы создаете файл под названием Makefile и добавляете переменную типа $(unittest) то вы сможете использовать эту переменную внутри Makefile даже с помощью подстановочных знаков
пример:
make unittest=*
Я использую BOOST_TEST и задавая шаблон для параметра --run_test = $(unittest) то я смогу использовать регулярное выражение, чтобы отфильтровать тест, я хочу, чтобы мой Makefile для запуска
Ответ 6
export ROOT_DIR=<path/value>
Затем используйте переменную $(ROOT_DIR)
в Makefile.
Ответ 7
Здесь также не указан другой вариант, который включен в книгу GNU. Сделайте книгу Stallman и McGrath (см. http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html). Он предоставляет пример:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
Он включает проверку того, появляется ли данный параметр в MAKEFLAGS
. Например.. предположим, что вы изучаете потоки в С++ 11, и вы разделили свое исследование на несколько файлов (class01
,..., classNM
), и вы хотите: скомпилировать все и запустить отдельно или компилировать по одному и запускать его, если указан флаг (-r
, например). Итак, вы можете найти следующие Makefile
:
CXX=clang++-3.5
CXXFLAGS = -Wall -Werror -std=c++11
LDLIBS = -lpthread
SOURCES = class01 class02 class03
%: %.cxx
$(CXX) $(CXXFLAGS) -o [email protected] $^ $(LDLIBS)
ifneq (,$(findstring r, $(MAKEFLAGS)))
./[email protected]
endif
all: $(SOURCES)
.PHONY: clean
clean:
find . -name "*.out" -delete
После этого вы должны:
- создать и запустить файл w/
make -r class02
; - построить все w/
make
илиmake all
; - создайте и запустите все w/
make -r
(предположим, что все они содержат некоторый определенный тип файлов assert, и вы просто хотите их протестировать)