2012-11-28 14 views
5

Ich möchte eine Datei namens Metafile in einem Makefile lesen.Eine Datei in Makefile lesen

Metafile sieht ungefähr so ​​aus:
file1
file2
file3

Ich brauche diese Metafile in meiner Make-Datei Zeile für Zeile zu lesen und überprüfen, ob die im Inneren genannten Dateien oder nicht, und nur Druck Namen existieren von Dateien, die existieren.

Ich habe ein paar Dinge ohne Erfolg versucht. wie:

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

Versuchen Sie beide Linien in einem Rezept? Jede Zeile wird in einer separaten Untershell ausgeführt. Sie können eine Linie mit der nächsten Linie verbinden, indem Sie '; am Ende. Aber dann wäre die erste Variable '$$ {LINE}' nicht '$ (LINE)'. – tripleee

Antwort

11

Sie können ein beliebiges Stück Shell-Skript in ein Ziel einfügen. Den Inhalt der Datei in einer Makefile-Variablen zu belassen, macht für mich keinen Sinn, es sei denn, Sie benötigen die Daten auch aus anderen Gründen in anderen Zielen. (Wenn ja, können Sie nicht Backticks verwenden, sowieso.)

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

Für das, was es wert ist, die while Schleife ist ein sicherer und idiomatischer Weg, um eine Schleife über eine Linie der Datei in einem Shell-Skript als die for Schleife mit Backticks obwohl du das oft siehst.

(Die @ verhindert Make-Befehle das Shell-Skript von Echo, das herausnehmen, wenn Sie aus irgendeinem Grund, sie zu sehen braucht.)

Eine idiomatische Weg, dies in einem Makefile zu tun ist, um ein Ziel zu haben abhängen für diese Dateien und verwenden Sie die eigene Logik von Make:

Dies ist GNU Make-Syntax; es könnte komplexer werden, wenn Sie zu anderen Make-Varianten portierbar sein möchten (bis zu dem Punkt, an dem vielleicht das Shell-Skript am besten ist). Es wird alles in einer Zeile wiedergeben, aber wenn Sie separate Zeilen benötigen, sollte das eine triviale Lösung sein.

Ich würde einfach einen kleinen Hilfsmakefile-Schnipsel bauen und umfassen die Abhängigkeiten:

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

Diese eine kleine Liste von Abhängigkeiten aufbauen, so dass Sie sie nicht explizit in den target: Abhängigkeiten auflisten müssen; so statt file1 file2 file3 im Rezept oben, würden die Abhängigkeiten in der generierten target.d leben die

target: file1 
target: file2 
target: file3 

Sie müssen sich auf target.d die Abhängigkeit heraus filtern enthalten würde (oder lassen Sie es nicht deklariert, ich glaube, GNU fertig Make sollte).

+0

Danke für so detaillierte Antwort. Ich versuche die erste while-Schleife, die Sie erwähnt haben, aber nichts als o/p bekommen. auch zweite "$ file" sollte "$$ file" sein ?? – hari

+0

Keine Sorge, es hat funktioniert. – hari