275 votes

Comment obtenir le répertoire relatif actuel de votre Makefile ?

J'ai plusieurs Makefiles dans des répertoires d'applications spécifiques comme celui-ci :

/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile

Chaque Makefile inclut un fichier .inc dans ce chemin un niveau au-dessus :

/project1/apps/app_rules.inc

Dans app_rules.inc, je définis la destination de l'endroit où je veux que les binaires soient placés lors de la construction. Je veux que tous les fichiers binaires soient dans leurs dossiers respectifs. app_type chemin :

/project1/bin/app_typeA/

J'ai essayé d'utiliser $(CURDIR) comme ceci :

OUTPUT_PATH = /project1/bin/$(CURDIR)

mais à la place, j'ai les binaires cachés dans le nom du chemin entier comme ceci : (remarquez la redondance)

/project1/bin/projects/users/bob/project1/apps/app_typeA

Que puis-je faire pour obtenir le "répertoire courant" d'exécution afin de connaître juste le app_typeX afin de placer les binaires dans leurs dossiers types respectifs ?

369voto

D.Dt.Operator Points 1102

La fonction shell.

Vous pouvez utiliser shell fonction : current_dir = $(shell pwd) . Ou shell en combinaison avec notdir si vous n'avez pas besoin d'un chemin absolu : current_dir = $(notdir $(shell pwd)) .

Mise à jour.

La solution proposée ne fonctionne que si vous exécutez make depuis le répertoire courant du Makefile.
Comme l'a noté @Flimm :

Notez que cela renvoie le répertoire de travail actuel, et non le répertoire parent du Makefile.
Par exemple, si vous exécutez cd /; make -f /home/username/project/Makefile le current_dir La variable sera / pas /home/username/project/ .

Le code ci-dessous fonctionnera pour les Makefiles invoqués à partir de n'importe quel répertoire :

mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))

179voto

sleepycal Points 961

Tiré de aquí ;

ROOT_DIR:=$(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

Il apparaît comme ;

$ cd /home/user/

$ make -f test/Makefile 
/home/user/test

$ cd test; make Makefile 
/home/user/test

J'espère que cela vous aidera

68voto

Si vous utilisez GNU make, $(CURDIR) est en fait une variable intégrée. Il s'agit du emplacement où réside le Makefile le répertoire de travail actuel, qui est probablement celui où se trouve le Makefile, mais pas toujours .

OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))

Voir Annexe A Référence rapide dans http://www.gnu.org/software/make/manual/make.html

35voto

momo Points 367
THIS_DIR := $(dir $(abspath $(firstword $(MAKEFILE_LIST))))

10voto

Richard Bronosky Points 3163

J'aime la réponse choisie, mais je pense qu'il serait plus utile de la montrer en train de fonctionner plutôt que de l'expliquer.

/tmp/makefile_path_test.sh

#!/bin/bash -eu

# Create a testing dir
temp_dir=/tmp/makefile_path_test
proj_dir=$temp_dir/dir1/dir2/dir3
mkdir -p $proj_dir

# Create the Makefile in $proj_dir
# (Because of this, $proj_dir is what $(path) should evaluate to.)
cat > $proj_dir/Makefile <<'EOF'
path := $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST)))))
cwd  := $(shell pwd)

all:
    @echo "MAKEFILE_LIST: $(MAKEFILE_LIST)"
    @echo "         path: $(path)"
    @echo "          cwd: $(cwd)"
    @echo ""
EOF

# See/debug each command
set -x

# Test using the Makefile in the current directory
cd $proj_dir
make

# Test passing a Makefile
cd $temp_dir
make -f $proj_dir/Makefile

# Cleanup
rm -rf $temp_dir

Sortie :

+ cd /tmp/makefile_path_test/dir1/dir2/dir3
+ make
MAKEFILE_LIST:  Makefile
         path: /private/tmp/makefile_path_test/dir1/dir2/dir3
          cwd: /tmp/makefile_path_test/dir1/dir2/dir3

+ cd /tmp/makefile_path_test
+ make -f /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
MAKEFILE_LIST:  /tmp/makefile_path_test/dir1/dir2/dir3/Makefile
         path: /tmp/makefile_path_test/dir1/dir2/dir3
          cwd: /tmp/makefile_path_test

+ rm -rf /tmp/makefile_path_test

NOTE : La fonction $(patsubst %/,%,[path/goes/here/]) est utilisé pour supprimer la barre oblique de fin.

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