makefile ejecutar otro objetivo

122

Tengo un archivo MAKE estructurado algo como esto:

all : 
    compile executable

clean :
    rm -f *.o $(EXEC)

Me di cuenta de que estaba ejecutando constantemente "make clean" seguido de "clear" en mi terminal antes de ejecutar "make all". Me gusta tener una terminal limpia antes de intentar examinar los desagradables errores de compilación de C ++. Así que intenté agregar un tercer objetivo:

fresh :
    rm -f *.o $(EXEC)
    clear
    make all

Esto funciona, sin embargo, esto ejecuta una segunda instancia de make (creo). ¿Existe una forma correcta de obtener la misma funcionalidad sin ejecutar una segunda instancia de make?

sas4740
fuente

Respuestas:

171

De hecho, tiene razón: ejecuta otra instancia de make. Una posible solución sería:

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : clean clearscr all

clearscr:
    clear

Al llamar make fresh, obtiene primero el cleanobjetivo, luego el clearscreenque se ejecuta cleary finalmente el allque hace el trabajo.

EDITAR 4 de agosto

¿Qué sucede en el caso de compilaciones paralelas con la -jopción de make ? Hay una forma de arreglar el orden. Del manual de marca, sección 4.2:

De vez en cuando, sin embargo, tiene una situación en la que desea imponer un orden específico en las reglas que se invocarán sin forzar la actualización del objetivo si se ejecuta una de esas reglas. En ese caso, desea definir requisitos previos de solo pedido. Los requisitos previos de solo pedido se pueden especificar colocando un símbolo de barra vertical (|) en la lista de requisitos previos: cualquier requisito previo a la izquierda del símbolo de barra vertical es normal; los requisitos previos a la derecha son solo de orden: objetivos: requisitos previos normales | requisitos previos de solo pedido

La sección de requisitos previos normal, por supuesto, puede estar vacía. Además, aún puede declarar varias líneas de requisitos previos para el mismo objetivo: se agregan de manera apropiada. Tenga en cuenta que si declara que el mismo archivo es un requisito previo tanto normal como de solo pedido, el requisito previo normal tiene prioridad (ya que son un superconjunto estricto del comportamiento de un requisito previo de solo pedido).

Por lo tanto, el archivo MAKE se convierte en

.PHONY : clearscr fresh clean all

all :
    compile executable

clean :
    rm -f *.o $(EXEC)

fresh : | clean clearscr all

clearscr:
    clear

EDITAR 5 de diciembre

No es gran cosa ejecutar más de una instancia de makefile ya que cada comando dentro de la tarea será un sub-shell de todos modos. Pero puede tener métodos reutilizables usando la función de llamada .

log_success = (echo "\x1B[32m>> $1\x1B[39m")
log_error = (>&2 echo "\x1B[31m>> $1\x1B[39m" && exit 1)

install:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  command1  # this line will be a subshell
  command2  # this line will be another subshell
  @command3  # Use `@` to hide the command line
  $(call log_error, "It works, yey!")

uninstall:
  @[ "$(AWS_PROFILE)" ] || $(call log_error, "AWS_PROFILE not set!")
  ....
  $(call log_error, "Nuked!")
Dacav
fuente
6
@ sas4740: básicamente todo lo que sigue .PHONY : se trata como una palabra clave que siempre se ejecuta, mientras que los objetivos no falsos deben ser archivos.
Dacav
¿Son condicionales los "requisitos previos de solo pedido"? para el objetivo t2, primero quiero hacer t0, que solo si t0 tiene éxito en ejecutar t1, y solo si ambos tienen éxito ejecutan alguna tarea en t3
fantastory
1
@fantastory, no, creo que son independientes. t2dependerá de t0, t1y t3. Si lo necesita, debe colocarlo t3como lo requiere t2, lo t1que lo requiera t3y lo t0que lo requiera t1. Esto significa 3 reglas diferentes. Sin embargo, debe verificar esto. No estoy 100% seguro.
Dacav
3
Los "requisitos previos de solo pedido" son independientes
fantastory
2
No veo dónde está la garantía de que "limpio" funciona antes que "todo". El hecho de que los coloques directamente desde | no hace que se ejecuten en orden. La dependencia de solo pedido significa que el destino no se actualiza necesariamente después de dicha operación. No tiene nada que ver con la ordenación de los elementos dependientes ... ¿o?
CygnusX1
6

Si eliminó la make alllínea de su objetivo "nuevo":

fresh :
    rm -f *.o $(EXEC)
    clear

Simplemente puede ejecutar el comando make fresh all, que se ejecutará como make fresh; make all.

Algunos podrían considerar esto como una segunda instancia de make, pero ciertamente no es una subinstancia de make (un make dentro de un make), que es en lo que pareció resultar su intento.

codenaugh
fuente