Ответы:
У вас есть несколько вариантов для установки переменных вне вашего make-файла:
Из среды - каждая переменная среды преобразуется в переменную makefile с тем же именем и значением.
Вы также можете захотеть включить -eпараметр (aka --environments-override), и ваши переменные среды будут переопределять назначения, сделанные в make-файле (если только эти назначения сами не используют overrideдирективу . Однако это не рекомендуется, и намного лучше и гибче использовать ?=назначение (условная переменная) Оператор присваивания действует только в том случае, если переменная еще не определена):
FOO?=default_value_if_not_set_in_environment
Обратите внимание, что некоторые переменные не наследуются от окружения:
MAKE получается из названия скриптаSHELLлибо устанавливается в make-файле, либо по умолчанию /bin/sh(обоснование: команды указываются в make-файле, и они зависят от оболочки).Из командной строки - makeможет принимать переменные назначения как часть своей командной строки, смешанные с целями:
make target FOO=bar
Но тогда все присваивания FOOпеременной внутри make-файла будут игнорироваться, если вы не используете overrideдирективу в присваивании. (Эффект такой же, как с -eопцией для переменных среды).
Экспорт из родительского Make - если вы вызываете Make из Makefile, вам обычно не следует явно писать назначения переменных следующим образом:
# Don't do this!
target:
$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Вместо этого лучшим решением может быть экспорт этих переменных. Экспорт переменной превращает ее в среду каждого вызова оболочки, и вызовы Make из этих команд выбирают эти переменные среды, как указано выше.
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
Вы также можете экспортировать все переменные, используя exportбез аргументов.
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)и передача его как make -C folder $(PROJECT_MAKE_FLAGS). Если есть способ заставить make-файл библиотеки игнорировать окружение, это было бы идеально (напротив -e).
make target FOO=bar make FOO=bar target?
Самый простой способ:
make foo=bar target
Тогда в вашем makefile вы можете сослаться $(foo). Обратите внимание, что это не будет распространяться на суб-производителей автоматически.
Если вы используете под-марку, см. Эту статью: Связь переменных с под-маркой
includedв главном make-файле?
Из руководства :
Переменные в make могут происходить из среды, в которой запускается make. Каждая переменная окружения, которая видит, когда она запускается, преобразуется в переменную make с тем же именем и значением. Однако явное присваивание в make-файле или с аргументом команды переопределяет окружение.
Так что вы можете сделать (из Баш):
FOOBAR=1 make
в результате чего переменная FOOBARв вашем Makefile.
Есть еще один вариант, не упомянутый здесь, который включен в книгу GNU Make 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. Например ... предположим, что вы изучаете потоки в 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
Имея это, вы бы:
make -r class02;makeили make all;make -r(предположим, что все они содержат какой-то определенный тип утверждений, и вы просто хотите проверить их все)это выглядит
команда args перезаписать переменную окружения
Makefile
send:
echo $(MESSAGE1) $(MESSAGE2)
Пример запуска
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
Если вы создадите файл с именем Makefile и добавите переменную наподобие этого $ (unittest), то вы сможете использовать эту переменную внутри Makefile даже с подстановочными знаками
пример :
make unittest=*
Я использую BOOST_TEST и, задав подстановочный знак для параметра --run_test = $ (unittest), я смогу использовать регулярное выражение для фильтрации теста, который я хочу запустить в своем Makefile.
make A='"as df"'