Réponses:
Vous avez plusieurs options pour configurer des variables depuis l'extérieur de votre makefile:
De l'environnement - chaque variable d'environnement est transformée en une variable makefile avec le même nom et la même valeur.
Vous pouvez également activer l' -e
option (aka --environments-override
), et vos variables d'environnement remplaceront les affectations faites dans makefile (sauf si ces affectations elles-mêmes utilisent la override
directive . Cependant, ce n'est pas recommandé, et il est beaucoup mieux et flexible d'utiliser l' ?=
affectation (la variable conditionnelle) opérateur d'affectation, il n'a d'effet que si la variable n'est pas encore définie):
FOO?=default_value_if_not_set_in_environment
Notez que certaines variables ne sont pas héritées de l'environnement:
MAKE
est obtenu à partir du nom du scriptSHELL
est soit défini dans un makefile, soit par défaut /bin/sh
(justification: les commandes sont spécifiées dans le makefile, et elles sont spécifiques au shell).Depuis la ligne de commande - make
peut accepter des affectations variables dans le cadre de sa ligne de commande, mêlées à des cibles:
make target FOO=bar
Mais alors toutes les affectations à la FOO
variable dans le makefile seront ignorées à moins que vous n'utilisiez la override
directive dans l'affectation. (L'effet est le même qu'avec l' -e
option pour les variables d'environnement).
Exportation à partir du Make parent - si vous appelez Make à partir d'un Makefile, vous ne devriez généralement pas écrire explicitement des affectations de variables comme ceci:
# Don't do this!
target:
$(MAKE) -C target CC=$(CC) CFLAGS=$(CFLAGS)
Au lieu de cela, une meilleure solution pourrait être d'exporter ces variables. L'exportation d'une variable la fait entrer dans l'environnement de chaque appel de shell, et les appels à partir de ces commandes choisissent ces variables d'environnement comme spécifié ci-dessus.
# Do like this
CFLAGS=-g
export CFLAGS
target:
$(MAKE) -C target
Vous pouvez également exporter toutes les variables en utilisant export
sans arguments.
export PROJECT_MAKE_ARGS = CC=$(CC) CFLAGS=$(CFLAGS)
et de la transmettre en tant que make -C folder $(PROJECT_MAKE_FLAGS)
. S'il y a un moyen de dire au makefile de la bibliothèque d'ignorer l'environnement, ce serait idéal (à l'opposé de -e).
make target FOO=bar
make FOO=bar target
?
La manière la plus simple est:
make foo=bar target
Ensuite, dans votre makefile, vous pouvez vous référer à $(foo)
. Notez que cela ne se propagera pas automatiquement aux sous-marques.
Si vous utilisez des sous-marques, consultez cet article: Communiquer des variables à une sous-marque
included
dans le makefile principal?
Du manuel :
Les variables dans make peuvent provenir de l'environnement dans lequel make est exécuté. Chaque variable d'environnement que make voit au démarrage est transformée en variable make avec le même nom et la même valeur. Cependant, une affectation explicite dans le makefile, ou avec un argument de commande, remplace l'environnement.
Vous pouvez donc faire (depuis bash):
FOOBAR=1 make
résultant en une variable FOOBAR
dans votre Makefile.
Il y a une autre option non citée ici qui est incluse dans le livre GNU Make de Stallman et McGrath (voir http://www.chemie.fu-berlin.de/chemnet/use/info/make/make_7.html ). Il fournit l'exemple:
archive.a: ...
ifneq (,$(findstring t,$(MAKEFLAGS)))
+touch archive.a
+ranlib -t archive.a
else
ranlib archive.a
endif
Il s'agit de vérifier si un paramètre donné apparaît dans MAKEFLAGS
. Par exemple .. supposons que vous étudiez les threads en c ++ 11 et que vous avez divisé votre étude sur plusieurs fichiers ( class01
, ..., classNM
) et que vous souhaitez: compiler puis tout et exécuter individuellement ou compiler un à la fois. et exécutez-le si un indicateur est spécifié ( -r
, par exemple). Ainsi, vous pouvez proposer les éléments suivants 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
Ayant cela, vous auriez:
make -r class02
;make
ou make all
;make -r
(supposons que tous contiennent un certain type de substance assert et que vous voulez juste tous les tester)il semble
commande args écraser la variable d'environnement
Makefile
send:
echo $(MESSAGE1) $(MESSAGE2)
Exécuter l'exemple
$ MESSAGE1=YES MESSAGE2=NG make send MESSAGE2=OK
echo YES OK
YES OK
Si vous créez un fichier appelé Makefile et ajoutez une variable comme celle-ci $ (unittest), vous pourrez utiliser cette variable dans le Makefile même avec des caractères génériques
exemple :
make unittest=*
J'utilise BOOST_TEST et en donnant un caractère générique au paramètre --run_test = $ (unittest), je pourrai utiliser une expression régulière pour filtrer le test que je veux que mon Makefile exécute
make A='"as df"'