/ / GNU Make e caratteri jolly - file mancanti - makefile, gnu-make

GNU Make e caratteri jolly - file mancanti - makefile, gnu-make

Ho un Makefile con il seguente tipo di regola:

%.html:
./generate-images.py > $@
make $(patsubst %.png,%.gif,$(wildcard *.png))

Il generate-images lo script scrive non solo il file HTML (allo stdout) ma diversi file .png nella directory corrente. L'obiettivo qui è convertirli in .gif. (non proprio, ma questo è un esempio)

Funziona se lo invoco direttamente. Il problema è: se lo invoco da un'altra regola dove foo.html è una dipendenza, l'istruzione jolly non riesce a trovare alcun file. In altre parole, ha appena chiamato make senza argomenti, che non è quello che voglio qui.

Qual è l'accordo con il carattere jolly o esiste un modo migliore per farlo?

risposte:

1 per risposta № 1

Sembra che stia valutando tutto il $() espressioni mentre sta elaborando il Makefile, piuttosto che come esegue ogni regola. Puoi aggiungere una regola al tuo makefile in questo modo:

images: $(patsubst %.png,%.gif,$(wildcard *.png))
.PHONY: images

e quindi modifica il tuo esempio di snippet in

%.html:
./generate-images.py > $@
make images

in modo che Make valuti il ​​glob al momento giusto. Questo è qualcosa su cui il controllo del manuale potrebbe essere utile.


3 per risposta № 2

Mentre il tuo problema potrebbe essere qualcosa di diverso, ne vedo chiaramente uno.

L'intero testo di tutti i comandi all'interno della regola vengono elaborati simultaneamente in modo che le funzioni e le variabili di s vengano espanse .png i file nella directory e invochi make in modo che li rigeneri: a.png e b.png. Quindi, dopo aver invocato make, il testo della regola apparirà in questo modo:

file.html:
./generate-images.py > file.html
make

perché al momento di leggere il makefile non c'erano .png File! Dopo l'esecuzione della prima riga, verranno visualizzati i file, ma la riga successiva era già stato generato essere solo "fare".

E solo quando invochi il tuo makefile per la seconda volta, lo espanderai

file.html:
./generate-images.py > file.html
make a.gif b.gif

Questo non è quello che vuoi. Quindi suggerisco di farlo nel modo giusto.

# If you have batch conversion program, this may be helpful
images.stamp: *.png
convert_all_images $?
touch images.stamp

# OR, if you want convert one-by-one with means of make
images.stamp: $(wildcard *.png)
touch images.stamp

%.gif: %.png
convert_one --from=$^ --to=$@

# HTML would look like
%.html:
./generate-images.py > $@
make images.stamp

Quindi quando invochi make all, genera html e converte le immagini appena generate. Nota che convertirà solo le immagini che vengono aggiornate, che è quello che vuoi


Grazie a Beta per sottolineare il caos con le estensioni gif / png.