EnglischFranzösischSpanisch

Ad


OnWorks-Favicon

makepp_functions – Online in der Cloud

Führen Sie makepp_functions im kostenlosen Hosting-Anbieter OnWorks über Ubuntu Online, Fedora Online, den Windows-Online-Emulator oder den MAC OS-Online-Emulator aus

Dies ist der Befehl makepp_functions, der beim kostenlosen Hosting-Anbieter OnWorks mit einer unserer zahlreichen kostenlosen Online-Workstations wie Ubuntu Online, Fedora Online, dem Windows-Online-Emulator oder dem MAC OS-Online-Emulator ausgeführt werden kann

PROGRAMM:

NAME/FUNKTION


makepp_functions – Funktionen in makepp

BESCHREIBUNG


A: absoluter_Dateiname,
absoluter_dateiname_nolink,
Abspath,
Präfix hinzufügen,
Addsuffix,
und, B: Basisname, C: Anruf, D: ist,
dir_noslash, E: Error, F: Dateiensubst,
Filter,
Aussortieren,
filter_out_dirs,
findfile,
find_first_upwards,
find_programm,
Suchzeichenfolge,
find_upwards,
first_verfügbar,
erstes Wort,
für jede, I: ob,
Wenn wahr,
infer_linker,
infer_objects,
Info, J: beitreten, M: machen,
Makemap,
makeperl,
Karte,
„mktemp“, N: notdir, O: only_generated,
only_nontargets,
only_phony_targets,
only_stale,
only_targets,
oder,
Ursprung, P: patsubst,
Perl,
falsch,
vorgefertigt,
drucken, R: realpath,
relativer_Dateiname,
relative_zu, S: Schale,
Sortieren,
Streifen,
subst,
Suffix, T: vorübergehend, W: Warnung,
Platzhalter,
Wort,
Wortliste,
Wörter, X: xargs

Jeder Ausdruck im Format „$(name)“, wobei „name“ nicht der Name einer Variablen ist, oder
„$(name arg1 arg2 arg3)“ wird als Funktionsaufruf interpretiert. Der Name kann Buchstaben enthalten,
Unterstriche oder Bindestriche; Um Verwirrung zu vermeiden, können Sie Bindestriche oder Unterstriche verwenden
austauschbar, da Bindestriche intern in Unterstriche umgewandelt werden. Solche bewerten
Ein Ausdruck ruft einfach eine Perl-Subroutine auf. Wenn vor „name“ ein „&“ steht, wird Folgendes ausgeführt
Eingebauter Befehl oder ein Skript mit diesem Namen innerhalb des makepp-Prozesses und gibt den Standard zurück
Ausgabe. Dazu muss Perl für PerlIO erstellt werden. Wenn der Name keine Funktion benennt
es wird in eine Anrufung des Rufes umgewandelt.

Wie bei Variablen haben Sie die Wahl zwischen „$(name ...)“ und „${name ...}“. Wenn Sie wollen
Wenn Sie die gleiche Klammer einbetten, muss sie gepaart werden, die andere spielt keine Rolle: „$(name
...(){..." oder "${name ...{}(...}". (Für Map und Perl endet jedoch das erste schließende Paren
Der Ausdruck.) Durch die Verdoppelung können sich die Argumente über mehrere Zeilen erstrecken. Die Zeilenumbrüche sind
werden dann als Leerzeichen behandelt, außer vielleicht in „define“. Es gibt auch die Syntax „$[name ...]“
oder $[[name ...]], das beim Lesen des Makefiles ausgewertet wird, bevor die Regeln festgelegt werden
und andere Konstrukte.

Makepp verfügt über eine Reihe integrierter Funktionen, die nützlich sein können. Es unterstützt fast alle
Die Textfunktionen von GNU make (Einzelheiten finden Sie in der Dokumentation von GNU make) und einige davon
eigen. Sie können Perl-Unterroutinen so definieren, dass sie alles tun, was Sie möchten. Siehe die „sub“-Anweisung
und der Abschnitt zum Erweitern von makepp für weitere Details.

Bedingt Funktionen
und Bedingung1[,Bedingung2[,Bedingung3...]]
Die Funktion „und“ ermöglicht eine „kurzschließende“ UND-Verknüpfung. Jedes Argument ist
erweitert, der Reihe nach. Wenn ein Argument zu einer leeren Zeichenfolge erweitert wird, stoppt die Verarbeitung und
Das Ergebnis der Erweiterung ist die leere Zeichenfolge. Wenn alle Argumente zu einem Nicht-Erweitert werden
Ist die Zeichenfolge leer, ist das Ergebnis der Erweiterung die Erweiterung des letzten Arguments.

if Schnur result-if-string-not-blank[, result-if-string-blank]
Wenn wahr Schnur result-if-string-true[, result-if-string-false]
Eine Alternative zu den „ifeq“-Anweisungen usw. Wenn die Zeichenfolge nicht leer ist (d. h. die
Wenn die Bedingung wahr ist), wird das zweite Argument (die „then“-Klausel) zurückgegeben (danach).
variable Erweiterung); Wenn die Zeichenfolge leer ist, ist das dritte Argument (die „else“-Klausel) leer
ist zurückgekommen.

Zum Beispiel,

CFLAGS := $(if $(filter gcc egcc, $(CC)), -g -Wall, -g)

Definiert CFLAGS als „-g -Wall“, wenn die Variable CC entweder „gcc“ oder „egcc“ ist, und „-g“
ansonsten. (Dies ist, was die Standard-Build-Regeln bewirken.)

„iftrue“ ähnelt „if“, außer dass die Zeichenfolge 0 als leer behandelt wird.

or Bedingung1[,Bedingung2[,Bedingung3...]]
Die Oder-Funktion ermöglicht eine „kurzschließende“ ODER-Verknüpfung. Jedes Argument wird erweitert,
in Ordnung. Wenn ein Argument zu einer nicht leeren Zeichenfolge erweitert wird, stoppt die Verarbeitung und die
Ergebnis der Erweiterung ist diese Zeichenfolge. Wenn, nachdem alle Argumente erweitert wurden, alle
Wenn sie falsch (leer) sind, ist das Ergebnis der Erweiterung die leere Zeichenfolge.

Reichen Sie das und Dateiname Funktionen
absoluter_Dateiname Dateien
Abspath Dateien
Konvertiert relative Dateinamen in absolute Namen ohne . or ... Beispielsweise,
„$(absolute_filename xyz.c)“ könnte „/usr/src/our_project/subdir/xyz.c“ zurückgeben.

absoluter_dateiname_nolink Dateien
realpath Dateien
Wie absolute_Dateiname, stellt aber sicher, dass symbolische Links aufgelöst werden.

Basisname Dateinamen
Der Basisname ist der gesamte Dateiname (mit dem Verzeichnis), abzüglich des Textes nach und
einschließlich der letzten Periode. Beispielsweise lautet „$(basename myfile/version-1.0-module.c)“.
„meineDatei/Version-1.0-Modul“

dir Dateinamen
Extrahiert den Verzeichnisteil jeder Datei in der Dateinamenliste, einschließlich des nachgestellten Teils
Schrägstrich. Gibt „./“ zurück, wenn der Dateiname kein Verzeichnis enthält.

dir_noslash Dateinamen
Identisch mit „$(dir)“, außer dass der abschließende Schrägstrich nicht zurückgegeben wird.

Dateiensubst Muster, Ersatz, Worte
Führen Sie eine Musterersetzung für Dateinamen durch. Dies unterscheidet sich von patsubst darin
Es funktioniert korrekt, wenn alternative Namen für Verzeichnisse angegeben werden (sofern
sie stehen vor dem Prozentzeichen). Zum Beispiel,

$(filesubst ./src/%.c, %.o, $(wildcard src/*.c))

funktioniert mit filesubst, aber nicht mit patsubst.

filter_out_dirs Dateinamen
Gibt alle Dateinamen zurück, die nicht auf Verzeichnisse verweisen.

findfile Dateiname, Weg
Sucht eine Datei im angegebenen Pfad oder in der Umgebungsvariablen PATH, wenn nichts vorhanden ist
angegeben. Dies kann nützlich sein, um Binärdateien oder Include-Dateien zu finden. Zum Beispiel,

TCL_INCLUDE := -I$(dir_noslash $(findfile tcl.h, \
/usr/local/stow/tcl-8.4.5-nothread/include \
/usr/include/tcl8.4 /usr/include/tcl \
/net/na1/tcl8.4a3/include /net/na1/tcl8.4a3/include))

Dadurch wird die Datei gefunden tcl.h indem Sie alle oben genannten Verzeichnisse durchsuchen. Das Absolute
Der Pfad zur Datei wird zurückgegeben. Dann extrahiert „$(dir_noslash)“ dieses Verzeichnis und es
wird in den Include-Pfad eingefügt.

find_program Name
Gibt das erste Programm in der Liste zurück, das im PATH gefunden werden kann. Das ist nützlich
wenn es mehrere gleichwertige Programme gibt, die verwendet werden können, und Sie dies einfach möchten
Wählen Sie eine davon aus. Hier ist beispielsweise die Standarddefinition mehrerer gemeinsamer
Variablen, die makepp bereitstellt, wenn Sie keine in Ihr Makefile einfügen:

CC = $(find_program gcc egcc pgcc c89 cc) # und mehr, je nach Maschine
F77 = $(find_program f77 g77 fort77)
CXX = $(find_program g++ c++ pg++ cxx CC aCC)

Wenn keines der Programme gefunden wird, gibt „$(find_program)“ die Zeichenfolge „not-found“ und zurück
protokolliert, was nicht gefunden wurde. Dies führt normalerweise nicht zu einem funktionsfähigen Makefile, aber es
führt tendenziell zu besseren Fehlermeldungen. Zum Beispiel, wenn Sie so etwas tun wie
Dies:

%.o : %.c
$(CC) $(Eingänge) -o $(Ausgänge)

und makepp keinen C-Compiler in der Liste oben finden kann, wird es durch „nicht gefunden“ ersetzt.
Andernfalls würde die Shell versuchen, die Quelldatei auszuführen, was zu einem Fehler führen würde
Die Nachricht könnte wirklich seltsam sein.

find_upwards Dateinamen
Sucht nach einer Datei mit dem angegebenen Namen im Verzeichnis ., .., ../ ..../../..Usw.
bis die Datei gefunden oder das Stammverzeichnis erreicht oder das Verzeichnis gefunden wird
auf einem anderen Dateisystem. (Diese letzte Anforderung dient dazu, Probleme mit zu verhindern
Automounter oder hängende Netzwerkdateisysteme.) Wenn Sie ein RootMakeppfile, das ist auch
eine Barriere, die eine Suche weiter oben verhindert.

Wenn Sie beispielsweise ein Projekt mit vielen Ebenen von Unterverzeichnissen haben, könnten Sie dies tun
Fügen Sie dieses gemeinsame Fragment in alle Makefiles ein (z. B. mithilfe der Funktion „include“).
Aussage):

TOP_LEVEL_INCLUDE_DIR := $(find_upwards enthält)
# Sucht nach einem Verzeichnis, das das enthält
# enthält Unterverzeichnis.

%.o : %.c
$(CC) $(CFLAGS) -I$(TOP_LEVEL_INCLUDE_DIR) -c $(Eingabe) -o $(Ausgabe)

Ein weiteres Problem, das „find_upwards“ lösen kann, ist das Auffinden des Verzeichnisses der obersten Ebene
eines Builds. Oft ist es sinnvoll, eine Variable wie folgt zu definieren:

OBEN := ../../..

wenn sich einige wichtige Informationen nur im Verzeichnis der obersten Ebene befinden. Aber
Dies ist schwer beizubehalten, da die Anzahl der „..“ für verschiedene Ebenen unterschiedlich ist
des Verzeichnisbaums. Stattdessen können Sie „find_upwards“ verwenden, um eine Datei zu finden
Es ist bekannt, dass es nur im Verzeichnis der obersten Ebene vorhanden ist. Nehmen wir zum Beispiel an, dass die
Die Datei „LICENSE“ befindet sich nur im obersten Verzeichnis. Dann könnten Sie Folgendes tun:

TOP := $(dir_noslash $(find_upwards LICENSE))

„$(find_upwards LICENSE)“ gibt den vollständigen Pfad der Lizenzdatei zurück;
„$(dir_noslash ...)“ entfernt den Dateinamen und gibt nur das Verzeichnis zurück.

(Beachten Sie, dass die „include“-Anweisung automatisch nach oben nach Dateien sucht, also dort
Es ist nicht nötig, so etwas zu tun:

include $(find_upwards top_level_rules.mk)

Stattdessen können Sie es einfach tun

top_level_rules.mk einschließen

und es wird genauso gut funktionieren.)

Wenn die Datei nicht gefunden wird, bricht „find_upwards“ den Build mit einer Fehlermeldung ab.

Wenn Sie mehr als eine Datei angeben, sucht find_upwards dann nach der ersten
der zweite und so weiter. Mit anderen Worten,

$(find_upwards Datei1 Datei2)

entspricht

$(find_upwards file1) $(find_upwards file2)

Wenn Sie nach einer der Dateien suchen möchten, verwenden Sie stattdessen „find_first_upwards“.

find_first_upwards file1 file2 ...
Diese Funktion verhält sich wie „find_upwards“, außer dass sie die erste Datei von allen zurückgibt
Dateien in der Liste, die es findet. Insbesondere wird das aktuelle Verzeichnis überprüft
eine beliebige Datei in der Liste und gibt die erste Datei zurück, die existiert oder erstellt werden kann.
Wenn keine der Dateien in diesem Verzeichnis vorhanden ist oder erstellt werden kann, wird eine Überprüfung durchgeführt .. und dann
../ ..usw., bis es entweder das Stammverzeichnis oder ein Verzeichnis erreicht, in dem es sich befindet
befindet sich in einem anderen Dateisystem.

first_available file1 file2 ...
Gibt die erste Datei in einer Liste zurück, die existiert oder erstellt werden kann. Dies kann nützlich sein für
Anpassen Ihrer Makefiles, um auf mehreren verschiedenen Maschinen oder Netzwerken zu funktionieren
Wichtige Dateien können sich an verschiedenen Orten befinden. Hier ist zum Beispiel eine Zeile von
eines meiner Makefiles:

TCL_LIB = $(first_available \
/usr/local/stow/tcl-8.4.5-nothread/lib/libtcl8.4.so \
/usr/lib/libtcl8.4.so /usr/lib/libtcl.so \
/net/na1/tcl8.4a3/lib/libtcl8.4.a \
/net/na1/tcl8.4a3/lib/libtcl8.4.sl)

Diese Zeile sucht an allen oben genannten Stellen nach der Tcl-Bibliothek und stoppt an der
das erste, das es findet. Der Link-Befehl enthält dann $(TCL_LIB), sodass wir das erhalten
entsprechende Tcl-Bibliothek.

infer_linker file1 file2 ...
Erstellen Sie anhand einer Liste von Objektdateien zunächst diese, falls dies noch nicht geschehen ist. Dann finden
ob sie von einer Fortran-, C++- oder einer C-Quelle abhängen und das entsprechende zurückgeben
Compiler (der besser verknüpft werden kann als „ld“).

infer_objects file1 file2 ... Anleitungen
$(infer_objects object1.o object2.o, *.o)

Wenn Sie Standardkonventionen für Header-Dateinamen verwenden, ist makepp dazu in der Lage
Erraten Sie, welche „.o“- oder „.lo“-Dateien mit Ihrem Programm verknüpft werden müssen. Ich benutze das, um
Wählen Sie Dateien aus einem Bibliotheksverzeichnis aus, das Module enthält, die in vielen verschiedenen Bereichen verwendet werden
Programme. Anstatt eine Bibliotheksdatei „.a“ ​​zu erstellen und den Linker diese auswählen zu lassen
Wenn Sie relevante Module benötigen, kann makepp die relevanten Module für Sie auswählen. Nur auf diese Weise
Die relevanten Module werden zusammengestellt.

Makepps Algorithmus zum Ableiten von Objektabhängigkeiten hängt von der Konvention ab
Die Implementierung aller Klassen oder Funktionen ist in einer Header-Datei „xyz.h“ definiert
in eine Objektdatei namens „xyz.o“ (oder „xyz.lo“) kompiliert. Also makepps Algorithmus für
Das Ableiten von Objektabhängigkeiten beginnt mit einem oder mehreren Objekten, von denen wir wissen, dass sie vorhanden sein müssen
in das Programm eingebunden. Es wird untersucht, welche Dateien mit „#include“ eingebunden wurden
Diese Quellen und versucht, entsprechende Objektdateien für jedes Include zu finden
Dateien.

„$(infer_objects)“ muss in der Abhängigkeitsliste eines Programms erwähnt werden, z
Dies:

myprog: $(infer_objects main.o another_object.o, \
**/*.o /other/library/dirs/**/*.o)
$(CXX) $(Eingaben) -o $(Ausgabe) $(LIBS)

Die Funktion „$(infer_objects)“ benötigt zwei Argumente (durch ein Komma getrennt, wie gezeigt).
Bei der ersten handelt es sich um eine oder mehrere Objektdateien, von denen bekannt ist, dass sie erforderlich sind (Platzhalter sind).
hier zulässig). Das zweite ist eine Liste möglicher Objekte (normalerweise würden Sie a
Platzhalter hier), der bei Bedarf eingebunden werden könnte. Der Rückgabewert davon
Funktion ist eine Liste, die zunächst alle Objekte im ersten Argument enthält, und
dann danach alle zusätzlichen Objekte, die im zweiten Argument enthalten waren
die von den Objekten im ersten Argument benötigt werden.

Angenommen, „main.o“ kommt von „main.cpp“, das „my_class.h“ enthält.
„$(infer_objects)“ sucht nach Dateien mit dem Namen „my_class.o“. Wenn genau ein solcher
Wenn die Datei gefunden wird, wird sie der Liste hinzugefügt. (Wenn zwei Objektdateien „my_class.o“ gefunden werden
in verschiedenen Verzeichnissen wird eine Warnmeldung ausgegeben.) „infer_objects“ auch
untersucht „my_class.cpp“, um zu sehen, was darin enthalten ist und welche zusätzlichen Objektdateien es gibt
impliziert.

mktemp
mktemp Präfix
mktemp PräfixXXX
mktemp /
Gibt einen unvorhersehbaren temporären Dateinamen zurück, der derzeit nicht existiert. Kein Name
Der Verweis auf dieselbe Datei wird zweimal zurückgegeben, auch bei unterschiedlichen relativen Pfaden.
innerhalb eines Makepp-Laufs (außer möglicherweise mit traditionellem rekursivem Make oder wenn Perl
Code, der innerhalb einer Regelaktion ausgeführt wird, ruft „f_mktemp“ auf). Am Ende des Makepps führen Sie alle aus
Von dieser Funktion zurückgegebene Dateien werden gelöscht, sofern sie vorhanden sind (wiederum mit Ausnahme dieser
von dieser Funktion in Perl-Code zurückgegeben, der innerhalb einer Regel ausgeführt wird).

Beliebig viele Großbuchstaben „X“ am Ende des Arguments werden durch entsprechend viele ersetzt
zufällige Buchstaben und Ziffern. Je mehr es sind, desto unwahrscheinlicher ist es, dass es zu einer Kollision kommt
mit anderen Prozessen, wenn Sie also ein Präfix wie „/tmp/abc.", du solltest genug haben
„X“s. Wenn mehr als ein X vorhanden ist, stammt das erste Zeichen aus der Prozess-ID. Wenn
es gibt keine, es ist, als wären es zehn, was angeblich ausreicht (8.4e17
Möglichkeiten oder 3.7e15 unter Windows). Wenn kein Argument vorhanden ist, wird standardmäßig das Präfix verwendet
"tmp." im aktuellen Verzeichnis.

Beachten Sie, dass Sie keinen Namen wie Regelziele und Abhängigkeiten vergeben möchten. Der
Das Ergebnis wäre korrekt, würde aber jedes Mal neu erstellt, wenn Sie makepp ausführen.

Da es immer anders ist, sollten Sie dies in einer Regelaktion nur dann verwenden, wenn Sie verwenden
„:build_checkignore_action“:

TMPFILE ;= $(mktemp) # 1 Aufruf; „=“ würde 3 Aufrufe bedeuten: 3 Dateien
A-Anzahl B-Anzahl: :build_checkignore_action
produziere-As-und-Bs >$(TMPFILE)
&grep -c /A/ $(TMPFILE) -o A-Anzahl
&grep -c /B/ $(TMPFILE) -o B-Anzahl

Oder Sie exportieren es und lassen es von der Shell auswerten:

TMPFILE exportieren ;= $(mktemp)
A-Anzahl B-Anzahl:
Produce-As-and-Bs >$$TMPFILE # makepp sieht den var-Wert nicht
fgrep -c A $$TMPFILE >A-count
fgrep -c B $$TMPFILE >B-Anzahl

Das letzte Formular wiederholt den vorherigen Rückgabewert, sodass Sie ihn in einer Musterregel verwenden können:

%.x: %.y
&grep foo $(input) -o $(mktemp)
&sed bar $(mktemp /) -o $(output) # Bearbeitet die Ausgabe von &grep

notdir Dateinamen
Gibt den nicht verzeichnisbezogenen Teil des Dateinamens/der Dateinamen zurück, also alles nach dem letzten
Schrägstrich, falls vorhanden, andernfalls der gesamte Dateiname.

only_generated Dateinamen
Gibt nur die Dateinamen in der Liste zurück, die von makepp generiert wurden und nicht seitdem
gemäß der Build-Info-Datei geändert.

Diese Funktion ist in sauberen Zielregeln nützlich (obwohl natürlich „makeppclean“ die ist).
bevorzugte Variante):

$(gefälschte Reinigung):
&rm -f $(only_generated **/*)

only_nontargets Dateinamen
Gibt nur die Dateinamen in der Liste zurück, die nicht Ziele einer Regel sind (oder auch nicht).
explizite Regeln oder Musterregeln). Sie können einen Platzhalter angeben (siehe „$(wildcard)“).
Weitere Informationen zu den Platzhaltern von makepp finden Sie in der Funktion (siehe Funktion). Dies kann zur Generierung eines verwendet werden
Vertriebsziel, zum Beispiel:

.PHONY: Vertrieb

Verteilung:
&mkdir our_product-$(VERSION)
&cp $(filter-out %~, $(only_nontargets *)) our_product-$(VERSION)
tar cf - our_product-$(VERSION) | gzip -9c > our_product-$(VERSION).tar.gz

In diesem Fall gibt „$(only_nontargets *)“ jede Datei im aktuellen Verzeichnis zurück
Das ist nicht das Ziel irgendeiner Regel. Das „$(filter_out %~, ...)“ entfernt den Editor
Backups.

Ähnlich wie „only_targets“ (siehe oben) kennt „only_nontargets“ nur Ziele, die
wurden bereits definiert. Dies ist nur dann ein Problem, wenn Sie es zum Definieren von Variablen verwenden
mit der Zuweisung „:="; wenn Sie es in der Abhängigkeitsliste oder im Hauptteil von a verwenden
Regel, alle anderen Regeln sind bereits gesehen.

only_stale Dateinamen
Gibt nur die Dateinamen in der Liste zurück, die von makepp generiert wurden und nicht seitdem
wurden gemäß der Build-Info-Datei geändert, sind aber nicht mehr das Ziel einer Regel.

Diese Funktion ist nützlich, um sicherzustellen, dass keine Abhängigkeiten zu solchen Dateien bestehen.
ohne einen sauberen Build aller Ziele zu erzwingen:

$(falscher Flush):
&rm -f $(only_stale **/*)

Tatsächlich ist es wahrscheinlich besser, ein Skript zu schreiben, das makepp zum Generieren aufruft
Sehen Sie sich die Liste der veralteten Dateien an und veranlassen Sie dann, dass das Skript alle aufgelisteten Dateien entfernt
stehen derzeit nicht unter Quellcodeverwaltung, nur für den Fall, dass eine generierte Datei zu einer Quelle wird
Datei. In Makepp ist eine solche Funktion nicht integriert, da makepp (und wahrscheinlich) eine solche Funktion hat
sollte hinsichtlich der Quellcodeverwaltung agnostisch bleiben.

only_targets Dateinamen
Gibt nur die Dateinamen in der Liste zurück, die tatsächlich Ziele einer Regel sind
(entweder explizite oder Musterregeln). Sie können Platzhalter (einschließlich makepps) angeben
spezielles Platzhalterzeichen „**“) in den Dateinamen ein. (Weitere Informationen finden Sie in der Funktion „$(wildcard)“.
Einzelheiten. Dies kann beispielsweise für ein sauberes Ziel verwendet werden:

.PHONY: sauber

reinigen:
&rm -f $(only_targets *)

Wenn Sie nun „makepp clean“ eingeben, wird alles gelöscht, was es zu erstellen weiß. Aber
Erstellen Sie kein sauberes Ziel, sondern verwenden Sie stattdessen „makeppclean“!

Ein weiterer Punkt, an dem es nützlich sein kann, ist die Vermeidung von Stale .o Dateien in Ihrem
bauen. Wenn Sie beispielsweise eine Bibliothek wie diese erstellen:

mylib.a: *.o
&rm -f $(Ausgabe)
$(AR) cr $(Ausgabe) $(Eingänge)

und dann löschen Sie einige Quelldateien, vergessen aber, die entsprechenden zu löschen .o Dateien,
.o Dateien werden weiterhin vorhanden sein. Dies bedeutet, dass sie weiterhin integriert werden
die Bibliothek, obwohl sie nicht mehr nützlich sind. Wenn Sie Ihre ändern
Regel wie folgt:

mylib.a: $(only_targets *.o)
&rm -f $(Ausgabe)
$(AR) cr $(Ausgabe) $(Eingänge)

dann wird dieses Problem nicht auftreten.

Beachten Sie, dass sich dies nur auf Dateien bezieht, die bekanntermaßen Ziele sind at Zeit U
aufrufen „Nur-Ziele“. Wenn „only_targets“ in den Abhängigkeiten oder Aktionen von a vorkommt
Regel, dann sind alle möglichen Ziele bekannt, weil Abhängigkeiten und Aktionen nicht bekannt sind
ausgewertet, bis die Regel ausgeführt wird. Wenn Sie jedoch bewerten, versuchen Sie, es zu bewerten
früher im Makefile mit einer „:="-Variable wie dieser:

ALL_TARGETS := $(only_targets *)

Ziel1: Abhängigkeit1
Aktionen

Ziel2: Abhängigkeit2
Aktionen

dann weiß „only_targets“ nichts von den nachfolgenden Regeln.

Ebenso weiß „only_targets“ nichts über Ziele, die in Makefiles erstellt wurden
geladen mit rekursivem make. (Aber Sie sollten rekursives Make sowieso nicht verwenden; verwenden Sie
Verwenden Sie stattdessen die Anweisung „load_makefile“ oder das implizite Laden von Makefiles.)

relativer_Dateiname file1 file2 Datei3[, Schrägstrich]
Gibt den Namen dieser Dateien relativ zum aktuellen Verzeichnis zurück (dasjenige, in dem
Makefile ist drin). Dies kann auch verwendet werden, um unnötiges „./“ und anderen Müll zu entfernen
der Weg:

DIR := .
UNTERVERZEICHNIS := ..
FNAME := $(DIR)/../otherdir/$(SUBDIR)/files
X := $(relative_filename $(FNAME))

If Schrägstrich wahr ist (normalerweise 1), enthalten die zurückgegebenen Dateinamen garantiert einen Schrägstrich
indem Sie bei Bedarf „./“ voranstellen, damit Sie es als ausführbaren Namen ohne verwenden können
Sie machen sich Sorgen, dass der Befehlssuchpfad den Verzeichnisspeicherort überschreibt.

Wenn der Pfad durch das Stammverzeichnis führt, ist das übergeordnete Verzeichnis entweder Ihres Home-Verzeichnisses oder
das „$(ROOT)“ Ihres Build-Systems oder unter Windows das Stammverzeichnis eines Laufwerks (abhängig von
Umgebung, dies geschieht auch für /cygdrive/c or /c), wird ein absoluter Pfad sein
stattdessen zurückgegeben.

relative_zu file1 file2 Datei3[, Verzeichnis]
Gibt den Namen dieser Dateien relativ zum angegebenen Verzeichnis zurück. Das ist
Normalerweise nützlich, wenn Sie aus irgendeinem Grund einen Befehl von einem ausführen müssen
anderes Verzeichnis (aktuelles Standardverzeichnis):

source_backup.tar:
cd .. && tar cf $(relative_to $(output), ..) $(relative_to ., ..)

Suffix Namen...
Extrahiert das Suffix jedes Dateinamens in Namen. Wenn der Dateiname einen Punkt enthält,
Das Suffix ist alles, beginnend mit dem letzten Punkt. Ansonsten ist das Suffix das
leerer String. Dies bedeutet häufig, dass das Ergebnis leer ist, wenn „names“ nicht vorhanden ist.
und wenn „names“ mehrere Dateinamen enthält, enthält das Ergebnis möglicherweise weniger Dateinamen.

Zum Beispiel,

$(Suffix src/foo.c src-1.0/bar.c Hacks)

erzeugt das Ergebnis „.c .c“.

vorübergehend Worte
Teilen Sie makepp mit, dass die angegebenen Ziele möglicherweise durch die generierte Regel entfernt werden
ihnen. Ähnlich wie „phony“, außer dass makepp erwartet, dass es sich um eine echte Datei mit diesem Namen handelt
Der Wille kann von der Regel betroffen sein. Eine Regel wird nicht ausgeführt, wenn sie nur vorübergehend ist
Ziele sind veraltet.

Platzhalter Anleitungen
Gibt die sortierten Namen aller vorhandenen Dateien zurück, die dem angegebenen Muster entsprechen
Dateien, die noch nicht existieren, aber basierend auf den Regeln erstellt werden können, die makepp kennt
ungefähr zu dem Zeitpunkt, an dem der Ausdruck ausgewertet wird. In diesem letzten Punkt ist es unterschiedlich
von Regeleingabe-Platzhaltern, die auch für Dateien gelten, die durch später gefundene Regeln erstellt wurden.

Makepp unterstützt alle üblichen Shell-Platzhalter („*“, „?“ und „[]“). Es hat auch eine
Platzhalter „**“, der auf eine beliebige Anzahl dazwischenliegender Verzeichnisse passt. (Diese Idee war
von zsh gestohlen.) Beispielsweise stimmt „**/*.c“ mit allen überein .c Dateien in der gesamten Quelle
Baum. „objects/**/*.o“ stimmt mit allen überein .o Dateien, die irgendwo im enthalten sind
Unterverzeichnis Objekte oder eines seiner Unterverzeichnisse oder eines ihrer Unterverzeichnisse. Der
Der Platzhalter „**“ folgt auf keiner Ebene Softlinks zu Verzeichnissen und wird dies auch nicht tun
Versuchen Sie, Verzeichnisse einzugeben, die zwar vorhanden, aber nicht lesbar sind. Auch Dateien und
Verzeichnisse, die existieren, aber nicht gelesen werden können, werden von „$(wildcard)“ nicht zurückgegeben.

Schnur Funktionen
Präfix hinzufügen Präfix, Worte
Stellt jedem Wort die Präfixzeichenfolge voran. Dies ist hauptsächlich für GNU-Make
Kompatibilität; Mit der Erweiterung im RC-Stil kann dies auf eine besser lesbare Weise erfolgen
so was:

MODULE := abcd
X_OLD_STYLE := $(addprefix $(OBJDIR)/, $(addsuffix .o, $(MODULES)))
X_NEW_STYLE := $(OBJDIR)/$(MODULES).o # Ist das nicht einfacher zu lesen?

Zusatzsuffix Suffix, Worte
Hängt die Suffixzeichenfolge an jedes der Wörter an. Dies ist hauptsächlich für GNU-Make
Kompatibilität; Mit der Erweiterung im RC-Stil kann dies auf eine besser lesbare Weise erfolgen
so was:

X_OLD_STYLE := $(addsuffix .o, $(MODULES))
X_NEW_STYLE := $(MODULES).o

rufen Sie uns an! Variable[, Wörter]...
Die Funktion „call“ ist insofern einzigartig, als sie zur Betrachtung verwendet werden kann Variable als ein
parametrisierte Funktion. Sie können ihm einen komplexen Ausdruck zuweisen Variable Und verwenden
„Aufruf“, um seinen Inhalt auf verschiedene Werte zu erweitern, die durch parametrisiert werden Worte später. In
Bei anderen Make-Systemen handelt es sich um eine Variable, die hauptsächlich für den Zweck der Erweiterung verwendet wird
„Anruf“, heißt a Makro.

Bei der Erweiterung des Makros werden die temporären Variablen $1, $2, "..." siehe die
Argumente, die „call“ während seines Aufrufs übergeben werden. Die Variable $0 wird erweitert auf
der Name des Makros (z. B Variable), dieser „Aufruf“ wird derzeit erweitert.

Es gibt keine Begrenzung, mit wie vielen Argumenten ein Makro „aufgerufen“ werden darf bzw. wie viele
Parameter, die ein Makro erwarten kann. Wenn Sie als Makro mehr Argumente an „call“ übergeben
Bei Bedarf werden alle darüber hinausgehenden Argumente verworfen. Wenn Sie weniger Argumente übergeben als a
Wenn das Makro erwartet, werden alle darüber hinausgehenden Parameter in den leeren String umgewandelt.

Zunächst ein einfaches Beispiel:

rest = $(wordlist 2, $(words $(1)),$(1))
Liste = ABCDE
butfirst := $(call rest,$(list))

Hier enthält die Variable „$(butfirst)“ die Liste „BCDE“.

Und nun ein komplexeres Beispiel, um zu zeigen, was möglich ist:

rest = $(wordlist 2,$(words $(1)),${1})
mymap = $(if $2,$(call $1,$(firstword $2)) $(call $0,$1,$(call rest,$2)))
downcase = ${makeperl lc("$1")}

UCWORDS = ALLE DIESE WÖRTER SIND UPCASE
DCWORDS := $(call mymap,downcase,$(UCWORDS))

Jetzt enthält „$(DCWORDS)“ „alle diese Wörter sind in Groß-/Kleinschreibung geschrieben“. Übrigens: Es macht nein
Unterschied, ob wir über auf die Argumente zugreifen $1, „${1}“ or „$(1)“ innerhalb eines Makros.

Sie können die Variable direkt verwenden, als wäre sie eine Funktion, wenn keine vorhanden ist
Funktion dieses Namens. Dies wird intern in „call“ umgewandelt, also sind es diese
Äquivalent:

Diskussion = Aus $0 wurde $1 $2.
direkt = $(Diskussion und Argument)
aufgerufen = $(call diskussion,an,argument)

Es könnte fraglich erscheinen, ob „$[call]“ auch das „$[]“ des Makros erweitern sollte.
Ausdrücke, oder ob eine Funktion immer das Gleiche tun soll, egal wie es ist
wird genannt. Letzteres wurde gewählt, da dies bei normaler Make-Syntax der Fall wäre
Es ist unmöglich, „$[1], $[2]…“ in eine Variable zu bekommen (sie würden durch nichts ersetzt werden,
bevor die Zuweisung überhaupt stattfindet.) Wenn Sie also ein Makro zum Definieren von a haben
Regel möchten Sie, dass Ausdrücke wie „$(output)“ angezeigt werden, wenn die Regel analysiert wird
Sie müssen sie vor „Anrufen“ schützen:

Definiere meine Regel
2 US-Dollar: 1 US-Dollar
mycommand $$(Eingabe) -o $$(Ausgabe)
Endef
$[myrule myinput,myoutput]

Filter Muster, Worte
Gibt alle Wörter in der Liste zurück, die den Mustern entsprechen. Muster können einfach anders sein
Wörter oder Dateinamen-Platzhalter (z. B. „*“, „?“ und „[az]“ werden erkannt), oder sie können es tun
haben ein „%“-Zeichen, was bedeutet, dass sie mit jeder Zeichenfolge an dieser Stelle übereinstimmen (dasselbe wie „*“).

Aussortieren Muster, Worte
Gibt alle Wörter in der Liste zurück, die nicht mit den Mustern übereinstimmen. Muster können einfach sein
andere Wörter oder Platzhalter für Dateinamen (z. B. „*“, „?“ und „[az]“ werden erkannt), oder
Sie können ein „%“-Zeichen haben, was bedeutet, dass sie mit einer beliebigen Zeichenfolge an dieser Stelle übereinstimmen (dasselbe wie
„*“).

Beispielsweise:

libproduktion.a: $(filter_out test_*, $(wildcard *.o))

wird alles setzen .o Dateien, die vorhanden sind oder erstellt werden können, mit Ausnahme derjenigen, die mit beginnen Test_,
in libproduktion.a.

Suchzeichenfolge finden, in
Return gefunden, wenn es ein Teilstring von ist in.

erstes Wort Worte
Geben Sie das erste Wort zurück.

Karte Wörter, Perlcode
Makemap Wörter, Perlcode
Gilt ähnlich wie bei Perls Karte Perlcode zu jedem Wort der Reihe nach und gibt das zurück
Ergebnisse. Die erste Variante ist reiner Perl-Code, während die zweite Variante zunächst durchläuft
den Perlcode durch Variablenerweiterung im Make-Stil. Die Wörter werden in beiden erweitert
Fälle.

Die Wörter sind in $_ und werden zurückgegeben, es sei denn, Sie haben $_ aufgehoben. Dies ist gedacht für
Änderungen, die von „patsubst“ nicht einfach gehandhabt werden können. Nur das erste Komma ist ein Trennzeichen,
Alle anderen gelten als Teil davon Perlcode.

# Wörter wechseln. Doppelte Klammern, um Klammern in Perlcode zuzulassen, oder verwenden Sie ${}:
X = $((map $(VALUES), s/(.+)-(.+)/$2-$1/))
# Sie können Make-Ausdrücke verwenden, müssen dann aber $$ für Perl $ verwenden:
Y = $(makemap $(VALUES), tr/$(OLDCHARS)/$(NEWCHARS)/ oder $$_ = 'failed')
# Sie können Kandidaten ausschließen:
Y = $(map $(VALUES), undef $_ if /no_good/)

join Wörter1, Wörter2
Führen Sie eine paarweise Verbindung der ersten und zweiten Wörter durch.

patsubst Muster, Ersatz, Worte
Führt eine Ersetzung für jedes Wort in der Wortliste durch. Ein „%“-Zeichen entspricht jedem
Zeichenfolge. Dies lässt sich am besten anhand eines Beispiels veranschaulichen:

OBJS = $(patsubst %.c, object_dir/%.o, $(C_SOURCES))

Nimmt jede Datei in C_SOURCES und gibt den Namen einer Objektdatei in object_dir zurück.
Manchmal ist es prägnanter, eine Substitutionsreferenz zu verwenden, z. B. wie oben
wurden geschrieben als

OBJS = $(C_SOURCES:%.c=object_dir/%.o)

sortieren word1 word2 word3 ...
Sortiert die Wörter in lexikalischer Reihenfolge und entfernt Duplikate.

abstreifen Schnur
Entfernt führende und nachfolgende Leerzeichen aus der Zeichenfolge und ersetzt alle internen Leerzeichen
Folge von einem oder mehreren Leerzeichen mit einem einzelnen Leerzeichen. Somit gilt: „$(strip ab
c )“ ergibt „abc“.

subst von, bis, Text
Führt eine Textersetzung für den Text durch: Jedes Vorkommen von from wird ersetzt
von bis. Das Ergebnis ersetzt den Funktionsaufruf. Zum Beispiel,

$(subst ee,EE,foots on the street)

ersetzt die Zeichenfolge „fEEt on the strEEt“.

Wort n,Text
Liefert die nDas Wort von Text. Die legitimen Werte von n Beginnen Sie am Anfang bei 1
oder rückwärts von -1 am Ende. Wenn n ist größer als die Anzahl der Wörter darin Text, der
Wert ist leer.

Wortliste Indexliste, Worte
Wortliste erster Index, Lastindex, Worte
Im ersten Formular geben Sie eine Liste von Indizes an (zählend von 1 am Anfang oder
rückwärts von -1 am Ende), um die gewünschten Wörter auszuwählen. In der zweiten Form du
Geben Sie den Bereich der Wörter an, die zurückgegeben werden sollen.

Worte Text
Gibt die Anzahl der Wörter zurück Text.

Weitere Anwendungsbereiche Funktionen
foreach var,Liste,Text
Die ersten beiden Argumente, jung und Liste, werden erweitert, bevor etwas anderes getan wird; Notiz
dass das letzte Argument, Text, nicht gleichzeitig erweitert wird. Dann für jedes Wort von
der erweiterte Wert von list, auf den die durch den erweiterten Wert von var benannte Variable gesetzt wird
dieses Wort und der Text werden erweitert. Vermutlich enthält der Text Verweise auf diese Variable.
daher wird seine Ausdehnung jedes Mal anders sein.

Dieses einfache Beispiel legt die Variable fest Dateien zur Liste aller Dateien im
Verzeichnisse in der Liste dirs:

dirs := abcd
Dateien := $(foreach dir,$(dirs),$(wildcard $(dir)/*))

Hier ist der Text „$(wildcard $(dir)/*)“. Die erste Wiederholung findet den Wert „a“ für dir,
es erzeugt also das gleiche Ergebnis wie „$(wildcard a/*)“; die zweite Wiederholung ergibt
das Ergebnis von „$(wildcard b/*)“; und der dritte, der von „$(wildcard c/*)“.

Dieses Beispiel hat das gleiche Ergebnis (außer der Einstellung von „dirs“) wie das folgende Beispiel:

Dateien := $(Platzhalter a/* b/* c/* d/*)

Wenn der Text kompliziert ist, können Sie die Lesbarkeit verbessern, indem Sie ihm einen Namen mit einem geben
zusätzliche Variable:

find_files = $(Platzhalter $(dir)/*)
dirs := abcd
Dateien := $(foreach dir,$(dirs),$(find_files))

Hier verwenden wir die Variable find_files auf diese Weise. Wir verwenden einfaches „=", um a zu definieren
rekursiv expandierende Variable, sodass ihr Wert einen tatsächlichen Funktionsaufruf enthält
unter der Kontrolle von foreach erneut erweitert werden; eine einfach erweiterte Variable würde nicht genügen,
da Wildcard zum Zeitpunkt der Definition von find_files nur einmal aufgerufen würde.

Hinweis: Verwechseln Sie dies nicht mit der speziellen Variablen „$(foreach)“.

Info Text
Warnung Text
Fehler Text
Ausgabetext, der das Nichts zurückgibt. Der erste geht an STDOUT, der zweite an STDERR,
der dritte bricht zusätzlich die Verarbeitung ab.

vorgefertigt Ziele
um Ziele
Gibt sein Argument wörtlich zurück, erstellt aber zunächst alle aufgelisteten Dateien. Das ist nützlich
wenn eine bestimmte Datei beim Auswerten eines Make-Ausdrucks benötigt wird. Dies geschieht normalerweise
wenn Sie einen Build haben, bei dem die Menge der beteiligten Dateien von einer Shell berechnet wird
Befehle. Zum Beispiel,

Dateiliste:
# Shell-Befehle zum Berechnen einer Liste von Dateien, die in das Programm eingefügt werden sollen

my_program : $(&cat $(prebuild file_list))

Wenn Sie die Liste in mehr als einer Regel benötigen, wäre es effizienter, eine zu verwenden
höchstens einmal erweitern Variable:

file_list ;= $(&cat $(prebuild file_list))

my_program1 : ao $(file_list)

my_program2 : bo $(file_list)

Wenn Sie stattdessen nur „$(&cat file_list)“ angeben würden, würde makepp dies nicht erzwingen
file_list muss auf dem neuesten Stand sein, bevor der Shell-Befehl ausgeführt wird. Verwendung von „$(prebuild )“
ist der beste Weg, dieses Problem zu lösen. Sie könnten versucht sein, andere Dinge auszuprobieren, z
Dies:

my_program : file_list $(&cat file_list)

Dies funktioniert jedoch nicht, da „$(&cat file_list)“ ausgewertet wird, bevor makepp es versucht
Erstellen Sie „file_list“.

only_phony_targets Namen
Gibt nur die Namen in der Liste zurück, die falsche Ziele einer Regel sind (entweder
explizite Regeln oder Musterregeln). Sie können Platzhalter angeben (einschließlich Makepps Spezial).
Platzhalter „**“) in den Dateinamen ein. (Weitere Einzelheiten finden Sie in der Funktion „$(wildcard)“.
Dies kann beispielsweise zum Gruppieren von Zielen verwendet werden:

$(falsche Tests): $(only_phony_targets */**/tests)

Herkunft Variable
Anhand des Namens einer Variablen erfahren Sie, woher ihr Wert kommt.

perl Perlcode
makeperl Perlcode
Wertet Perlcode in einem Block aus und gibt das Ergebnis zurück. Die erste Variante ist einfaches Perl
Code, während die zweite Variante zuerst den Perlcode durch eine Variable im Make-Stil übergibt
Erweiterung.

Beachten Sie, dass wie bei allen Funktionen das verwendete Funktionstrennzeichen möglicherweise nicht darin erscheint
der Perlcode außerhalb von Zeichenfolgen in einfachen oder doppelten Anführungszeichen. Aber Sie können es wie folgt verdoppeln
das letzte Beispiel:

VAR = 1
VAR1 = ${perl ($VAR + 1) * 3}
VAR2 = $(perl do { $VAR *= 3; return $VAR + 1 } if $VAR)
VAR3 = $(makeperl $(VAR1) * 3 + $$VAR) # eine Make-Variable und eine Perl-Variable
VAR = $((perl if( ... ) { ... }))

falsch Worte
Zeigt an, dass es sich bei der Liste der Wörter tatsächlich um falsche Ziele handelt, und gibt die Liste der Wörter zurück
Ziele. Es soll wie folgt verwendet werden:

$(falsche alle): my_program

$(gefälschte Reinigung):
&rm -f *.o mein_Programm

Sie können mit einer Zeile wie dieser auch überall dort ein oder mehrere Ziele als gefälscht deklarieren
Dein Makefile:

.PHONY: alles sauber

drucken Text
Gibt den Text aus und gibt ihn zurück. Dies ist vor allem zum Debuggen nützlich, wenn Sie dies nicht tun
Verstehen Sie, warum die Variablensubstitution zu dem Ergebnis führt, das sie hat. Zum Beispiel,

XYZ := $(print $(patsubst %.c, %o, $(SOURCE_FILES)))

gibt das Ergebnis des „patsubst“-Aufrufs aus.

XYZ := $(patsubst %.c, %o, $(print $(SOURCE_FILES)))

gibt das letzte Argument des „patsubst“-Aufrufs aus.

Schale Shell-Befehl
Gibt die Ausgabe des angegebenen Shell-Befehls zurück, wobei Zeilenumbrüche durch Leerzeichen ersetzt werden.

Beachten Sie, dass wie bei allen Funktionen das verwendete Funktionstrennzeichen möglicherweise nicht darin erscheint
Der Shell-Befehl außerhalb von Zeichenfolgen in einfachen oder doppelten Anführungszeichen. Aber man kann es verdoppeln
wie im zweiten Beispiel:

date = $(Shell-Datum) # besser: $(perl scalar localtime)
VAR = ${{shell f() { echo hallo; }; F}}

xargs Befehl,Argumente[,Suffix[,Länge]]
Gibt eine durch Zeilenumbrüche getrennte Liste von Befehlen zurück, die jeweils mit dem angegebenen beginnen
Befehl und schließen Sie mit so vielen Elementen der Liste wie möglich ab, ohne sie durchzugehen
Länge (Standard 1000) Zeichen.

Der Zweck besteht darin, eine Überschreitung der Befehlslängenbeschränkung auf Ihrem System zu vermeiden.
Wenn beispielsweise viele generierte Dateien vorhanden sind, möchten Sie wahrscheinlich Ihre
clean target (was Sie nicht haben sollten, da „makeppclean“ effizienter ist) zu
sieht in etwa so aus:

$(gefälschte Reinigung):
$(xargs $(RM), $(only_targets **/*))

Dies hat auch den Nebeneffekt, dass bei der Liste überhaupt kein Befehl generiert wird
ist zufällig leer. Aber in diesem Fall wäre es besser, das eingebaute &rm zu verwenden,
weil die Argumente für die eingebauten Befehle nur durch den Speicher von Perl begrenzt sind:

$(gefälschte Reinigung):
&rm -f $(only_targets **/*)

Wenn ein drittes Argument angegeben wird, wird es zum Postfixieren jedes Befehls verwendet. Das ist
nützlich für die Angabe von Redirectoren, z. B. (obwohl auch hier wieder &echo helfen würde):

Manifest:
&rm -f $@
&berühre $@
$(xargs echo, $(only_nontargets **/*), >> $@)

Ein Teil dieser Dokumentation basiert auf der GNU-Make-Dokumentation.

Bitte beachten Sie, dass, wenn eine Funktion während der Makefile-Initialisierung aufgerufen wird, z. B. die
Bei der Erweiterung von Exportvariablen wird bei Fehler- oder Warnmeldungen die Zeilennummer 0 gemeldet.

Verwenden Sie makepp_functions online über die Dienste von onworks.net


Kostenlose Server & Workstations

Laden Sie Windows- und Linux-Apps herunter

Linux-Befehle

Ad