Dies ist der Befehl makepp_scanning, 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_scanning – Wie makepp Include-Dateien und andere versteckte Abhängigkeiten findet
BESCHREIBUNG
Makepp kann für bestimmte ihm bekannte Befehle zusätzliche Abhängigkeiten oder Ziele ermitteln
etwas über. Dies ist besonders wichtig für die C/C++-Kompilierung, wo dies auch der Fall ist
Es ist fehleranfällig, alle Include-Dateien, von denen eine bestimmte Quelldatei abhängt, manuell aufzulisten.
Durch einen Blick auf den Kompilierungsbefehl und die Quelldateien selbst ist makepp dazu in der Lage
Bestimmen Sie genau, welche Objektdateien neu erstellt werden müssen, wenn einige Dateiänderungen enthalten.
Beispiel: Gegeben eine Regel
foo.o: # Normalerweise %.o: %.c, nur zur Veranschaulichung
time -p /bin/libtool -bar /usr/bin/cc -c -I irgendwo foo.c
makepp weiß, dass „time“ und „libtool“ übersprungen werden müssen und dass „cc“ der eigentliche Befehl ist
hier analysiert werden. Es versteht das foo.c ist die Eingabedatei und somit eine Abhängigkeit von
diese Regel. Darüber hinaus wird die Datei nach Include-Anweisungen durchsucht, auch in
Verzeichnis irgendwo, weil es die Befehlsoptionen verstanden hat.
Eigentlich gibt es drei Schritte zu dem, was historisch als Scannen bekannt ist:
1. Die Regelaktion wird in Zeilen aufgeteilt (Fortsetzungszeilen zählen als eine). Jede Zeile
(außer Builtins und Perl-Blöcken) ist lexikalisch analysiert als ein oder mehrere Shell-Befehle.
Umleitungen werden als Eingaben oder Ausgaben dieser Regel erkannt. Das erste Wort von jedem
Der Befehl wird nachgeschlagen (mit seinem Verzeichnisteil, aber, wenn er nicht gefunden wird, erneut ohne).
Finden Sie einen Parser dafür. Diese werden zu optionalen Abhängigkeiten, sie werden nach Möglichkeit erstellt,
wird aber ignoriert, wenn es nicht gefunden wird, da makepp nicht wissen kann, um welchen Teil eines komplexen Befehls es sich handelt
tatsächlich laufen.
Befehle in Backquotes werden analysiert, aber nicht ausgeführt. (Oft ist die Ausführung wichtig,
aber das wäre ein großer Eingriff seitens makepp.) Es ist besser, sie zu vermeiden.
Lassen Sie stattdessen makepp den Befehl höchstens einmal ausführen, indem Sie ihn auf diese spezielle Weise zuweisen:
XYZFLAGS ;= $(shell pkg-config --cflags xyz)
Derzeit gibt es nur eine Lexer-Klasse, die Bourne Shell versteht. Verbessern
Wenn Sie die C-Shell oder „command.com“ verarbeiten, können Unterklassen erstellt werden. Es gibt jedoch viel Syntax
ähnlich genug, um dies nicht zu rechtfertigen. Wenn auch Sie einen Beitrag leisten möchten, nehmen Sie Kontakt mit uns auf.
2. Für bekannte Befehle die entsprechenden Befehl Parser (auch nur als Parser bezeichnet)
analysiert die wichtigen Optionen und Argumente. Die verfügbaren werden im Folgenden beschrieben.
Auch wenn kein spezialisierter Parser gefunden wurde, macht der generische Parser den Befehl ausführbar
eine Eingabe dieser Regel. Sie können dies mit --no-path-executable-dependencies ändern
Befehlsoption.
3. Wenn der Parser Eingabedateien erkannt hat, werden diese an gesendet Scanner gewählt von der
Parser. Weitere Eingaben findet es, indem es nach „#include“ oder vergleichbaren Anweisungen sucht.
Dies ist der teuerste Schritt. Alle Ergebnisse werden zwischengespeichert, um Wiederholungen zu vermeiden
unnötigerweise.
Wenn makepp denkt, dass es eine C/C++-Quelle kompiliert, aber keinen Parser finden kann, gibt es eine Fehlermeldung aus
Warnmeldung, um Sie darüber zu informieren. Dies bedeutet normalerweise, dass Sie Ihren Compilerbefehl vergraben haben
zu tief im Geschehen, als dass Makepp es finden könnte. Ich habe zum Beispiel Regeln wie diese gesehen:
%.o: %.c
@echo Kompiliert $< jetzt; obscure_wrapper gcc -c $< $(CFLAGS) -o $@
Die ersten Wörter der Aktionen sind hier „echo“ und „obscure_wrapper“, für die es solche gibt
Keine Parser, daher sucht makepp in diesem Fall nicht nach Include-Dateien. Sie können das ignorieren
vorangestellter Befehl von:
Register-Parser obscure_wrapper Skip-Wort
In den folgenden Abschnitten werden die integrierten Parser und Scanner dokumentiert. Im Namen kannst du
Verwenden Sie „-“ austauschbar mit „_“.
SCANNER (PARSER)
Die verschiedenen Scanner müssen von einem Befehlsparser ausgewählt werden, der in Klammern angegeben ist:
C / C ++ Zusammenstellung (C-Zusammenstellung, gcc-Kompilierung)
Der C/C++-Scanner behandelt beide Sprachen gleichgültig. Tatsächlich schaut es nur an
Präprozessoranweisungen, so dass es für eine ganze Reihe von Sprachen verwendet werden kann. Der Parser das
Aktiviert es eine spezielle Variante für die vielen Optionen von gcc, die ausgewählt wird, wenn die
Der Befehlsname enthält die Zeichenfolge „gcc“ oder g++. Wenn Compiler für andere Sprachen mit C
Wenn der Präprozessor dieselben Optionen wie der C-Compiler verwendet (mindestens „-I“), funktioniert dieser Parser
fein.
Es sucht im Befehl nach „-Idir“-Optionen, die den Include-Pfad angeben, oder nach „-Ldir“-Optionen
Angabe des Linkpfads. Anschließend werden alle Quelldateien nach „#include“-Anweisungen durchsucht
Schaut auch in der Befehlszeile nach, ob Quelldateien oder Bibliotheken erwähnt werden
die nicht als Abhängigkeiten aufgeführt sind. Diese erkennt es an der Erweiterung.
Dieser Scanner gibt eine Warnmeldung aus, wenn Dateien, die mit „#include „file.h““ eingebunden sind, nicht enthalten sind
im Include-Pfad oder im Verzeichnis gefunden, das von makepp nicht erstellt werden kann
Datei, die „#includ“ ist, oder in / usr / include. Es wird keine Warnung ausgegeben, wenn eine Datei enthalten ist
mit „#include " wurde nicht gefunden. Makepp geht davon aus, dass es in einem System enthalten ist
Verzeichnis, das dem Compiler bekannt ist und dass Dateien im System Verzeichnisse enthalten
wird sich nicht ändern.
Darüber hinaus Dateien in / usr / include, /usr/local/include, /usr/X11R6/includeund alle anderen
Verzeichnisse, die nicht beschreibbar sind, werden nicht gescannt, um festzustellen, was sie enthalten. Makepp geht davon aus
dass sich diese Dateien nicht ändern. (Wenn Sie als Root ausgeführt werden, erfolgt der Beschreibbarkeitstest
wird mit der UID und GID des Verzeichnisses durchgeführt, aus dem Sie makepp ausgeführt haben. Das ist so kompilierend
Ein Programm als normaler Benutzer auszuführen und dann „makepp install“ als Root auszuführen, verursacht keine zusätzlichen Kosten
Verzeichnisse, die gescannt werden sollen.)
Dies ist ein ziemlich einfältiger Scanner. Es wird verwirrt, wenn Sie Dinge wie diese tun:
#ifdef INCLUDE_THIS
#include „this.h“
#endif
weil es nichts über Präprozessorbedingungen weiß. Dies ist normalerweise harmlos; Es
kann dazu führen, dass zusätzliche zusätzliche Dateien als Abhängigkeiten gekennzeichnet werden (was gelegentlich zu Problemen führt).
unnötige Neuerstellungen), andernfalls könnte es dazu führen, dass makepp eine Warnung ausgibt, dass die Include-Datei nicht vorhanden ist
gefunden. Sie können die Warnmeldungen entweder ignorieren oder eine leere Datei „this.h“ ausgeben
da, um Makepp zum Schweigen zu bringen.
Wenn Ihr Compiler einen lustigen Namen hat, können Sie einen der beiden Namen sagen
Register-Parser obscure_c_compiler C-Kompilierung
register-parser obscure_gcc_alias gcc-compilation
Embedded SQL C / C ++ Zusammenstellung (Esql-Kompilierung)
Diese Befehle, die mit den verschiedenen Datenbanken geliefert werden, verarbeiten spezielle Abschnitte in vor
andernfalls C/C++-ähnliche Quellen und erzeugen C/C++-Header und -Quellen. Dadurch wird EXEC SQL gefunden
INCLUDE „Dateiname“- oder $INCLUDE „Dateiname“-Anweisungen.
Diese Präprozessoren werden erkannt: Altibase APRE*C/C++ (apre), CASEMaker DBMaker
(dmppcc), Firebird / InterBase (gpre), IBM DB2 (db2 vorkompilieren, db2 prep) & Informix
ESQL/C (esql), Ingres (esqlc), Mimer (esql), Oracle (proc), PostgreSQL (EKG) & HOF
(Yardpc). Wenn Ihr Präprozessor nicht erkannt wird, können Sie sagen
register-parser obscure_esqlc_preprocessor esql-compilation
Dies behandelt jedoch nur den Stil, der Informix und anderen gemeinsam ist: Befehlsargumente
mit der Endung „.ec“ sind zu scannende Dateien, „-I“ definiert den Include-Pfad und EXEC SQL
INCLUDE-Direktiven ohne Suffix wird „.h“ angehängt.
Schluck (Schluck)
Swig (vereinfachter Wrapper- und Schnittstellengenerator, http://www.swig.org/) ist ein Programm, das
Konvertiert eine C/C++-Header-Datei in die Wrapper-Funktionen, die erforderlich sind, um Ihren Code aufrufbar zu machen
aus einer Vielzahl anderer Sprachen, wie Perl, Python, Tcl, C#, Ruby, OCaml und
wahrscheinlich noch einige andere, von denen ich nichts weiß.
Makepp versteht und analysiert die Swig-Befehlszeile und sucht nach den Optionen „-I“ und „-l“.
Es weiß auch, wie die Schnittstellendefinitionsdateien von swig gescannt werden (.i Dateien) gesucht
%include, %import und auch „#include“, wenn „-includeall“ wirksam ist.
Wenn Ihr Schluck einen lustigen Namen hat, können Sie sagen
register-parser obscure_swig_alias swig
Vera und Verilog (vcs_compilation)
Wenn Sie Hardware entwerfen, ist dies praktisch.
Ignorierbar Wrapper (Überspringwort, Hülse)
Makepp erkennt die folgenden und viele weitere Befehlswörter und überspringt sie
Geben Sie bei der Suche nach dem richtigen Scanner entsprechend Folgendes ein: „condor_compile“, „distcc“,
„ignore_error“, „libtool“, „noecho“ „purify“.
Es gibt eine Variante davon, die die verschachtelten Befehle in „sh -c 'command1;“ findet.
command2'".
Wenn Sie mehr solcher Befehle haben, können Sie sagen
Register-Parser-Befehl Skip-Wort
Libtool
Libtool ist ein sehr cleveres Kompilierungssystem, das die gemeinsame Nutzung erheblich vereinfacht
Bibliotheken, indem alle systemabhängigen Details in einem Shell-Skript versteckt werden. Die einzige
Die Schwierigkeit besteht darin, dass die Binärdateien der Bibliothek nicht tatsächlich im selben Verzeichnis gespeichert sind
Als Ausgabedatei erstellt libtool tatsächlich ein Unterverzeichnis „.libs“, das die Datei enthält
echte Dateien. Normalerweise ist das kein Problem, aber makepp muss wissen, wo das Original ist
Binärdateien sind, wenn es darum geht, sie aus einem Repository einzubinden. Im Moment libtool-Bibliotheken
(„.la“-Dateien) werden nicht aus Repositorys verlinkt; Sie werden bei Bedarf immer wieder aufgebaut.
Außerdem ist makepp derzeit nicht in der Lage, die gespeicherten Abhängigkeitsinformationen zu verwenden
in der Datei „.la“ selbst. Das wird sich hoffentlich bald ändern.
Unterdrücken Scan (Keine)
Manchmal möchten Sie möglicherweise nicht, dass eine Regel oder ein bestimmter Befehl analysiert wird. Sie können es ausschalten
Parsen und damit Scannen mit
Register-Parser CC keine
VERBINDUNG OPTIONAL
schneller Scan und intelligente Suche
Die Regeloptionen „:quickscan“ und „:smartscan“ (sofern zutreffend) wirken sich auf die Art und Weise aus, wie Dateien abgelegt werden
werden gescannt.
Im „:quickscan“-Modus (Standardeinstellung) werden alle Include-Anweisungen als aktiv angenommen. Dies erlaubt
für sehr effizientes Scannen.
Im Modus „:smartscan“ wird versucht, Makros und Ausdrücke so zu interpretieren, dass
Inaktive Include-Anweisungen werden ignoriert. Zum Beispiel die ausführbare Datei, die von erstellt wurde
Das Kompilieren des folgenden C-Programms sollte nicht abhängig sein von foo.h:
#if 0
#include "foo.h"
#endif
int main() { return 0; }
KUNDENSPEZIFISCH SCANNER
Sie können Ihren eigenen Parser entweder in einer Regeloption wie „:parser foo“ oder mithilfe von angeben
die Anweisungen „register_parser“ oder „register_command_parser“.
So oder so, wie unter „register_parser“ beschrieben, müssen Sie dort direkt oder indirekt vorgehen
(über eine Klasse) geben Sie eine Funktion an, die ein Parser-Objekt erstellt. Dieses Objekt wird normalerweise
Erstellen Sie ein Scannerobjekt für Dateien und füttern Sie es über die Befehlszeile mit seinen Ergebnissen
Optionen. Diese beiden Objekte rufen die „add_*_dependency“-Methoden des Parsers auf
Leiten Sie die Informationen an das etwas kompliziertere „Mpp::Lexer::add_*_dependency“ weiter.
Dienstprogrammfunktionen.
In einfachen Fällen kann Ihre Parser-Funktion diese Arbeit jedoch auch selbst erledigen. Es gibt eine
einige spezielle Rückgabewerte, wenn diese Funktion kein Parser-Objekt zurückgibt:
"undef"
Die Scan-Informationen können nicht zwischengespeichert werden und müssen beim nächsten Aufruf der Regel neu berechnet werden
muss gebaut werden.
„p_none, p_skip_word“ oder „p_shell“
Dabei handelt es sich tatsächlich um numerische Konstanten, die den Lexer anweisen, die Arbeit dieser Konstanten zu erledigen
Pseudo-Parser.
beliebige Referenz, z. B. „\1“
Dies entspricht der Rückgabe eines Parser-Objekts der Basis „Mpp::CommandParser“.
Klasse, die den ausführbaren Befehl nur zusätzlich selbst zu einer Abhängigkeit macht.
In den meisten Fällen sollten Objekte vom Typ „Mpp::CommandParser“ mindestens ein Objekt instanziieren
vom Typ „Mpp::Scanner“. Für die Unterscheidung sorgt die Basisklasse „Mpp::Scanner“.
zwischen Quickscan und Smartscan. Beachten Sie, dass das Verhalten von „Mpp::Scanner“ deutlich abweichen kann
von dieser Unterscheidung betroffen, sollte jedoch für die abgeleitete Klasse transparent sein, wenn dies der Fall ist
wohlgeformt. Neu abgeleitete „Mpp::Scanner“-Klassen sollten in beiden Modi getestet werden.
Wenn Sie Ihre eigene „Mpp::Scanner“-Klasse schreiben, sollten Sie auch Ihre Entscheidung zum erneuten Scannen darauf stützen
auf der Build-Info „RESCAN“. Dies wird durch „makeppreplay“ festgelegt, nachdem Dateien ohne signiert wurden
Scannen. Obwohl die Signaturen konsistent sind, ist dennoch ein erneuter Scan erforderlich. Wenn
Ihr „Mpp::Scanner“ die geerbte Methode „scan_file1“ verwendet, ist wahrscheinlich alles in Ordnung.
Weitere Einzelheiten finden Sie in der jeweiligen Klassendokumentation. Beispiele finden Sie unter
„Mpp::CommandParser::Gcc“ und „Mpp::CommandParser::Vcs“. Schauen Sie sich die „p_“-Funktionen in an
Mpp/Subs.pm die beim Laden in ihre jeweiligen Klassen als „Factory“ ein Alias erhalten.
Caching Scanner Info
Wenn alle wichtigen Nebenwirkungen des Scanners durch Methodenaufrufe bewirkt werden
der Basisklasse „Mpp::CommandParser“ können diese Nebenwirkungen im Build zwischengespeichert werden
info-Datei, sodass sie bei einem späteren Aufruf von makepp ohne abgespielt werden können
die gesamte kostspielige Scanarbeit übernehmen. Dies kann vor allem im Internet eine Menge Zeit sparen
Smartscan-Modus.
Wenn der Scanner andere wichtige Nebenwirkungen hat, sollte er die „Regel“-Objekte aufrufen
mark_scaninfo_uncacheable-Methode. Andernfalls werden die vom Build abgerufenen Scannerinformationen verwendet
Die Informationen sind möglicherweise ungenau, was dazu führen kann, dass das Build-Ergebnis falsch ist. Diese Methode ist
Wird automatisch aufgerufen, wenn ein Wert aus dem %parsers-Hash kein Objekt des Typs zurückgibt
„Mpp::CommandParser“, oder wenn der Parser mit einer Regeloption und dem „p_*“ angegeben wird
Die Routine gibt kein Objekt vom Typ „Mpp::CommandParser“ zurück.
Zwischengespeicherte Scaninformationen werden anhand von Kriterien ungültig gemacht, die denen zur Bestimmung des Zeitpunkts ähneln
Das Ziel ist veraltet. Ebenso kann es mit aus einem Repository abgerufen werden
Kriterien, die denen ähneln, die zur Bestimmung verwendet werden, wann ein Ziel von einem aus verlinkt werden kann
Repository.
Mit der Option „--force-rescan“ können Sie makepp zwingen, die zwischengespeicherten Scannerinformationen zu ignorieren.
Dies ist nützlich, wenn ein defekter Scanner möglicherweise dazu geführt hat, dass falsche Scannerinformationen zwischengespeichert wurden.
Ad Sprunggelenk Scanner
Oft haben Sie nur eine oder wenige Dateien, die Abhängigkeitsinformationen enthalten. Das tust du nicht
Ich möchte dies redundant in ein Makefile schreiben (da Redundanz später oft dazu führt).
Inkonsistenzen, wenn ein Update vergessen wird). Aber Sie möchten auch keine schreiben
Mpp::Scanner? Um dieses Problem zu umgehen, können Sie spontan eine Include-Datei generieren. Zum Beispiel
Qt hat .qrc Dateien, die wie folgt aussehen können:
ABC
xyz
...
Wenn Sie sich an das obige Layout halten, können Sie die relevanten Zeilen in ein Makepp umwandeln
Include-Datei, die beim Einbinden automatisch erstellt wird.
%.qrc.makepp: %.qrc
&grep 's! \n!$(stem).cc:! || S! * ! ! && S! \N!!' $(Eingabe) -o $(Ausgabe)
include $(wildcard *.qrc) # .makepp wird automatisch angehängt
Im Kochbuch sind dazu mehrere Varianten aufgeführt. Der Nachteil ist, dass Sie anfangen
Erstellen, während das Makefile gelesen wird. Daher ist die Befehlsoption --loop nicht so nützlich
bei der ersten Iteration.
Verwenden Sie makepp_scanning online über die Dienste von onworks.net