Pregunta ¿Cuál es el propósito de .PHONY en un archivo MAKE?


Que hace .PHONY significa en un Makefile? He pasado por esta, pero es demasiado complicado.

¿Alguien puede explicarme en términos simples?


1207
2018-01-27 09:08


origen


Respuestas:


De forma predeterminada, los objetivos 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 escribir 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 para esto son los objetivos comunes "limpio" y "todo". Es probable que este no sea el caso, pero tú mayo potencialmente tener un archivo llamado clean en tu directorio principal. En tal caso, Make se confundirá porque, por clean target se asociará 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 falso y puede decir explícitamente Hacer que no estén asociados con archivos, p. ej .:

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

Ahora make clean funcionará 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 siempre que lo pidas make <phony_target>, se ejecutará, independientemente del estado del sistema de archivos. Algo comun make Los objetivos que a menudo son falsos son: all, install, clean, distclean, TAGS, info, check.


1341
2018-01-27 09:11



Supongamos que tienes install objetivo, que es muy común en makefiles. Si lo haces no utilizar .PHONYy un archivo llamado install existe en el mismo directorio que el Makefile, luego make install va a hacer nada. Esto se debe a que Make interpreta que la regla significa "ejecutar tal y tal receta para crear el archivo llamado install". Dado que el archivo ya está allí, y sus dependencias no cambiaron, no se hará nada.

Sin embargo, si haces el install Diríjase a PHONY, le dirá a la herramienta make que el objetivo es ficticio, y que make no debe esperar que cree el archivo real. Por lo tanto, no verificará si install existe un archivo, lo que significa que: a) su comportamiento no se verá alterado si el archivo existe yb) extra stat() no será llamado.

En general, todos los destinos en su Makefile que no producen un archivo de salida con el mismo nombre que el nombre del objetivo deben ser PHONY. Esto generalmente incluye all, install, clean, distclean, y así.


636
2017-08-26 10:54



NOTA: La herramienta make 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 'test' están presentes los siguientes archivos:

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

En makefile, una regla se define de la siguiente manera:

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 'hello.c'. Por lo tanto, la marca de tiempo de modificación (o creación) de 'hola' será más nueva que la de 'hola.c'. Entonces cuando invoquemos 'make hello' desde la línea de comando, se imprimirá como:

make: `hello' is up to date.

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

cc hello.c -o hello

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

Si usamos .PHONY en el archivo MAKE de la siguiente manera:

.PHONY:hello

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

y luego invocar 'hacer hola', ignorará si algún archivo presente en el pwd llamado 'hola' y ejecutará el comando cada vez.

Ahora supongamos que si no hay dependencias de destino en el archivo MAKE:

hello:
    cc hello.c -o hello

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

make: `hello' is up to date.

64
2017-09-30 14:51



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

63
2017-08-25 22:39



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


34
2018-01-27 16:48



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

.PHONY es una de las marcas Nombres de diana incorporados especiales. Hay otros objetivos en los que puede estar interesado, por lo que vale la pena revisar estas referencias.

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

Usted también podría estar interesado en make's Objetivos estándar como all y clean.


21
2018-04-03 23:49



También hay un truco 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

Simplemente esperaría que si actualizó TARGET2, entonces TARGET1 se considere obsoleto contra TARGET1, por lo que TARGET1 debería reconstruirse. Y realmente funciona de esta manera.

La parte difícil es cuando TARGET2 no es obsoleto contra TARGET1 - en cuyo caso debe esperar que TARGET1 no se vuelva a generar.

Sorprendentemente, esto no funciona porque: el objetivo falso se ejecutó de todos modos (como normalmente lo hacen los objetivos falsos), Lo que significa que el objetivo falso se consideró actualizado. A causa de 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"
  • jugar con eso tocando archivos particulares para verlos actualizados

Puedes ver que el archivo depende del archivo1 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 todo el tiempo, sino solo cuando alguno de los objetivos dependientes está obsoleto contra él como un archivo.


8
2018-02-11 10:11



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

superclean: clean andsomethingelse

blah: superclean

clean:
   @echo clean

%:
   @echo catcher $@

.PHONY: superclean

Sin PHONY, make superclean dispararía clean, andsomethingelsey catcher superclean; pero con PHONY, make superclean no disparará el catcher superclean.

No tenemos que preocuparnos de decir hacer el clean el objetivo es PHONY, porque no es completamente falso. A pesar de que nunca produce el archivo limpio, tiene comandos para disparar, por lo que hará pensar que es un objetivo final.

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

Tenga en cuenta que no decimos nada en absoluto sobre andsomethingelse o blah, así que claramente van al receptor.

El resultado se ve así:

$ make clean
clean

$ make superclean
clean
catcher andsomethingelse

$ make blah 
clean
catcher andsomethingelse
catcher blah

0
2017-07-08 13:22