Passer des variables supplémentaires de la ligne de commande à make
Puis-je passer des variables à un Makefile GNU en tant qu'arguments de ligne de commande? En d'autres termes, je veux passer quelques arguments qui deviendront éventuellement des variables dans le Makefile.
7 réponses
Vous avez plusieurs options pour configurer des variables à partir de l'extérieur de votre makefile:
-
From environment - chaque variable d'environnement est transformée en une variable makefile avec le même nom et la même valeur.
Vous pouvez également définir l'option
-e(aka--environments-override) sur, et vos variables d'environnement remplaceront les affectations faites dans makefile (à moins que ces affectations elles-mêmes utilisent leoverridedirective . Cependant, il n'est pas recommandé, et c'est beaucoup meilleur et flexible à utiliser?=assignment (l'opérateur d'affectation de variable conditionnelle, il n'a d'effet que si la variable n'est pas encore définie):FOO?=default_value_if_not_set_in_environmentNotez que certaines variables ne sont pas héritées de l'environnement:
-
MAKEest obtenu à partir du nom du script -
{[9] } est défini dans un makefile, ou par défaut
/bin/sh(justification: les commandes sont spécifiées dans le makefile, et elles sont spécifiques au shell).
-
-
À Partir de ligne de commande -
makepeut prendre des affectations de variables dans le cadre de sa ligne de commande, mêlée à des cibles:make target FOO=barMais alors toutes les affectations à la variable
FOOdans le makefile seront ignorées sauf si vous utilisezoverridedirective {[26] } en cession. (L'effet est le même qu'avec l'option-epour les variables d'environnement). -
Exporter à partir du parent Make - si vous appelez Make à partir D'un Makefile, vous ne devriez généralement pas explicitement écrivez les 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 rend dans l'environnement de chaque appel de shell, et faire des appels à partir de ces commandes choisir ces variables d'environnement comme spécifié ci-dessus.
# Do like this CFLAGS=-g export CFLAGS target: $(MAKE) -C targetVous pouvez également exporter toutes les variables en utilisant
exportsans arguments.
Le moyen le plus simple est:
make foo=bar target
, Puis 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
Dites que vous avez un makefile comme ceci:
action:
echo argument is $(argument)
Vous l'appelleriez alors make action argument=something
Les Variables de 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 une 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.
Donc vous pouvez faire (de bash):
FOOBAR=1 make
Résultant en une variable FOOBAR dans votre Makefile.
export ROOT_DIR=<path/value>
Ensuite, utilisez la variable, $(ROOT_DIR) dans le Makefile.
Si vous créez un fichier appelé Makefile et ajoutez une variable comme celle-ci $(unittest) ensuite, 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) ensuite, je serai en mesure d'utiliser l'expression régulière pour filtrer le test que je veux mon Makefile pour exécuter
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
Cela implique de vérifier si un paramètre donné apparaît dans MAKEFLAGS. Exemple .. supposons que vous étudiez les threads en C++11 et que vous avez divisé votre étude sur plusieurs fichiers (class01, ... , classNM) et vous voulez: compiler puis tout et exécuter individuellement ou compiler et l'exécuter si un indicateur est spécifié (-r, par exemple). Donc, vous pouvez trouver ce qui suit 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 feriez:
- construire et exécuter un fichier w/
make -r class02; - construire tous les w/
makeoumake all; - construisez et exécutez tous w /
make -r(supposons que tous contiennent un certain type de choses assert et que vous voulez juste les tester tous)