Wie kann ich eine Variable im laufenden Betrieb aus dem Makefile erstellen, deren Wert den gesamten Inhalt einer anderen Datendatei darstellt?
81
Ich vermute, dass Sie eine Variable in Ihrem Makefile auf den Inhalt einer anderen Datei setzen möchten:
FILE=test.txt
VARIABLE=`cat $(FILE)`
target:
echo $(VARIABLE)
VARIABLE
ist eine Zeichenfolgecat $(FILE)
(in Anführungszeichen), die nur in einem Rezept von der Shell erweitert wird. Versuchen Sie, den Wert wie folgt zu drucken$(info ${VARIABLE})
.VARIABLE
als Versprechen betrachten. Dies ist die einzige Version, die mit älteren Versionen von funktioniertmake
. Beide:=
und$(shell ...)
sind GNU-Erweiterungen.cat
jedes Mal ausgeführt , wenn die Regel ausgeführt wird. Dies ist normalerweise nicht beabsichtigt und sollte gewarnt werden, da es langsam ist. Wenn die Datei eine Pipe ist, hat sie außerdem unbeabsichtigte Nebenwirkungen. Die Zuweisung sollte mit erfolgen,:=
damit die Regel nicht ausgewertet wird, wenn die Variable ersetzt wird, sondern wenn die Variable definiert wird. Der Ersetzungswert sollte$(shell cat $(FILE))
so sein, dass dercat
Befehl direkt von make ausgeführt wird, nicht später von den Rezeptregeln.cat
eher auf komplexe als auf alternative Regeln verlassen, werden Ihre Makefiles viel einfacher zu verstehen und fast genauso portabel oder manchmal portabler.Angenommen, GNU machen:
quelle
GNU make Version 4.2 unterstützt das Lesen von Dateien. In Bezug auf Maxim Egorushkins großartige Antwort gibt es jetzt eine optionale Möglichkeit, dieses Problem zu lösen:
quelle
cat
existiert unter Windows nicht. Lösung, die für Linux und Windows funktioniert:Erläuterung: Unter Windows scheint immer eine
OS
Umgebungsvariable definiert zu sein, die gleich 'Windows_NT' ist. Auf diese Weise wird für Windows dertype
Befehl für Nicht-Windowscat
verwendet.quelle
Viel einfacher, da
$(file op filename)
hinzugefügt wurde:Handbuchseite hier: https://www.gnu.org/software/make/manual/html_node/File-Function.html#index-file_002c-reading-from
quelle
Wenn Sie GNU make verwenden, können Sie diesen Effekt auch erzielen, indem Sie ein make "include" eines anderen Makefiles verwenden:
Aus dem Makefile:
Erstellen Sie eine Datei "MyFile.mak" mit Inhalt:
quelle
Makefile:1: "./MyFile.mak": No such file or directory
make -v
gibtGNU Make 3.81
include ./MyFile
Da die Plattform nicht angegeben wurde, funktioniert sie unter Solaris folgendermaßen:
quelle
Hier ist eine portablere Lösung, die mit
MAKE
Version 3 funktioniert , für diefile
keine Direktive verfügbar ist. Der Nachteil ist, dass dabei eine temporäre Datei erstellt werden muss.Die Hauptidee ist die Verwendung einer
define
Direktive, die speziell zum Deklarieren mehrzeiliger Variablen entwickelt wurde. Natürlich können Sie die Verwendung vermeidenshell
einer temporären Datei wenn Sie den Dateiinhalt explizit für die Verwendung von Makefile schreiben können.Denken Sie daran, dass Ihre Datei, wenn sie
$
Zeichen enthält ,MAKE
versucht, diese als Variablen / Anweisungen zumy_variable
erweitern, wenn sie erweitert wird (oder wenn sie zugewiesen ist, von denen Sie sie definieren:=
). Wenn Sie dies vermeiden möchten, müssen Sie sie maskieren, bevor Sie Dateiinhalte einfügen. Zum Beispiel können Sie stattdessencat
Folgendes tun:quelle