Прохождение дополнительных переменных из командной строки, чтобы сделать
могу ли я передавать переменные в 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, и вы просто хотите их проверить все)