web-dev-qa-db-fra.com

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

J'ai plusieurs Makefiles dans des répertoires spécifiques à l'application comme ceci:

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

Chaque Makefile inclut un fichier .inc dans ce chemin d'accès au niveau supérieur:

/project1/apps/app_rules.inc

Dans app_rules.inc, je suis en train de définir la destination de l'emplacement des fichiers binaires lors de la construction. Je veux que tous les fichiers binaires soient dans leur chemin app_type respectif:

/project1/bin/app_typeA/

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

OUTPUT_PATH = /project1/bin/$(CURDIR)

mais au lieu de cela, les fichiers binaires sont enterrés dans le nom de chemin complet comme ceci: (remarquez la redondance)

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

Que puis-je faire pour obtenir le "répertoire actuel" d'exécution afin de pouvoir connaître uniquement leapp_typeXafin de placer les fichiers binaires dans leurs dossiers de types respectifs?

154
boltup_im_coding

La fonction shell.

Vous pouvez utiliser Shell function: current_dir = $(Shell pwd). Ou Shell en combinaison avec notdir , si vous n'avez pas besoin du chemin absolu: current_dir = $(notdir $(Shell pwd)).

Mettre à jour.

La solution donnée ne fonctionne que lorsque vous exécutez make à partir du répertoire actuel du Makefile.
Comme l'a noté @ Flimm:

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

Le code ci-dessous fonctionnera pour tous les Makefiles appelés depuis n'importe quel répertoire:

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

Tel que pris de ici ;

ROOT_DIR:=$(Shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))

Se présente comme;

$ cd /home/user/

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

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

J'espère que cela t'aides

108
sleepycal

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

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

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

35
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
22
momo

J'ai essayé plusieurs de ces réponses, mais sur mon système AIX avec GNU make 3,80, je devais faire certaines choses à l'ancienne.

Il s'avère que lastword, abspath et realpath n'ont pas été ajoutés avant 3,81. :(

mkfile_path := $(Word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(Shell cd $(Shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))

Comme d’autres l’ont dit, ce n’est pas le plus élégant, car il invoque deux fois un shell et il a toujours des problèmes d’espace.

Mais comme je n’ai aucun espace dans mes chemins, cela fonctionne pour moi peu importe la façon dont j’ai commencé make:

  • make -f ../wherever/makefile
  • faire -C ../whereever
  • make -C ~/n'importe où
  • cd ../wherever; faire

Tous me donnent wherever pour current_dir et le chemin d'accès absolu à wherever pour mkfile_dir.

3
Jesse Chisholm

Solution trouvée ici: https://sourceforge.net/p/ipt-netflow/bugs-requests-patches/53/

La solution est : $ (CURDIR)

Vous pouvez l'utiliser comme ça:

CUR_DIR = $(CURDIR)

## Start :
start:
    cd $(CUR_DIR)/path_to_folder
2
Soma Bini

J'aime la réponse choisie, mais je pense qu'il serait plus utile de le montrer réellement 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ée pour effacer le slash final.

2
Bruno Bronosky

Exemple pour votre référence, comme ci-dessous:

La structure du dossier peut être la suivante:

 enter image description here

Où il y a deux Makefiles, chacun comme ci-dessous;

sample/Makefile
test/Makefile

Voyons maintenant le contenu des Makefiles.

échantillon/Makefile

export ROOT_DIR=${PWD}

all:
    echo ${ROOT_DIR}
    $(MAKE) -C test

test/Makefile

all:
    echo ${ROOT_DIR}
    echo "make test ends here !"

Maintenant, exécutez l'exemple/Makefile, comme;

cd sample
make

SORTIE:

echo /home/symphony/sample
/home/symphony/sample
make -C test
make[1]: Entering directory `/home/symphony/sample/test'
echo /home/symphony/sample
/home/symphony/sample
echo "make test ends here !"
make test ends here !
make[1]: Leaving directory `/home/symphony/sample/test'

Une explication serait que le répertoire parent/home puisse être stocké dans le flag-environnement et exporté, de sorte qu'il puisse être utilisé dans tous les makefiles du sous-répertoire.

0
parasrish

Voici une ligne pour obtenir le chemin absolu de votre fichier Makefile à l'aide de la syntaxe du shell:

Shell := /bin/bash
CWD := $(Shell cd -P -- '$(Shell dirname -- "$0")' && pwd -P)

Et voici la version sans Shell basée sur @ 0xff answer :

CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))

Testez-le en l’imprimant, par exemple:

cwd:
        @echo $(CWD)
0
kenorb

Si la variable make contient le chemin relatif est ROOT_DIR

ROOT_DIR := ../../../

Pour obtenir le chemin absolu, utilisez simplement la méthode ci-dessous.

ROOT_DIR := $(abspath $(ROOT_DIR))

Son travail fonctionne bien dans GNUMake ...

0
Jerry

Faites-vous une énorme faveur et attendez-vous à ce que chaque fichier soit exécuté à partir du répertoire contenant. Pas besoin de se soucier de quelque chemin que ce soit dans n'importe quelle commande.

0