2046 votes

Quel est le but de .PHONY dans un Makefile ?

Que signifie .PHONY dans un Makefile? J'ai parcouru ceci, mais c'est trop compliqué.

Est-ce que quelqu'un peut m'expliquer simplement?

2319voto

Eli Bendersky Points 82298

Par défaut, les cibles des Makefile sont des "cibles de fichiers" - elles sont utilisées pour construire des fichiers à partir d'autres fichiers. Make suppose que sa cible est un fichier, et cela rend relativement facile l'écriture des Makefiles :

foo: bar
  create_one_from_the_other foo bar

Cependant, parfois, vous voulez que votre Makefile exécute des commandes qui ne représentent pas des fichiers physiques dans le système de fichiers. De bons exemples de ceci sont les cibles communes "clean" et "all". Il y a des chances que ce ne soit pas le cas, mais vous pourriez éventuellement avoir un fichier nommé clean dans votre répertoire principal. Dans un tel cas, Make sera confus car par défaut la cible clean serait associée à ce fichier et Make ne l'exécutera que lorsque le fichier ne semble pas être à jour par rapport à ses dépendances.

Ces cibles spéciales sont appelées fausses et vous pouvez dire explicitement à Make qu'elles ne sont pas associées à des fichiers, par exemple :

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

Maintenant, make clean s'exécutera comme prévu même si vous avez un fichier nommé clean.

En termes de Make, une cible fausse est simplement une cible qui est toujours obsolète, donc chaque fois que vous demandez make , elle s'exécutera, indépendamment de l'état du système de fichiers. Certaines cibles make couramment fausses sont : all, install, clean, distclean, TAGS, info, check.

Voir aussi : Manuel GNU make : Cibles Faux

1 votes

Je pense que j'ai maintenant une idée à ce sujet (après avoir consulté le lien que vous avez mentionné). Au fait, pourquoi est-ce appelé "faux" ?

63 votes

@eSKay: 'pourquoi est-ce appelé 'faux' ?' -- parce que ce n'est pas une cible réelle. Autrement dit, le nom de la cible n'est pas un fichier produit par les commandes de cette cible.

119 votes

@Lazer: Je ne sais pas si vous êtes un locuteur natif de l'anglais. Je ne le suis pas. Le mot "phony" ne signifie pas ce qu'il semble. en.wiktionary.org/wiki/phony dit : Frauduleux ; faux ; ayant une apparence trompeuse.

774voto

George Y. Points 4269

Supposons que vous avez une cible install, ce qui est très courant dans les makefiles. Si vous n'utilisez pas .PHONY, et qu'un fichier nommé install existe dans le même répertoire que le Makefile, alors make install ne fera rien. En effet, Make interprète la règle comme "exécuter telle ou telle recette pour créer le fichier nommé install". Comme le fichier est déjà là, et que ses dépendances n'ont pas changé, rien ne sera fait.

Cependant, si vous déclarez la cible install comme PHONY, cela indiquera à l'outil make que la cible est fictive, et que make ne doit pas s'attendre à ce qu'elle crée le fichier réel. Ainsi, il ne vérifiera pas si le fichier install existe, ce qui signifie : a) son comportement ne sera pas modifié si le fichier existe et b) aucun appel supplémentaire à stat() ne sera fait.

En général, toutes les cibles de votre Makefile qui ne produisent pas de fichier de sortie portant le même nom que la cible doivent être déclarées comme PHONY. Cela inclut généralement all, install, clean, distclean, et ainsi de suite.

6 votes

@PineappleUndertheSea La réponse acceptée a été considérablement améliorée depuis son niveau initial d'inutilité, et est désormais aussi bonne que celle-ci. J'ai dû consulter son historique de révisions pour comprendre votre commentaire.

2 votes

Il semble un peu inutile puisque je n'aurai jamais de fichiers nommés 'install' ou similaire dans ma base de code. La plupart des fichiers auront une extension de fichier, et les fichiers sans extension de fichier sont généralement en majuscules, comme 'README'. Mais encore une fois, si vous avez un script bash nommé 'install' au lieu de 'install.sh', vous allez passer un mauvais moment.

8 votes

@JasonTu Ce n'est pas nécessairement vrai. Les conventions de script Bash vous demandent d'omettre l'extension .sh ou .bash pour les "programmes" qui s'exécutent comme s'ils avaient une fonction principale et de réserver l'ajout d'une extension pour les bibliothèques que vous incluez (source mylib.sh). En fait, je suis arrivé à cette question SO car j'avais un script dans le même répertoire que mon Makefile appelé install

151voto

prerit jain Points 21

REMARQUE : L'outil make lit le makefile et vérifie les horodatages de modification des fichiers des deux côtés du symbole ':' dans une règle.

Exemple

Dans un répertoire 'test' les fichiers suivants sont présents :

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

Dans le makefile une règle est définie comme suit :

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

Supposez maintenant que le fichier 'hello' est un fichier texte contenant des données, qui a été créé après le fichier 'hello.c'. Donc l'horodatage de modification (ou création) de 'hello' sera plus récent que celui de 'hello.c'. Donc lorsque nous allons invoquer 'make hello' depuis la ligne de commande, il affichera :

make: `hello' est à jour.

Accédez maintenant au fichier 'hello.c' et ajoutez des espaces blancs, ce qui n'affecte ni la syntaxe ni la logique du code, puis enregistrez et quittez. Maintenant l'horodatage de modification de hello.c est plus récent que celui de 'hello'. Maintenant si vous invoquez 'make hello', il exécutera les commandes comme suit :

cc hello.c -o hello

Et le fichier 'hello' (fichier texte) sera écrasé par un nouveau fichier binaire 'hello' (résultat de la commande de compilation ci-dessus).

Si nous utilisons .PHONY dans le makefile comme suit :

.PHONY:hello

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

puis invoquez 'make hello', il ignorera tout fichier présent dans le répertoire de travail 'test' et exécutera la commande à chaque fois.

Supposons maintenant que la cible 'hello' n'a pas de dépendances déclarées :

hello:
    cc hello.c -o hello

et que le fichier 'hello' est déjà présent dans le répertoire de travail 'test', alors 'make hello' affichera toujours :

make: `hello' est à jour.

7 votes

Non seulement cela rend les commandes que j'exécute logiques, mais cela donne enfin du sens à make dans son ensemble, tout tourne autour des fichiers ! Merci pour cette réponse.

0 votes

Voici à quoi ressemble une règle simple : ``` target: dependencies ... commands ... ``` Ref: gnu.org/software/make

85voto

YourBestBet Points 411
.PHONY: installer
  • signifie que le mot "install" ne représente pas un nom de fichier dans ce Makefile;
  • signifie que le Makefile n'a rien à voir avec un fichier appelé "install" dans le même répertoire.

46voto

JohnMcG Points 5062

C'est une cible de construction qui n'est pas un nom de fichier.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X