¿Cómo obtener el directorio relativo actual de su Makefile?
Tengo varios Makefiles en directorios específicos de aplicaciones 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 configurando el destino de donde quiero que se coloquen los binarios cuando se construyan. Quiero que todos los binarios estén en su respectiva app_type
ruta:
/project1/bin/app_typeA/
He intentado usar $(CURDIR)
, así:
OUTPUT_PATH = /project1/bin/$(CURDIR)
Pero en su lugar tengo los binarios enterrados en todo el nombre de la ruta como este: (observe la redundancia)
/project1/bin/projects/users/bob/project1/apps/app_typeA
¿Qué puedo hacer para obtener el "directorio actual" de ejecución para que pueda saber solo el app_typeX
con el fin de poner los binarios en sus respectivos tipos carpeta?
11 answers
La función shell.
Puede utilizar shell
función: current_dir = $(shell pwd)
.
O shell
en combinación con notdir
, si no necesitas ruta absoluta:
current_dir = $(notdir $(shell pwd))
.
Actualización.
La solución dada solo funciona cuando se está ejecutando make
desde el directorio actual del Makefile.
Como señaló @Flimm:
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
, elcurrent_dir
la variable será/
, no/home/username/project/
.
El siguiente código funcionará para cualquiera de los Makefiles invocados desde cualquier directorio:
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))
current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path))))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-08-11 18:24:25
Tomado de aquí;
ROOT_DIR:=$(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
Aparece como;
$ cd /home/user/
$ make -f test/Makefile
/home/user/test
$ cd test; make Makefile
/home/user/test
Espero que esto ayude
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:18:22
Si está utilizando 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))
Véase la Referencia Rápida del Apéndice A en http://www.gnu.org/software/make/manual/make.html
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-06 01:07:13
THIS_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-03-16 07:45:12
Probé muchas de estas respuestas, pero en mi sistema AIX con gnu make 3.80 necesitaba hacer algunas cosas de la vieja escuela.
Resulta que lastword
, abspath
y realpath
no se añadieron 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 otros han dicho, no es el más elegante, ya que invoca un shell dos veces, y todavía tiene los problemas de espacios.
Pero como no tengo ningún espacio en mis caminos, funciona para mí sin importar cómo comencé make
:
- make-f ../wherever / makefile
- make-C ../ wherever
- make-C ~ / wherever
- cd ../ wherever; make
Todos me dan wherever
para current_dir
y el camino absoluto a wherever
para mkfile_dir
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-06 23:01:54
Juntando los ejemplos dados aquí, esto da la ruta completa al makefile:
# Get the location of this makefile.
ROOT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-07 21:18:53
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 utiliza para eliminar la barra diagonal final.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-09 19:27:07
Ejemplo para su referencia, como a continuación:
La estructura de carpetas podría 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
Test / Makefile
all:
echo ${ROOT_DIR}
echo "make test ends here !"
Ahora, ejecute el archivo de ejemplo / 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 padre / hogar el directorio puede ser almacenado en la bandera environment-flag, y puede ser exportado, para que pueda ser usado en todos los makefiles del sub-directorio.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-01-18 14:53:21
Aquí está una línea para obtener la ruta absoluta a su archivo Makefile
usando la 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)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:42
Si la variable make contiene la ruta relativa es ROOT_DIR
ROOT_DIR := ../../../
Para obtener la ruta absoluta solo use el método siguiente.
ROOT_DIR := $(abspath $(ROOT_DIR))
Funciona bien en GNUMake...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-20 05:09:50
Actualización 2018/03/05 finnaly 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 correctamente invocado por crontab. Ejecutado correctamente en otro shell.
Mostrar ejemplo, a.sh imprimir auto ruta.
[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 /]#
Antiguo: Yo uso esto:
MAKEFILE_PATH := $(PWD)/$({0%/*})
Puede mostrar correcto si se ejecuta en otro shell y otro directorio.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-05 09:55:36