2012-11-28 23 views
5

Desidero leggere un file chiamato metafile all'interno di un makefile.Lettura di un file all'interno del makefile

metafile simile a questa:
file1
file2
file3

ho bisogno di leggere questo metafile dentro la mia linea di makefile per riga e verificare se i file menzionati all'interno esiste o no e nomi di stampare solo di file che esiste.

Ho provato alcune cose senza successo. del tipo:

FILE=`cat metafile` 
for line in $(FILE); if [ -e $${line} ]; then echo $${line} fi; done; 
+0

Stai provando entrambe le righe in una ricetta? Ogni riga viene eseguita in una subshell separata. Puoi unirti a una linea con la riga successiva inserendo '; \ 'alla fine. Ma allora la prima variabile sarebbe '$$ {LINE}' not '$ (LINE)'. – tripleee

risposta

11

È possibile inserire un oggetto arbitrario di shell in un obiettivo. Mantenere il contenuto del file in una variabile Makefile non ha senso per me, a meno che tu non abbia bisogno dei dati anche in altri target per altri motivi. (Se è così, non si può usare backticks, comunque.)

target: 
     @while read -r file; do \ 
      test -e "$$file" && echo "$$file"; \ 
     done <metafile 

Per quello che vale, il ciclo while è un modo più sicuro e più idiomatico per ciclare su linee di un file in uno script di shell che il ciclo for con apici inversi , anche se lo vedi molto.

(L'@ impedisce Faccia dal riecheggiando lo script di shell comandi, prendere che se per qualche motivo è necessario vederli.)

Un modo più idiomatico per fare questo in un Makefile è quello di avere un target dipendono su questi file, e logica l'uso del Marchio:

target: file1 file2 file3 
     @echo $(filter-out $?,$^) 

Questo è GNU make sintassi; potrebbe diventare più complesso se si vuole essere portabile ad altri sapori Make (al punto che forse lo script di shell è preferibile dopo tutto). Riecheggerà tutto su una riga, ma se hai bisogno di linee separate, questa dovrebbe essere una soluzione banale.

Vorrei semplicemente costruire un piccolo frammento Makefile ausiliario e includono le dipendenze:

target: target.d 
target.d: metafile 
     sed 's/^/target: /' $< >[email protected] 
include target.d 

Questo costruisce un piccolo elenco delle dipendenze in modo che non c'è bisogno di elencarli in target: dipendenze esplicitamente; così invece di file1 file2 file3 nella ricetta di cui sopra, le dipendenze vivrebbero nella generato target.d che conterrebbe

target: file1 
target: file2 
target: file3 

È necessario filtrare la dipendenza target.d (o lasciare sommerso; credo GNU Make deve far fronte).

+0

Grazie per la risposta così dettagliata. Sto provando il primo ciclo che hai menzionato ma non ricevendo nulla come o/p. anche il secondo "$ file" dovrebbe essere "$$ file" ?? – hari

+0

Nessun problema, ha funzionato. – hari