113 votes

Comment pourrais-je ajouter dir à $PATH dans le fichier Makefile?

Je veux écrire un Makefile qui exécuterait des tests. Les tests se trouvent dans un répertoire './tests' et les fichiers exécutables à tester se trouvent dans le répertoire './bin'.

Lorsque je lance les tests, ils ne voient pas les fichiers exécutables, car le répertoire ./bin n'est pas dans le $PATH.

Quand je fais quelque chose comme ceci :

EXPORT PATH=bin:$PATH
make test

tout fonctionne. Cependant, j'ai besoin de modifier le $PATH dans le Makefile.

Contenu du Makefile simple :

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x

Il affiche correctement le chemin, cependant il ne trouve pas le fichier x.

Quand je fais ceci manuellement :

$ export PATH=bin:$PATH
$ x

tout va bien alors.

Comment pourrais-je changer le $PATH dans le Makefile?

130voto

Eldar Abusalimov Points 8143

Avez-vous essayé la directive export de Make lui-même (en supposant que vous utilisez GNU Make) ?

export PATH := bin:$(PATH)

test all:
    x

Aussi, il y a un bug dans votre exemple :

test all:
    PATH=bin:${PATH}
    @echo $(PATH)
    x

Tout d'abord, la valeur affichée par echo est une expansion de la variable PATH effectuée par Make, et non par le shell. Si elle affiche la valeur attendue, alors je suppose que vous avez défini la variable PATH quelque part plus tôt dans votre Makefile, ou dans un shell qui a invoqué Make. Pour éviter un tel comportement, vous devriez échapper les signes dollars :

test all:
    PATH=bin:$$PATH
    @echo $$PATH
    x

Deuxièmement, de toute façon cela ne fonctionnera pas car Make exécute chaque ligne de la recette dans un shell séparé. Cela peut être modifié en écrivant la recette sur une seule ligne :

test all:
    export PATH=bin:$$PATH; echo $$PATH; x

38voto

kenorb Points 2464

Par conception, le parseur make exécute les lignes dans des invocations de shell séparées, c'est pourquoi le changement de variable (par exemple PATH) dans une ligne peut ne pas être appliqué pour les lignes suivantes (voir ce post).

Une façon de contourner ce problème est de convertir plusieurs commandes en une seule ligne (séparées par ;), ou d'utiliser la cible spéciale One Shell (.ONESHELL, à partir de GNU Make 3.82).

Alternativement, vous pouvez fournir la variable PATH au moment où le shell est invoqué. Par exemple:

PATH  := $(PATH):$(PWD)/bin:/my/other/path
SHELL := env PATH=$(PATH) /bin/bash

27voto

underspecified Points 569

Les modifications de chemin semblent être persistantes si vous définissez la variable SHELL dans votre makefile en premier :

SHELL := /bin/bash
PATH := bin:$(PATH)

test all:
    x

Je ne sais pas si c'est un comportement désiré ou non.

4voto

Richard Pennington Points 12912

Ce que je fais habituellement est de fournir le chemin de l'exécutable explicitement :

EXE=./bin/
...
test all:
    $(EXE)x

J'utilise également cette technique pour exécuter des binaires non natifs sous un émulateur comme QEMU si je suis en train de compiler en croisant :

EXE = qemu-mips ./bin/

Si make utilise le shell sh, cela devrait fonctionner :

test all:
    PATH=bin:$PATH x

-3voto

karnhick Points 46

Pour définir la variable PATH, uniquement dans le Makefile, utilisez quelque chose comme :

PATH := $(PATH):/mon/dossier

test:
@echo mon nouveau PATH = $(PATH)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X