Je veux écrire un Makefile qui exécuterait des tests. Les tests sont dans un répertoire './tests' et les fichiers exécutables à tester se trouvent dans le répertoire './bin'.
Lorsque j'exécute les tests, ils ne voient pas les fichiers exec, car le répertoire ./bin ne se trouve pas dans $ PATH.
Quand je fais quelque chose comme ça:
EXPORT PATH=bin:$PATH
make test
tout fonctionne. Cependant, j'ai besoin de changer le $ PATH dans le Makefile.
Contenu Makefile simple:
test all:
PATH=bin:${PATH}
@echo $(PATH)
x
Il affiche correctement le chemin, mais ne trouve pas le fichier x.
Quand je le fais manuellement:
$ export PATH=bin:$PATH
$ x
tout va bien alors.
Comment pourrais-je changer le $ PATH dans le Makefile?
Avez-vous essayé export
directive de Make lui-même (en supposant que vous utilisiez GNU Make)?
export PATH := bin:$(PATH)
test all:
x
De plus, il y a un bug dans votre exemple:
test all:
PATH=bin:${PATH}
@echo $(PATH)
x
Premièrement, la valeur echo
ed est une extension de la variable PATH
effectuée par Make et non par le shell. Si elle affiche la valeur attendue, alors, je suppose, vous avez défini la variable PATH
quelque part plus tôt dans votre Makefile, ou dans un shell qui a appelé Make. Pour prévenir un tel comportement, vous devriez échapper à des dollars:
test all:
PATH=bin:$$PATH
@echo $$PATH
x
Deuxièmement, dans tous les cas, cela ne fonctionnera pas car Make exécute chaque ligne de la recette dans un shell séparé . Cela peut être changé en écrivant la recette sur une seule ligne:
test all:
export PATH=bin:$$PATH; echo $$PATH; x
Les modifications de chemin d'accès semblent persistantes si vous définissez d'abord la variable Shell dans votre fichier makefile:
Shell := /bin/bash
PATH := bin:$(PATH)
test all:
x
Je ne sais pas si c'est le comportement souhaité ou non.
De par sa conception, l’analyseur make
exécute des lignes dans des invocations de shell distinctes. C’est pourquoi, en changeant de variable (par exemple, PATH
) sur une ligne, la modification peut ne pas être appliquée aux lignes suivantes (voir post ).
Une solution pour résoudre ce problème consiste à convertir plusieurs commandes en une seule ligne (séparées par ;
), ou utilisez One Shell cible spéciale (.ONESHELL
, à partir de GNU Make 3.82).
Vous pouvez également fournir la variable PATH
au moment où Shell est appelé. Par exemple:
PATH := $(PATH):$(PWD)/bin:/my/other/path
Shell := env PATH=$(PATH) /bin/bash
Ce que je fais habituellement est de fournir explicitement le chemin d'accès à l'exécutable:
EXE=./bin/
...
test all:
$(EXE)x
J'utilise également cette technique pour exécuter des fichiers binaires non natifs sous un émulateur tel que QEMU si je compile de manière croisée:
EXE = qemu-mips ./bin/
Si make utilise sh shell, cela devrait fonctionner:
test all:
PATH=bin:$PATH x