Прохождение дополнительных переменных из командной строки, чтобы сделать
могу ли я передавать переменные в GNU Makefile в качестве аргументов командной строки? Другими словами, Я хочу передать некоторые аргументы, которые в конечном итоге станут переменными в файле Makefile.
7 ответов:
у вас есть несколько вариантов настройки переменных вне вашего makefile:
окружающая среда - каждая переменная среды преобразуется в переменную makefile с тем же именем и значением.
вы также можете установить (Он же
--environments-override
) on, и ваши переменные среды будут переопределять назначения, сделанные в makefile (если только эти назначения сами не используютoverride
директива . Тем не менее, это не рекомендуется, и это гораздо лучше и гибко использовать?=
присваивание (оператор присваивания условной переменной, он действует только в том случае, если переменная еще не определена):FOO?=default_value_if_not_set_in_environment
обратите внимание, что некоторые переменные не наследуются от среды:
MAKE
получается из названия скриптаSHELL
устанавливается либо в файле makefile, либо по умолчанию/bin/sh
(обоснование: команды, указанные в makefile, и они специфичны для оболочки).из командной строки -
make
может принимать переменные назначения как часть его командной строки, смешанные с целями:make target FOO=bar
а то все поручения
FOO
переменная в файле makefile будет проигнорирована если вы используетеoverride
директива в назначении. (Эффект тот же, что и с для окружающей среды переменные параметры.)экспорт из родительского 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
без аргументов.
самый простой способ-это:
make foo=bar target
тогда в вашем makefile вы можете ссылаться на
$(foo)
. Обратите внимание, что это не будет распространяться на суб-делает автоматически.Если вы используете суб-делает, см. Эту статью:передача переменных в суб-make
скажем, у вас есть makefile, как это:
action: echo argument is $(argument)
вы бы тогда назвали это
make action argument=something
С руководство:
переменные в make могут поступать из среды, в которой выполняется make. Каждая переменная среды, которая make видит, когда она запускается, преобразуется в переменную make с тем же именем и значением. Однако явное назначение в файле makefile или с аргументом команды переопределяет среду.
Так что вы можете сделать (от bash):
FOOBAR=1 make
в результате в переменной
FOOBAR
в файл Makefile.
Если вы создадите файл с именем Makefile и добавите такую переменную, как $(unittest) тогда вы сможете использовать эту переменную внутри файла Makefile даже с подстановочными знаками
пример :
make unittest=*
Я использую BOOST_TEST и, давая подстановочный знак параметру --run_test=$(unittest) тогда я смогу использовать регулярное выражение для фильтрации теста, который я хочу, чтобы мой Makefile для запуска
есть еще один вариант, не упомянутый здесь, который включен в Книгу GNU Make Stallman and 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
. Например.. предположим, что вы изучаете темы в c++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 $@.out $^ $(LDLIBS) ifneq (,$(findstring r, $(MAKEFLAGS))) ./$@.out endif all: $(SOURCES) .PHONY: clean clean: find . -name "*.out" -delete
имея это, вы бы:
- построить и запустить файл W/
make -r class02
;- построить все ж/
make
илиmake all
;- построить и запустить все ж/
make -r
(предположим, что все они содержат некоторые определенные вещи assert, и вы просто хотите их проверить все)