Odpowiedzi:
Masz kilka opcji konfigurowania zmiennych spoza twojego makefile:
Ze środowiska - każda zmienna środowiskowa jest przekształcana w zmienną makefile o tej samej nazwie i wartości.
Możesz także ustawić -e
opcję (aka --environments-override
) na, a zmienne środowiskowe zastąpią przypisania dokonane w pliku makefile (chyba że te przypisania same używają override
dyrektywy . Jednak nie jest to zalecane, a korzystanie z ?=
przypisania jest znacznie lepsze i elastyczne (zmienna warunkowa operator przypisania, działa tylko wtedy, gdy zmienna nie jest jeszcze zdefiniowana):
FOO?=default_value_if_not_set_in_environment
Zauważ, że niektóre zmienne nie są dziedziczone ze środowiska:
MAKE
pochodzi od nazwy skryptuSHELL
jest albo ustawiony w pliku makefile, albo domyślnie ustawiony na /bin/sh
(uzasadnienie: polecenia są określone w pliku makefile i są one specyficzne dla powłoki).Z wiersza poleceń - make
może przyjmować przypisania zmiennych jako część swojego wiersza poleceń, zmieszanego z celami:
make target FOO=bar
Ale wtedy wszystkie przypisania do FOO
zmiennej w pliku makefile będą ignorowane, chyba że użyjesz override
dyrektywy w przypisaniu. (Efekt jest taki sam jak w przypadku -e
opcji dla zmiennych środowiskowych).
Eksportowanie z nadrzędnego programu Make - jeśli wywołasz program Make z pliku Makefile, zwykle nie powinieneś jawnie zapisywać przypisań zmiennych takich jak to:
# Don't do this!
target:
$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Zamiast tego lepszym rozwiązaniem może być eksport tych zmiennych. Wyeksportowanie zmiennej powoduje, że staje się ona środowiskiem każdego wywołania powłoki, a wywołania tych poleceń wybierają te zmienne środowiskowe, jak określono powyżej.
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
Możesz także wyeksportować wszystkie zmienne, używając export
bez argumentów.
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
i przekazanie go jako make -C folder $(PROJECT_MAKE_FLAGS)
. Jeśli istnieje sposób, aby powiedzieć plikowi makefile biblioteki, aby ignorował środowisko, byłoby to idealne rozwiązanie (w przeciwieństwie do -e).
make target FOO=bar
make FOO=bar target
?
Najprostszym sposobem jest:
make foo=bar target
Następnie w swoim makefile możesz się odwoływać $(foo)
. Zauważ, że nie będzie to automatycznie propagować do podwykonawców.
Jeśli używasz podwykonawców, zapoznaj się z tym artykułem: Przekazywanie zmiennych do podwykonawców
included
w głównym makefile?
Z instrukcji :
Zmienne w make mogą pochodzić ze środowiska, w którym make jest uruchamiany. Każda zmienna środowiskowa, która widzi, kiedy się uruchamia, jest przekształcana w zmienną make o tej samej nazwie i wartości. Jednak wyraźne przypisanie w pliku makefile lub za pomocą argumentu polecenia zastępuje środowisko.
Możesz więc zrobić (z bash):
FOOBAR=1 make
co daje zmienną FOOBAR
w twoim Makefile.
Jest jeszcze inna opcja, która nie jest tu cytowana, a która jest zawarta w książce GNU Make autorstwa Stallmana i McGratha (patrz http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html ). Podaje przykład:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
Polega na sprawdzeniu, czy dany parametr pojawia się w MAKEFLAGS
. Na przykład ... załóżmy, że studiujesz wątki w c ++ 11 i podzieliłeś swoje badanie na wiele plików ( class01
, ..., classNM
) i chcesz: skompilować wszystkie i uruchomić osobno lub skompilować jeden na czas i uruchom go, jeśli podano flagę ( -r
na przykład). Więc możesz wymyślić następujące 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
Mając to, możesz:
make -r class02
;make
lub make all
;make -r
(załóżmy, że wszystkie zawierają pewne pewne aserty i po prostu chcesz je wszystkie przetestować)wydaje się
polecenie args zastępuje zmienną środowiskową
Makefile
send:
echo $(MESSAGE1) $(MESSAGE2)
Uruchom przykład
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
Jeśli utworzysz plik o nazwie Makefile i dodasz zmienną taką jak ten $ (unittest), będziesz mógł używać tej zmiennej w Makefile nawet z symbolami wieloznacznymi
przykład:
make unittest=*
Używam BOOST_TEST i podając symbol wieloznaczny do parametru --run_test = $ (unittest), wtedy będę mógł użyć wyrażenia regularnego do odfiltrowania testu, który chcę uruchomić mój Makefile
make A='"as df"'