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 ?

7voto

Jesse Chisholm Points 633

J'ai essayé plusieurs de ces réponses, mais sur mon système AIX avec gnu make 3.80, j'avais besoin de faire certaines choses à l'ancienne.

Il s'avère que lastword , abspath y realpath n'ont pas été ajoutés avant la version 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 un shell deux fois, et il y a toujours le problème des espaces.

Mais comme je n'ai pas d'espace dans mes chemins, cela fonctionne pour moi, quelle que soit la façon dont j'ai commencé. make :

  • make -f ../wherever/makefile
  • make -C ../où que ce soit
  • make -C ~/wherever
  • cd ../où que ce soit ; make

Tous me donnent wherever para current_dir et le chemin absolu vers wherever para mkfile_dir .

2voto

kenorb Points 2464

Voici une ligne unique pour obtenir le chemin absolu de votre fichier Makefile en utilisant 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 Réponse @0xff :

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

Testez-le en l'imprimant, par exemple :

cwd:
        @echo $(CWD)

1voto

Peter Frost Points 61

Pour autant que je sache, c'est la seule réponse ici qui fonctionne correctement avec les espaces :

space:= 
space+=

CURRENT_PATH := $(subst $(lastword $(notdir $(MAKEFILE_LIST))),,$(subst $(space),\$(space),$(shell realpath '$(strip $(MAKEFILE_LIST))')))

Il fonctionne essentiellement en échappant aux caractères d'espacement en substituant ' ' para '\ ' ce qui permet à Make de l'analyser correctement, et ensuite il supprime le nom de fichier du makefile dans MAKEFILE_LIST en faisant une autre substitution pour que vous vous retrouviez avec le répertoire dans lequel se trouve le makefile. Ce n'est pas exactement la chose la plus compacte du monde mais cela fonctionne.

Vous obtiendrez quelque chose comme ceci, où tous les espaces sont échappés :

$(info CURRENT_PATH = $(CURRENT_PATH))

CURRENT_PATH = /mnt/c/Users/foobar/gDrive/P\ roje\ cts/we\ b/sitecompiler/

0voto

parasrish Points 2001

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

La structure du dossier pourrait être la suivante :

enter image description here

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

sample/Makefile
test/Makefile

Maintenant, voyons le contenu des Makefiles.

sample/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 le fichier sample/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'

L'explication, serait que le répertoire parent/home peut être stocké dans le drapeau d'environnement, et peut être exporté, afin qu'il puisse être utilisé dans tous les makefiles des sous-répertoires.

-1voto

Soma Bini Points 87

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

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