Que .PHONY
signifie un Makefile? J'ai vécu ça , mais c'est trop compliqué.
Quelqu'un peut-il me l'expliquer en termes simples?
la source
Que .PHONY
signifie un Makefile? J'ai vécu ça , mais c'est trop compliqué.
Quelqu'un peut-il me l'expliquer en termes simples?
Par défaut, les cibles Makefile sont des "cibles de fichiers" - elles sont utilisées pour créer des fichiers à partir d'autres fichiers. Make suppose que sa cible est un fichier, ce qui rend l'écriture de Makefiles relativement facile:
foo: bar
create_one_from_the_other foo bar
Cependant, vous souhaitez parfois que votre Makefile exécute des commandes qui ne représentent pas des fichiers physiques dans le système de fichiers. De bons exemples en sont les cibles communes «propre» et «tout». Ce n'est probablement pas le cas, mais vous pouvez potentiellement avoir un fichier nommé clean
dans votre répertoire principal. Dans un tel cas, Make sera confus parce que par défaut la clean
cible serait associée à ce fichier et Make ne l'exécutera que lorsque le fichier ne semble pas à jour en ce qui concerne 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
Exécute maintenant make clean
comme prévu même si vous avez un fichier nommé clean
.
En termes de Make, une fausse cible est simplement une cible qui est toujours obsolète, donc chaque fois que vous le demandez make <phony_target>
, elle s'exécutera, indépendamment de l'état du système de fichiers. Certaines communes make
cibles qui sont souvent faux sont: all
, install
, clean
, distclean
, TAGS
, info
, check
.
Supposons que vous ayez une
install
cible, ce qui est très courant dans les makefiles. Si vous ne pas utiliser.PHONY
, et un fichier nomméinstall
existe dans le même répertoire que le Makefile, puismake install
fera rien . En effet, Make interprète la règle comme signifiant "exécuter telle ou telle recette pour créer le fichier nomméinstall
". Puisque le fichier est déjà là et que ses dépendances n'ont pas changé, rien ne sera fait.Cependant, si vous créez la
install
PHONIE cible, il indiquera à l'outil de création que la cible est fictive, et que la marque ne doit pas s'attendre à ce qu'elle crée le fichier réel. Par conséquent, il ne vérifiera pas si leinstall
fichier existe, ce qui signifie: a) son comportement ne sera pas modifié si le fichier existe et b) extrastat()
ne sera pas appelé.Généralement, toutes les cibles de votre Makefile qui ne produisent pas de fichier de sortie portant le même nom que le nom cible doivent être PHONY. Cela comprend généralement
all
,install
,clean
,distclean
et ainsi de suite.la source
.sh
or.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 parce que j'avais un script dans le même répertoire que mon Makefile appeléinstall
.PHONY
tout le temps ....PHONY
version.REMARQUE : l'outil make lit le makefile et vérifie les horodatages de modification des fichiers à la fois du côté du symbole ':' dans une règle.
Exemple
Dans un répertoire 'test' les fichiers suivants sont présents:
Dans makefile, une règle est définie comme suit:
Supposons maintenant que le fichier «hello» est un fichier texte contenant des données, qui a été créé après le fichier «hello.c». Ainsi, l'horodatage de modification (ou de création) de «bonjour» sera plus récent que celui de «bonjour.c». Ainsi, lorsque nous invoquerons «faire bonjour» à partir de la ligne de commande, il s'affichera comme suit:
Accédez maintenant au fichier 'hello.c' et placez-y des espaces blancs, ce qui n'affecte pas la syntaxe ou 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 appelez «make hello», il exécutera les commandes comme suit:
Et le fichier 'hello' (fichier texte) sera remplacé par un nouveau fichier binaire 'hello' (résultat de la commande de compilation ci-dessus).
Si nous utilisons .PHONY dans le makefile comme suit:
puis appelez «make hello», il ignorera tout fichier présent dans le test «pwd» et exécutera la commande à chaque fois.
Supposons maintenant que cette cible 'hello' n'ait aucune dépendance déclarée:
et le fichier 'hello' est déjà présent dans le test 'pwd', alors 'make hello' apparaîtra toujours comme:
la source
make
un sens à l'ensemble, c'est une question de fichiers! Merci pour cette réponse.la source
Il s'agit d'une cible de génération qui n'est pas un nom de fichier.
la source
La meilleure explication est le manuel GNU make lui-même: 4.6 Section Phony Targets .
.PHONY
est l'un des noms de cible intégrés spéciaux de make . Il existe d'autres cibles qui pourraient vous intéresser, il vaut donc la peine de parcourir ces références.Vous pouvez également être intéressé par les cibles standard de make telles que
all
etclean
.la source
Il y a aussi un traitement délicat important de ".PHONY" - quand une cible physique dépend d'une cible bidon qui dépend d'une autre cible physique:
TARGET1 -> PHONY_FORWARDER1 -> PHONY_FORWARDER2 -> TARGET2
Vous vous attendez simplement à ce que si vous mettez à jour TARGET2, TARGET1 doit être considéré comme périmé par rapport à TARGET1, donc TARGET1 doit être reconstruit. Et cela fonctionne vraiment de cette façon .
La partie délicate est lorsque TARGET2 n'est pas périmé par rapport à TARGET1 - auquel cas vous devez vous attendre à ce que TARGET1 ne soit pas reconstruit.
Cela ne fonctionne étonnamment pas parce que: la cible bidon a quand même été exécutée (comme le font normalement les cibles bidon) , ce qui signifie que la cible bidon a été considérée comme mise à jour . Et à cause de cela, TARGET1 est considéré comme périmé par rapport à la fausse cible .
Considérer:
Vous pouvez jouer avec ceci:
Vous pouvez voir que fileall dépend indirectement de file1 via une cible bidon - mais il est toujours reconstruit en raison de cette dépendance. Si vous modifiez la dépendance
fileall
defilefwd
àfile
, maintenantfileall
ne sera pas reconstruit à chaque fois, mais uniquement lorsque l'une des cibles dépendantes est périmée en tant que fichier.la source
La cible spéciale
.PHONY:
permet de déclarer des cibles bidon, ce quimake
ne les vérifiera pas comme des noms de fichiers réels: cela fonctionnera tout le temps même si de tels fichiers existent toujours.Vous pouvez en mettre plusieurs
.PHONY:
dansMakefile
:Il existe une autre façon de déclarer des cibles bidon: il suffit de mettre '::'
Le '::' a une signification particulière: les cibles sont fausses et peuvent apparaître plusieurs fois:
Les blocs de commandes seront appelés les uns après les autres.
la source
Je les utilise souvent pour dire à la cible par défaut de ne pas tirer.
Sans PHONY,
make superclean
tireraientclean
,andsomethingelse
etcatcher superclean
; mais avec PHONY,make superclean
ne tirera pas lecatcher superclean
.Nous n'avons pas à nous soucier de dire que la
clean
cible est PHONY, car elle n'est pas complètement bidon. Bien qu'il ne produise jamais le fichier propre, il a des commandes à tirer, donc make pensera que c'est une cible finale.Cependant, la
superclean
cible est vraiment bidon, alors make essaiera de l'empiler avec tout ce qui fournit des deps pour lasuperclean
cible - cela inclut d'autressuperclean
cibles et la%
cible.Notez que nous ne disons rien du tout sur
andsomethingelse
oublah
, donc ils vont clairement au receveur.La sortie ressemble à ceci:
la source