que make comando archivo makefile phony-target

comando - makefile ubuntu



¿Cuál es el propósito de.PHONY en un makefile? (8)

¿Qué significa .PHONY en un Makefile? He pasado por this , pero es demasiado complicado.

¿Puede alguien explicármelo en términos simples?


A menudo los uso para decirle al objetivo predeterminado que no dispare.

superclean: clean andsomethingelse blah: superclean clean: @echo clean %: @echo catcher $@ .PHONY: superclean

Sin PHONY, make superclean dispararía clean , y andsomethingelse , y catcher superclean ; pero con PHONY, make superclean no disparará al catcher superclean .

No tenemos que preocuparnos por decirle que el objetivo clean es PHONY, porque no es completamente falso. Aunque nunca produce el archivo limpio, tiene comandos para disparar, así que make pensará que es un objetivo final.

Sin embargo, el objetivo superclean es realmente falso, por lo que make intentará apilarlo con cualquier otra cosa que proporcione deps para el objetivo superclean , esto incluye otros objetivos superclean y el objetivo % .

Tenga en cuenta que no decimos nada en absoluto acerca de andsomethingelse o de andsomethingelse como blah , por lo que claramente van al receptor.

La salida se ve algo como esto:

$ make clean clean $ make superclean clean catcher andsomethingelse $ make blah clean catcher andsomethingelse catcher blah


De forma predeterminada, los destinos de Makefile son "objetivos de archivo", se utilizan para crear archivos a partir de otros archivos. Make asume que su objetivo es un archivo, y esto hace que la creación de Makefiles sea relativamente fácil:

foo: bar create_one_from_the_other foo bar

Sin embargo, a veces desea que su Makefile ejecute comandos que no representan archivos físicos en el sistema de archivos. Buenos ejemplos de esto son los objetivos comunes "limpio" y "todos". Es probable que este no sea el caso, pero es posible que tenga un archivo llamado clean en su directorio principal. En tal caso, Make se confundirá porque, de forma predeterminada, el objetivo clean estaría asociado con este archivo y Make solo lo ejecutará cuando el archivo no parezca estar actualizado con respecto a sus dependencias.

Estos objetivos especiales se llaman falsos y puede indicar explícitamente a Make que no están asociados con archivos, por ejemplo:

.PHONY: clean clean: rm -rf *.o

Ahora make clean se ejecutará como se espera, incluso si tiene un archivo llamado clean .

En términos de Make, un objetivo falso es simplemente un objetivo que siempre está desactualizado, por lo que cada vez que solicite make <phony_target> , se ejecutará, independientemente del estado del sistema de archivos. Algunos objetivos comunes de make que suelen ser falsos son: all , install , clean , distclean , TAGS , info , check .


Es un objetivo de compilación que no es un nombre de archivo.


La mejor explicación es el propio manual GNU make: 4.6 Sección de objetivos falsos .

.PHONY es uno de los Nombres de objetivos incorporados especiales de make. Hay otros objetivos que le pueden interesar, por lo que vale la pena hojear estas referencias.

Cuando sea el momento de considerar un objetivo .PHONY, make ejecutará su receta incondicionalmente, sin importar si existe un archivo con ese nombre o cuál es su hora de última modificación.

También te pueden interesar los objetivos estándar de make, como all and clean .


Supongamos que tiene un destino de install , que es muy común en makefiles. Si no usa .PHONY , y existe un archivo llamado install en el mismo directorio que Makefile, make install no hará nada . Esto se debe a que Make interpreta la regla para que signifique "ejecutar tal y cual receta para crear el archivo llamado install ". Como el archivo ya está allí y sus dependencias no cambiaron, no se hará nada.

Sin embargo, si hace que el objetivo de la install PHONY, le dirá a la herramienta make que el objetivo es ficticio y que no debe esperar que cree el archivo real. Por lo tanto, no comprobará si existe el archivo de install , lo que significa que: a) su comportamiento no se modificará si el archivo existe yb) extra stat() no se llamará.

En general, todos los destinos en su Makefile que no produzcan un archivo de salida con el mismo nombre que el nombre del objetivo deben ser PHONY. Esto normalmente incluye all , install , clean , distclean , etc.


También hay un tratamiento delicado importante de ".PHONY": cuando un objetivo físico depende de un objetivo falso que depende de otro objetivo físico:

TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2

Usted simplemente esperaría que si actualizase TARGET2, entonces TARGET1 debería considerarse obsoleto contra TARGET1, por lo que TARGET1 debería reconstruirse. Y realmente funciona de esta manera .

La parte difícil es cuando TARGET2 no está obsoleto contra TARGET1, en cuyo caso debe esperar que TARGET1 no se reconstruya.

Esto sorprendentemente no funciona porque: el objetivo falso se ejecutó de todos modos (como lo hacen normalmente los objetivos falsos) , lo que significa que el objetivo falso se consideró actualizado . Y debido a eso, TARGET1 se considera obsoleto contra el objetivo falso .

Considerar:

all: fileall fileall: file2 filefwd echo file2 file1 >fileall file2: file2.src echo file2.src >file2 file1: file1.src echo file1.src >file1 echo file1.src >>file1 .PHONY: filefwd .PHONY: filefwd2 filefwd: filefwd2 filefwd2: file1 @echo "Produced target file1" prepare: echo "Some text 1" >> file1.src echo "Some text 2" >> file2.src

Puedes jugar con esto:

  • Primero haz ''preparar'' para preparar los "archivos fuente"
  • juega con eso tocando archivos particulares para verlos actualizados

Puede ver que fileall depende de file1 indirectamente a través de un objetivo falso, pero siempre se reconstruye debido a esta dependencia. Si cambia la dependencia en fileall de filefwd a file , ahora fileall no se reconstruye cada vez, pero solo cuando cualquiera de los objetivos dependientes está obsoleto como archivo.


NOTA : La herramienta de fabricación lee el archivo MAKE y verifica las marcas de tiempo de modificación de los archivos en ambos lados del símbolo '':'' en una regla.

Ejemplo

En un directorio ''prueba'' están presentes los siguientes archivos:

prerit@vvdn105:~/test$ ls hello hello.c makefile

En makefile una regla se define como sigue:

hello:hello.c cc hello.c -o hello

Ahora suponga que el archivo ''hola'' es un archivo de texto que contiene algunos datos, que se creó después del archivo ''hola.c''. Por lo tanto, la modificación (o creación) de la marca de tiempo de ''hola'' será más nueva que la de ''hola.c''. Entonces, cuando invocaremos ''make hello'' desde la línea de comando, se imprimirá como:

make: `hello'' is up to date.

Ahora acceda al archivo ''hello.c'' y coloque algunos espacios en blanco en él, lo que no afecta la sintaxis o la lógica del código, y luego guarde y salga. Ahora la modificación de la marca de tiempo de hello.c es más reciente que la de ''hello''. Ahora, si invoca ''make hello'', ejecutará los comandos como:

cc hello.c -o hello

Y el archivo ''hola'' (archivo de texto) se sobrescribirá con un nuevo archivo binario ''hola'' (resultado del comando de compilación anterior).

Si usamos .PHONY en makefile como sigue:

.PHONY:hello hello:hello.c cc hello.c -o hello

y luego invoca ''make hello'', ignorará si algún archivo presente en el pwd llamado ''hello'' y ejecutará el comando cada vez.

Ahora suponga que si no hay dependencias de destino en makefile:

hello: cc hello.c -o hello

y el archivo ''hola'' ya está presente en la ''prueba'' de pwd, entonces ''hola'' siempre se mostrará como:

make: `hello'' is up to date.


.PHONY: install

  • significa que la palabra "instalar" no representa un nombre de archivo en este Makefile;
  • significa que Makefile no tiene nada que ver con un archivo llamado "instalar" en el mismo directorio.