urls una rutas ruta relativos relativas relativa qué ejemplo acceso absolutos absolutas absoluta makefile gnu-make current-dir

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 ejecuta cd /; make -f /home/username/project/Makefile cd /; make -f /home/username/project/Makefile , la variable current_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))))