make instalar entre ejecutar diferencia con compilar como comando makefile gnu-make

instalar - makefile linux c



¿Cómo escribo el comando ''cd'' en un makefile? (6)

Por ejemplo, tengo algo como esto en mi makefile:

all: cd some_directory

Pero cuando escribí make solo vi ''cd some_directory'', como en el comando echo .


¿Qué quieres que haga una vez que llegue allí? Cada comando se ejecuta en una subshell, por lo que la subshell cambia de directorio, pero el resultado final es que el siguiente comando aún se encuentra en el directorio actual.

Con GNU make, puedes hacer algo como:

BIN=/bin foo: $(shell cd $(BIN); ls)


A partir de la .ONESHELL GNU make 3.82 de GNU make 3.82 , puede usar el objetivo especial .ONESHELL para ejecutar todas las líneas de receta en una única instancia del shell (énfasis en negrita mío):

  • Nuevo objetivo especial: .ONESHELL indica a make que invoque una única instancia del shell y le proporcione la receta completa , independientemente de la cantidad de líneas que contenga. [...]

.ONESHELL: all: cd ~/some_dir pwd # Prints ~/some_dir if cd succeeded


Aquí hay un lindo truco para lidiar con directorios y hacer. En lugar de utilizar cadenas multilínea, o "cd;" en cada comando, define una función chdir simple como tal:

CHDIR_SHELL := $(SHELL) define chdir $(eval _D=$(firstword $(1) $(@D))) $(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL)) endef

Entonces todo lo que tienes que hacer es llamarlo en tu regla como tal:

all: $(call chdir,some_dir) echo "I''m now always in some_dir" gcc -Wall -o myTest myTest.c

Incluso puedes hacer lo siguiente:

some_dir/myTest: $(call chdir) echo "I''m now always in some_dir" gcc -Wall -o myTest myTest.c


En realidad, está ejecutando el comando, cambiando el directorio a some_directory , sin embargo, esto se realiza en un shell de subproceso y no afecta ni a make ni al shell en el que se está trabajando.

Si desea realizar más tareas dentro de some_directory , debe agregar un punto y coma y agregar los otros comandos también. Tenga en cuenta que no puede usar las nuevas líneas tal como se interpretan por make como el final de la regla, por lo que cualquier nueva línea que use para la claridad debe escaparse con una barra invertida.

Por ejemplo:

all: cd some_dir; echo "I''m in some_dir"; / gcc -Wall -o myTest myTest.c

Tenga en cuenta también que el punto y coma es necesario entre cada comando, aunque agregue una barra diagonal inversa y una nueva línea. Esto se debe al hecho de que el shell analiza toda la cadena como una sola línea. Como se señaló en los comentarios, debe usar ''&&'' para unir comandos, lo que significa que solo se ejecutan si el comando anterior fue exitoso.

all: cd some_dir && echo "I''m in some_dir" && / gcc -Wall -o myTest myTest.c

Esto es especialmente importante cuando se realiza un trabajo destructivo, como la limpieza, ya que de lo contrario destruirá las cosas equivocadas, en caso de que el cd falle por cualquier motivo.

Sin embargo, un uso común es llamar a make en el subdirectorio, que es posible que desee examinar. Hay una opción de línea de comando para esto, por lo que no tiene que llamar a cd , por lo que su regla se vería así.

all: $(MAKE) -C some_dir all

que cambiará en some_dir y ejecutará el Makefile allí con el objetivo "all". Como práctica recomendada, use $(MAKE) lugar de llamar a make directamente, ya que se encargará de llamar a la instancia de make correcta (si, por ejemplo, utiliza una versión de make especial para su entorno de compilación), así como también Comportamiento ligeramente diferente cuando se ejecuta con ciertos conmutadores, como -t .

Para el registro, siempre haga un eco del comando que ejecuta (a menos que se suprima explícitamente), incluso si no tiene salida, que es lo que está viendo.


Me gusta esto:

target: $(shell cd ....); / # ... commands execution in this directory # ... no need to go back (using "cd -" or so) # ... next target will be automatically in prev dir

¡Buena suerte!


Para cambiar dir

foo: $(MAKE) -C mydir multi: $(MAKE) -C / -C my-custom-dir ## Equivalent to /my-custom-dir