2009-07-25 6 views
3

Ich habe ein Perl-Skript Ich möchte meine cpp/h-Dateien filtern, bevor gcc sie normal verarbeitet - im Grunde als ein zusätzlicher Vorverarbeitungsschritt. Gibt es einen einfachen Weg, dies zu tun? Mir ist klar, dass ich die cpp-Dateien dem Skript zuführen kann und gcc die Ausgabe von stdin gelesen habe, aber das hilft nicht bei den Header-Dateien.Filter C++ durch ein Perl-Skript?

Antwort

7

Die klassische Methode, einen solchen Prozess zu verarbeiten, besteht darin, den Quellcode (Eingabe in den Perl-Filter) als neue Sprache mit einem neuen Dateisuffix zu behandeln. Dann sagen Sie make, dass der Weg, um eine C++ - Quelldatei von diesem neuen Dateityp zu kompilieren, mit dem Perl-Skript ist.

Zum Beispiel:

  • New Suffix: .ccp
  • Neue Regel (unter der Annahme .cc Suffix):

    .ccp.cc: 
         ${FILTERSCRIPT} $< 
    
  • Fügen Sie das neue Suffix an die Suffixliste - mit Vorrang vor der normale C++ Regeln.

Der letzte Punkt ist der schwierigste. Wenn Sie einfach das .ccp Suffix der Liste hinzufügen, dann wird make nicht wirklich auf Änderungen in der .ccp Datei achten, wenn die .cc Datei existiert. Sie müssen entweder die Zwischen-.cc Datei entfernen oder sicherstellen, dass .ccp vor .cc in der Suffix-Liste angezeigt wird. (Hinweis: Wenn Sie eine '.ccp.o'-Regel ohne eine' .ccp.cc'-Regel schreiben und nicht sicherstellen, dass das Zwischenelement '.cc' bereinigt wird, dann kann eine Wiederherstellung nach einem Kompilierungsfehler dazu führen, dass make nur die '.cc' kompiliert. Datei, die frustrierend und verwirrend sein kann.)

Wenn die Änderung des Suffix keine Option ist, dann schreibe ein Kompilierungsscript, das die Filterung durchführt und den C++ - Compiler direkt aufruft.

2

Der C und C++ Präprozessor hat keine Unterstützung für diese Art von Sache. Die einzige Möglichkeit, dies zu umgehen, besteht darin, dass Ihr Makefile (oder was auch immer) alle Dateien über das Perl-Skript verarbeitet, bevor der Compiler aufgerufen wird. Dies ist offensichtlich sehr schwierig und ist ein sehr guter Grund dafür, keine Architekturen zu entwerfen, die einen solchen Schritt benötigen. Was machst du, dass du denkst, dass du eine solche Einrichtung brauchst? Es gibt wahrscheinlich eine bessere Lösung, die Ihnen nicht bekannt ist.

+0

stimme ich zu. Ich habe Makefiles mit komplexen Regeln für alle Arten von Quellcode-Vorverarbeitung gepflegt, und es macht wirklich nicht sehr viel Spaß. – JesperE

2

Wie wäre es mit einem Wrapper um gcc, der Ihr Perl-Skript ausführt und dann gcc aufruft? Nennen Sie es so etwas wie plgcc und setzen Sie CC=plgcc in Ihrem Makefile. Ihr Skript muss intelligent genug sein, um die Include-Anweisungen zu verarbeiten - es sei denn, Ihr Skript ruft nur den Pre-Prozessor auf, um die Includes einzubringen, macht seine Sache und ruft dann gcc auf.

2

GCC ermöglicht die Verwendung eines eigenen Präprozessors. Sie können Ihr Skript als Präprozessor festlegen und dann die Ausgabe über cpp (den normalen gcc-Preprozessor) ausführen. Sehen Sie sich das gcc-Handbuch für die Befehlszeilenoptionen -B und -no-integrated-cpp an.

Warnung - Ich habe es nie selbst ausprobiert, also nicht wissen, wie chaotisch es sein könnte (bedenken Sie, dass viele Sprachen, einschließlich C++, als Präprozessoren zum AC-Compiler implementiert wurden, so sollte Unterstützung nicht sei zu schlecht).

+0

C++ wurde nie als Präprozessor implementiert - es wurde ursprünglich als Compiler implementiert, der C anstelle von Objektcode oder Assemblersprache ausgibt –

+0

Die Verwendung von GCC-spezifischen Optionen verhindert natürlich, dass Ihr Code von anderen Compilern konsumiert wird. – JesperE

1

Ich habe Fälle wie diese in der Vergangenheit behandelt, indem ich so etwas wie das Folgende gemacht habe.Dieser Ansatz setzt voraus, dass der unverarbeitete Quellcode durch ein Benennungsschema irgendeiner Art unterschieden werden kann, in diesem Fall den Basisnamen mit _pp.

# These are your source files to be preprocessed 
SRC_RAW = mysrc_pp.cpp 

# These are the source files after preprocessing 
SRC_PP = $(patsubst %_pp.cpp, %.cpp, $(SRC_RAW)) 

ALL_SRC = $(SRC) main.cpp other.cpp 

OBJ = $(patsubst %.cpp, %.o, $(ALL_SRC)) 

$(SRC): %.cpp: %_pp.cpp 
     $(PERL) $< > [email protected] 

$(OBJ): %.o: %.cpp 
     $(CXX) ... 

Dies behandelt jedoch nicht den Fall, in dem Sie Header-Dateien haben, die Vorverarbeitung benötigen. In diesem Fall benötigen Sie ähnliche Regeln, um sie zu erstellen.

+0

Ich denke, die Header-Datei ist das Hauptproblem hier –