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_typeX
afin de placer les fichiers binaires dans leurs dossiers de types respectifs?
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))
.
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écutezcd /; make -f /home/username/project/Makefile
, la variablecurrent_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))))
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
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
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
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
:
Tous me donnent wherever
pour current_dir
et le chemin d'accès absolu à wherever
pour mkfile_dir
.
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
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.
Exemple pour votre référence, comme ci-dessous:
La structure du dossier peut être la suivante:
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.
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)
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 ...
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.