2013-02-08 6 views
1

j'ai quelques problèmes avec mon Makefile:flux de travail avec un grand nombre de fichiers intermédiaires

# Manage rendering of images 
.PHONY: explode 

all: explode anime.apng 

out.ppm: file.code 
    ./pgm -f $< 

explode: out.ppm 
    split -d -a 3 --lines=$(N) --additional-suffix=.ppm $< frame 

# Convert to multiple png 
%.png: %.ppm 
    convert $< [email protected] 
    optipng [email protected] 

# Assemble in one animated png 
anime.apng: %.png 
    apngasm [email protected] frame000.png 

Mon problème est: Je ne sais pas combien de fichiers intermédiaires, je vais devoir produire mon objectif final, donc je ne peux pas les spécifier à l'avance. Schématiquement:

1 file.code -> 1 out.ppm |> LOADS of .ppm |> LOADS of .png -> 1 anime.apng 
         +> …    +> … 
         +> …    +> … 

Pour que j'utiliser une règle implicite %.png: %.ppm. Mais alors je ne peut pas spécifier un prérequis pour ma dernière étape de fusion! Des idées? Avec un autre outil que de faire? Rien d'élégant?

Répondre

2

Je pense qu'une approche simple et plutôt propre serait d'avoir une variable enregistrer la liste de ces «CHARGES» de ppm, dans mon exemple c'est variable STEP2. Vous pouvez certainement utiliser le programme qui vous mène de '1 out.ppm' à 'LOADS of .ppm' pour lister les fichiers .ppm que vous obtiendrez.

Avec un très trivial où exemple out.ppm serait un fichier texte listant les noms des .ppm pour produire, vous pouvez écrire quelque chose comme:

SOURCE = file.code 
STEP1 = out.ppm 
STEP2 = $(shell cat $(STEP1)) 
STEP3 = $(STEP2:%.ppm=%.png) 
TARGET = anime.apng 

Ensuite, vous aurez besoin d'écrire une règle pour obtenir tous les fichiers répertoriés dans STEP2 à partir du fichier $ (STEP1). Ceci est fait fichier par fichier comme si elle était une règle implicite avec un motif%, en supposant que votre programme est appelé « extracteur »:

$(STEP2): $(STEP1) 
    extractor $^ [email protected] 

Cette règle sera appliquée une fois pour chaque fichier répertorié à l'étape 2. Cela suppose que votre programme ne veut que les noms des fichiers source et de sortie. Si vous préférez passer la tige du fichier de sortie, vous pouvez toujours utiliser un vieux règle implicite simple:

$(STEP2):%.ppm: $(STEP1) 
    extractor $^ $* 

(Le $ (STEP2): au début du mois est d'empêcher faire d'utiliser cette règle pour générer out.ppm)

Ensuite, tout est comme d'habitude quand il s'agit de compiler et vous pouvez adapter les règles pour compiler et relier n'importe quel projet C. Le% .ppm ->% .png étape est comme compilation% .c% .o:

%.png: %.ppm 
    convert $< [email protected] 
    optipng [email protected] 

Pour tout groupe à la fin (l'équivalent de relier plusieurs% .o dans un seul binaire):

$(TARGET): $(STEP3) 
    apngasm [email protected] $^ 

Je suppose ici que apngasm peut prendre la liste de tout à mettre en tant qu'arguments à la tar.

Espérons que c'est clair et utile.

+0

Super! Donc, je peux tout avoir dans un seul fichier? – MP0

+0

Ouais je suppose. Peut-être que vous aurez besoin de scripts supplémentaires pour remplir STEP2 si votre 'extracteur' ne fait pas déjà le travail, mais au moins en ce qui concerne make un Makefile seulement devrait être suffisant. – Greygjhart

0

Une solution de contournement temporaire serait de s'inspirer de a close question et de rendre les images dans un sous-dossier avec un appel secondaire. Quelque chose comme:

Makefile:

# Manage rendering of images 
.PHONY: explode 

all: explode anime.apng 

out.ppm: file.code 
    ./pgm -f $< 

explode: out.ppm 
    split -d -a 3 --lines=$(N) --additional-suffix=.ppm $< subfolder/frame 

ppm2png: explode 
    $(MAKE) -C subfolder 

# Assemble in one animated png 
anime.apng: ppm2png 
    apngasm [email protected] subfolder/frame000.png 

temp/Makefile:

SOURCES := $(wildcard *.ppm) 
OUTPUTS = $(patsub %.ppm,%.png,%(SOURCES)) 

.PHONY: all 
all: $(OUTPUTS) 

# Convert to multiple png 
%.png: %.ppm 
    convert $< [email protected] 
    optipng [email protected] 

Je suis sûr que mieux peut être fait. Avec un autre outil que de faire?

Questions connexes