Affectation de variables dans une commande à l’intérieur d’une cible Makefile

J’ai donc ce fragment de code dans un fichier Makefile.am (automake):

 RUNNER = \ for asm in $${TEST_ASSEMBLIES}; do \ echo -e "Running tests on $${asm}..."; \ $(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm; \ echo $$?; \ done test: @pushd $(DIR_BIN) &>/dev/null; \ export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; $(RUNNER); \ popd &>/dev/null; 

La déclaration echo $$?; fonctionne: il imprime 0 lorsque le test fonctionne et 1 lorsqu’il échoue.

Mais ce que j’essaie de faire est d’avoir une GLOBAL_EXIT_CODE globale appelée GLOBAL_EXIT_CODE ou quelque chose, qui aurait 0 si tous les tests fonctionnent bien, ou 1 si l’ un des tests échouait. Mais pour la vie de moi, je ne peux même pas saisir la valeur de $$? dans une variable. J’ai essayé de nombreuses choses: export, assignemnt via simple “VAR = $$?”, Également avec l’opérateur += … etc. Rien ne marche! 🙁

La raison pour laquelle je souhaite avoir une variable GLOBAL_EXIT_CODE est que je puisse exit $GLOBAL_EXIT_CODE dans la cible du test , au cas où sa valeur serait supérieure à zéro, afin que la commande make test renvoie une erreur.

Vous ne pouvez pas faire ça. Vous devez vous rappeler que la recette est en cours d’exécution dans un shell que make a appelé. C’est un processus distinct, pas dans le processus de fabrication.

Il n’y a aucun moyen que ce qui se passe dans le shell (un processus enfant) puisse changer un aspect de make (le processus parent) tel que définir une variable make. Une fois le shell sorti, toutes les informations qu’il contient sont perdues. La seule chose que l’on récupère du shell est le code de sortie final; C’est comme ça que make décide si la commande a réussi ou échoué.

La seule façon de faire est d’écrire la valeur dans un fichier, puis de faire lire le fichier et de mettre la valeur résultante dans une variable make.

ETA:

Mais si tout ce que vous voulez faire est de conserver le code de sortie dans le shell (comme disent vos modifications), alors vous n’avez pas besoin de variable make . Vous avez besoin d’une variable shell et c’est très facile. De plus, notez que make appelle toujours /bin/sh qui est un shell POSIX, et que pushd et popd sont des fonctions de shell bash, donc ce fichier makefile n’est pas portable. Heureusement, il est inutile de faire le pushd ou le popd toute façon, car le répertoire de travail (dans un système POSIX) est une fonctionnalité d’un processus individuel (le shell dans ce cas). et sont partis quand la shell sort.

Alors, essayez quelque chose comme ceci:

 RUNNER = \ RETURN=0; \ for asm in $${TEST_ASSEMBLIES}; do \ echo -e "Running tests on $${asm}..."; \ $(ENV_OPTIONS) $(NUNIT_CONSOLE) -nologo -noshadow $$asm \ || RETURN=$$?; \ done test: @export TEST_ASSEMBLIES="$(TEST_ASSEMBLIES)"; \ $(RUNNER); \ exit $$RETURN 

Je ne comprends pas vraiment pourquoi vous définissez la variable shell TEST_ASSEMBLIES sur la valeur de la variable make $(TEST_ASSEMBLIES) . Ce n’est pas nécessaire, mais ça va marcher.

J’élargis mon commentaire en réponse; c’est le moyen automatique de résoudre le problème, puisque l’autre réponse se concentre sur la fabrication simple.

En supposant que votre TEST_ASSEMBLIES est une liste de programmes pouvant être exécutés de manière autonome:

 TESTS = $(TEST_ASSEMBLIES) 

Terminé. Faites un make check et vous devriez voir le résumé des tests. Par défaut, automake utilisera son propre pilote de test, qui exécute chaque test, redirige la sortie vers un fichier journal et imprime le résumé.

Si vous souhaitez que les tests soient exécutés par un programme spécial, utilisez la variable LOG_COMPILER :

 TESTS = $(TEST_ASSEMBLIES) LOG_COMPILER = $(NUNIT_CONSOLE) AM_LOG_FLAGS = -nologo -noshadow 

Si vous avez besoin de configurer des variables d’environnement (est-ce que c’est ce ENV_OPTIONS fait ENV_OPTIONS ?), Vous pouvez utiliser AM_TESTS_ENVIRONMENT pour cela.