Ruta del directorio de archivo MAKU común

Estoy tratando de consolidar cierta información de comstackción utilizando un archivo MAKE común. Mi problema es que quiero usar ese archivo make desde diferentes niveles de subdirectorio, lo que hace que el valor del directorio de trabajo ( pwd ) sea impredecible. Por ejemplo:

 # Makefile.common TOP := $(shell pwd) COMPONENT_DIR := $(TOP)/component COMPONENT_INC := $(COMPONENT_DIR)/include COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a 

Si Makefile.common desde un subdirectorio, el directorio $(TOP) es incorrecto y todo lo demás sigue su ejemplo:

 # other_component/Makefile include ../Makefile.common # $(COMPONENT_LIB) is incorrectly other_component/component 

¿Cuál es la mejor manera de hacer que Makefile.common use su propia ruta de directorio en lugar de la pwd más voluble?

Debería poder usar la variable MAKEFILE_LIST , así:

 # This must be the first line in Makefile.common TOP := $(dir $(lastword $(MAKEFILE_LIST))) 

De la documentación:

Cuando make lea varios archivos make, incluidos los obtenidos de la variable MAKEFILES, la línea de comandos, los archivos predeterminados o las directivas include, sus nombres se agregarán automáticamente a la variable MAKEFILE_LIST. Se agregan justo antes de que make comience a analizarlos. Esto significa que si lo primero que hace un archivo MAKE es examinar la última palabra en esta variable, será el nombre del archivo MAKE actual. Una vez que se haya utilizado el archivo MAKE actual, sin embargo, la última palabra será el archivo MAKE recién incluido.

Este no es un buen estilo porque agrega otra dependencia (es decir, el binario realpath). Dependiendo de su caso de uso, eso puede ser aceptable.

 ROOT_DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST)))) 

Si no tiene instalado realpath:

 $ sudo apt-get install realpath # on debian and derivatives 

Editar : asegúrese de usar := lugar de = porque este último hace make use el enlace de MAKEFILE_LIST y MAKEFILE_LIST puede haber cambiado debido a las MAKEFILE_LIST posteriores.

Has intentado hacer:

 # Makefile.common TOP ?= $(shell pwd) COMPONENT_DIR := $(TOP)/component COMPONENT_INC := $(COMPONENT_DIR)/include COMPONENT_LIB := $(COMPONENT_DIR)/libcomponent.a # other_component/Makefile TOP ?= .. include ../Makefile.common 

Usar el constructo? = Evitará que redefinan TOP si ya está configurado. Puede establecerlo en el valor apropiado en función de dónde se encuentre en el árbol cuando invoque make. Confieso que ha pasado un tiempo desde que usé GNU make, por lo que es posible que esto no funcione o necesite algunos ajustes.

Mi solución:

 cwd := $(shell readlink -en $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))) 

Esto también funciona para llamadas como make -f /opt/some/dir/Makefile cuando estás en /opt/other/path/subdir .

simplemente escriba las cosas comunes en common.mk . A continuación, coloque el campo common.mk es la carpeta predeterminada que Make busca cuando encuentra una instrucción include common.mk.

Ver ayuda para carpetas comunes. Buscar. También puede poner common.mk en su carpeta de inicio y luego escribir make -I$HOME desde cualquier carpeta.

Dentro del Makefile en cada subcarpeta, simplemente haces

 include common.mk 

Eso es todo. No hay necesidad de preocuparse por el camino y mover las cosas.