makefile - una - url relativos y absolutos
¿Cómo obtener el directorio relativo actual de tu Makefile? (11)
La función de shell.
Puede usar la función de shell
: current_dir = $(shell pwd)
. O shell
en combinación con notdir
, si no necesita la ruta absoluta: current_dir = $(notdir $(shell pwd))
.
Actualizar.
La solución dada solo funciona cuando ejecuta make
desde el directorio actual de Makefile.
Como @Flimm señaló:
Tenga en cuenta que esto devuelve el directorio de trabajo actual, no el directorio padre del Makefile.
Por ejemplo, si ejecutacd /; make -f /home/username/project/Makefile
cd /; make -f /home/username/project/Makefile
, la variablecurrent_dir
será/
, not/home/username/project/
.
El siguiente código funcionará para cualquiera de los archivos Makefiles invocados desde cualquier directorio:
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
Tengo varios Makefiles en directorios específicos de la aplicación como este:
/project1/apps/app_typeA/Makefile
/project1/apps/app_typeB/Makefile
/project1/apps/app_typeC/Makefile
Cada Makefile incluye un archivo .inc en esta ruta un nivel más arriba:
/project1/apps/app_rules.inc
Dentro de app_rules.inc, estoy estableciendo el destino de donde quiero que se coloquen los binarios cuando se construye. Quiero que todos los binarios estén en su respectiva ruta de tipo de aplicación:
/project1/bin/app_typeA/
Intenté usar $(CURDIR)
, así:
OUTPUT_PATH = /project1/bin/$(CURDIR)
pero en su lugar obtuve los binarios enterrados en el nombre completo de la ruta de la siguiente manera: (fíjate en la redundancia)
/project1/bin/projects/users/bob/project1/apps/app_typeA
¿Qué puedo hacer para obtener el "directorio actual" de ejecución para poder conocer solo el app_typeX
para poner los binarios en su respectiva carpeta de tipos?
Aquí hay una línea para obtener una ruta absoluta a su archivo Makefile
usando sintaxis de shell:
SHELL := /bin/bash
CWD := $(shell cd -P -- ''$(shell dirname -- "$0")'' && pwd -P)
Y aquí está la versión sin shell basada en @ 0xff respuesta :
CWD=$(abspath $(patsubst %/,%,$(dir $(abspath $(lastword $(MAKEFILE_LIST))))))
Pruébelo imprimiéndolo, como:
cwd:
@echo $(CWD)
Como tomado de here ;
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
Se muestra como;
$ cd /home/user/
$ make -f test/Makefile
/home/user/test
$ cd test; make Makefile
/home/user/test
Espero que esto ayude
Ejemplo para su referencia, como a continuación:
La estructura de la carpeta puede ser como:
Donde hay dos Makefiles, cada uno como abajo;
sample/Makefile
test/Makefile
Ahora, veamos el contenido de los Makefiles.
sample / Makefile
export ROOT_DIR=${PWD}
all:
echo ${ROOT_DIR}
$(MAKE) -C test
prueba / Makefile
all:
echo ${ROOT_DIR}
echo "make test ends here !"
Ahora, ejecute la muestra / Makefile, como;
cd sample
make
SALIDA:
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''
Explicación, sería que el directorio padre / home se puede almacenar en el indicador de entorno y se puede exportar, de modo que se pueda usar en todos los archivos make del subdirectorio.
Intenté muchas de estas respuestas, pero en mi sistema AIX con gnu make 3.80 tenía que hacer algunas cosas en la vieja escuela.
Resulta que la lastword
, abspath
y realpath
no se agregaron hasta 3.81. :(
mkfile_path := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
mkfile_dir:=$(shell cd $(shell dirname $(mkfile_path)); pwd)
current_dir:=$(notdir $(mkfile_dir))
Como han dicho otros, no es el más elegante ya que invoca un caparazón dos veces, y todavía tiene los problemas de espacios.
Pero como no tengo ningún espacio en mi camino, funciona para mí independientemente de cómo comencé a make
:
- make -f ../whereVER/makefile
- hacer -C ../wherever
- hacer -C ~ / donde sea
- cd ../wherewhere; hacer
Todos me dan wherever
para current_dir
y la ruta absoluta a wherever
para mkfile_dir
.
Me gusta la respuesta elegida, pero creo que sería más útil mostrarla funcionando que explicarla.
/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
Salida:
+ 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
NOTA: La función $(patsubst %/,%,[path/goes/here/])
se usa para quitar la barra inclinada.
Poniendo juntos los ejemplos dados aquí, esto da la ruta completa al archivo MAKE:
# Get the location of this makefile.
ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
Si está usando GNU make, $ (CURDIR) es en realidad una variable incorporada. Es la ubicación donde reside el Makefile el directorio de trabajo actual, que es probablemente donde está el Makefile, pero no siempre .
OUTPUT_PATH = /project1/bin/$(notdir $(CURDIR))
Consulte el Apéndice A Referencia rápida en http://www.gnu.org/software/make/manual/make.html
Si la variable make contiene la ruta relativa es ROOT_DIR
ROOT_DIR := ../../../
Ellos para obtener la ruta absoluta solo use el método a continuación.
ROOT_DIR := $(abspath $(ROOT_DIR))
Funciona bien en GNUMake ...
actualización 2018/03/05 finnaly Yo uso esto:
shellPath=`echo $PWD/``echo ${0%/*}`
# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == ''/'' ] ; then
shellPath=${shellPath2}
fi
Se puede ejecutar correctamente en ruta relativa o ruta absoluta. Ejecutado correcto invocado por crontab. Ejecutado correcto en otro shell.
muestra un ejemplo, a.sh print self path.
[root@izbp1a7wyzv7b5hitowq2yz /]# more /root/test/a.sh
shellPath=`echo $PWD/``echo ${0%/*}`
# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == ''/'' ] ; then
shellPath=${shellPath2}
fi
echo $shellPath
[root@izbp1a7wyzv7b5hitowq2yz /]# more /root/b.sh
shellPath=`echo $PWD/``echo ${0%/*}`
# process absolute path
shellPath1=`echo $PWD/`
shellPath2=`echo ${0%/*}`
if [ ${shellPath2:0:1} == ''/'' ] ; then
shellPath=${shellPath2}
fi
$shellPath/test/a.sh
[root@izbp1a7wyzv7b5hitowq2yz /]# ~/b.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]# /root/b.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]# cd ~
[root@izbp1a7wyzv7b5hitowq2yz ~]# ./b.sh
/root/./test
[root@izbp1a7wyzv7b5hitowq2yz ~]# test/a.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz ~]# cd test
[root@izbp1a7wyzv7b5hitowq2yz test]# ./a.sh
/root/test/.
[root@izbp1a7wyzv7b5hitowq2yz test]# cd /
[root@izbp1a7wyzv7b5hitowq2yz /]# /root/test/a.sh
/root/test
[root@izbp1a7wyzv7b5hitowq2yz /]#
viejo: uso esto:
MAKEFILE_PATH := $(PWD)/$({0%/*})
Puede mostrarse correcto si se ejecuta en otro shell y otro directorio.
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))