Ответы:
У вас есть несколько вариантов для установки переменных вне вашего 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"'