2010-03-16 3 views
3

J'utilise un fichier makefile pour automatiser la génération de certains documents. J'ai plusieurs documents dans un répertoire, et une de mes règles makefile va générer une page d'index de ces fichiers. La liste des fichiers elle-même est chargée à la volée en utilisant list := $(shell ls documents/*.txt), donc je n'ai pas à déranger manuellement la modification du fichier makefile chaque fois que j'ajoute, supprime ou renommer un document. Naturellement, je veux que la règle de génération d'index se déclenche lorsque le nombre/titre des fichiers dans le répertoire de documents change, mais je ne sais pas comment configurer les conditions préalables pour fonctionner de cette manière.Makefile règle en fonction du changement du nombre/titre des fichiers au lieu de la modification du contenu des fichiers

Je pourrais utiliser .PHONY ou quelque chose de similaire pour forcer la génération d'index à fonctionner tout le temps, mais je préfère ne pas gaspiller les cycles. En tant que prérequis pour ma règle de génération d'index, j'ai essayé d'ajouter et comme, mais cela nécessiterait soit de modifier manuellement list.txt (en essayant de l'éviter), soit de le générer automatiquement dans le fichier makefile (cela change la temps de création, donc je ne peux pas utiliser list.txt dans la condition préalable car cela déclencherait la règle à chaque fois).

Répondre

6

Si vous avez besoin d'une dépendance sur le nombre de fichiers, alors ... pourquoi ne pas simplement compter sur le numéro lui-même? Le nombre sera représenté comme un fichier fictif créé lorsque le nubmer de fichiers spécifié est dans le répertoire documents.

NUMBER=$(shell ls documents/*.txt | wc -l).files 
# This yields name like 2.files, 3.files, etc... 
# .PHONY $(NUMBER) -- NOT a phony target! 

$(NUMBER): 
     rm *.files # Remove previous trigger 
     touch $(NUMBER) 

index.txt: $(NUMBER) 
     ...generate index.txt... 

Bien que le nombre de fichiers est une propriété à suivre, au lieu que vous pouvez compter sur un hachage d'une liste de répertoires. Il est très improbable que la fonction de hachage soit la même pour deux listes qui se produisent dans votre flux de travail. Voici un exemple:

NUMBER=$(shell ls -l documents/*.txt | md5sum | sed 's/[[:space:]].*//').files 

note à l'aide -l - cette façon, vous dépendez la liste complète des fichiers, ce qui inclut le temps de modification, la taille et les noms de fichiers. Bu si vous n'en avez pas besoin, vous pouvez laisser tomber l'option.

Remarque: sed était nécessaire car sur mon système, md5sum génère des données après la somme de hachage elle-même.

+0

+1 oh, c'est intelligent. – Beta

+0

Je me demande si cette solution peut être ajustée pour tenir compte du changement de nom de fichier et pas seulement du nombre de fichiers. – user17925

+0

@goathens, ça peut, je répare la réponse. Mais, en fait, alors que votre intention était claire, vous avez demandé la dépendance sur un * nombre * de fichiers ;-) –

2

Vous pouvez mettre une dépendance sur le répertoire lui-même pour le fichier de liste, par ex.

list.txt: documents 
     ls documents/*.txt 2>/dev/null > [email protected] || true 

Chaque fois que vous ajoutez ou supprimez un fichier dans le répertoire des documents, l'horodatage du répertoire sera modifié et make fera la bonne chose.

+0

La modification d'un nom de fichier modifie-t-elle également l'horodatage? – user17925

+0

Oui, en modifiant le nom d'un fichier, vous modifiez le répertoire et l'horodatage du répertoire sera mis à jour (l'horodatage du fichier lui-même restera inchangé). – hlovdal

+0

Il s'agit peut-être d'un système de fichiers spécifique, mais la modification d'un fichier dans le répertoire augmente également l'horodatage. La règle décrite ci-dessus s'exécute même si aucun fichier n'a été ajouté, supprimé ou renommé. Il ne s'exécuterait pas à chaque fois, mais l'édition du contenu d'un fichier ne devrait pas déclencher une régénération de la liste. – user17925

0

Voici une solution qui met à jour l'index si et seulement si l'ensemble des fichiers a changé:

list.txt.tmp: documents 
    ls $</*.txt > [email protected] 

list.txt: list.txt.tmp 
    cmp -s $< [email protected] || cp $< [email protected] 

index.txt: list.txt 
    ...generate index.txt... 

Merci à la « cmp || cp », le ctime de « list.txt » ne change pas sauf si la sortie du "ls" a changé.

Questions connexes