2016-06-03 11 views
11

PrecompiledHeader.h machen:Wie Klirren -E auslassen vorkompilierte Header

#include "stdio.h" 

main.cpp:

#include "PrecompiledHeader.h" 
#include "stdio.h" 

int main() 
{ 
    return 123; 
} 

Erstellen vorkompilierte Header:

clang -x c++-header PrecompiledHeader.h -o PrecompiledHeader.pch 

Lauf Klirren Präprozessor auf Haupt .cpp:

clang main.cpp -include-pch PrecompiledHeader.pch -E 

Dies gibt derzeit viele, viele Seiten der Ausgabe (stdio.h) aus. Ich möchte jedoch nur die Hauptfunktion erhalten und den Inhalt von PrecompiledHeader.h aus der Ausgabe auslassen.

Gibt es eine Möglichkeit, Clang dies zu tun? (Wenn jemand die Antwort auf die gleiche Frage für VisualStudio's cl.exe weiß würde ich gerne darüber auch wissen :)

+0

"Ich möchte nur die Hauptfunktion erhalten und den Inhalt von PrecompiledHeader.h aus der Ausgabe weggelassen haben." Das ist unklar. Wenn Sie (nur) den Inhalt von 'PrecompiledHeader.h' weglassen, erhalten Sie die Hauptfunktion * plus * den Inhalt von' stdio.h'. –

Antwort

4

Kaum ein solcher Weg existiert oder wird in Clang (oder einem anderen C++ Compiler) in der gebaut werden Zukunft. Das Problem besteht darin, dass vorkompilierte Header verwendet werden, um den Kompilierungsschritt zu beschleunigen, der normalerweise wesentlich teurer ist als der Vorverarbeitungsschritt. Wenn Sie Ihre Quelle nur vorverarbeiten, wird der vorkompilierte Header einfach nicht verwendet. Eine Möglichkeit, dass eine vernachlässigbar kleine Chance zu produzieren hat, was Sie wollen, ist die -include Option verwenden anstelle der -include-pch Option (beachten Sie, dass Sie die *.h angeben müssen, anstatt die *.pch Datei, um es):

clang main.cpp -include PrecompiledHeader.h -E 

Das garantiert Weg, um Ihr Problem zu lösen, ist die Präprozessorausgabe durch ein einfaches Filterprogramm zu Rohr, das an den # line "file" Richtlinien sieht und entfernt Text aus #include ed Dateien kommen:

clang main.cpp -E|remove_included_code 

remove_included_code lässt sich leicht DURCHFÜHRU nted in Python, Bash, C/C++, usw. Hier ist eine C++ Implementierung (C++ wurde so gewählt, dass es am einfachsten unter Windows verwendet werden kann):

remove_included_code.cpp

#include <iostream> 
#include <cstdlib> 

using namespace std; 
typedef std::string Str; 

bool isLineDirective(const Str& line) 
{ 
    return line.size() >= 3 
     && line[0] == '#' 
     && line[1] == ' ' 
     && isdigit(line[2]); 
} 

Str getFile(const Str& line) 
{ 
    const Str::size_type start = line.find_first_of('"') + 1; 
    const Str::size_type end = line.find_first_of('"', start); 
    return line.substr(start, end - start); 
} 

int main() 
{ 
    Str line; 
    getline(cin, line); 
    if (!isLineDirective(line)) { 
     cerr << "Error: Input must start with a '# line \"file\"' directive\n"; 
     exit(1); 
    } 

    const Str startFile = getFile(line); 
    Str currentFile = startFile; 
    while (getline(cin, line)) { 
     if (isLineDirective(line)) 
      currentFile = getFile(line); 
     else if (currentFile == startFile) 
      cout << line << endl; 
    } 

    return 0; 
} 

Die Vorteil dieser Lösung ist, dass sie mit allen Compilern funktioniert.

+1

Aus allen Sprachen Sie cpp für remove_included_code gewählt? – Dani

+1

@Dani Ich habe es aus einem bestimmten Grund getan. Obwohl es in der Tat absolut nicht die beste Sprache für die Textverarbeitung ist, hat ein einfaches Programm, das in C++ geschrieben ist, den Vorteil, dass es am wenigsten Abhängigkeiten für das Ausführen benötigt. Dies ist wichtig, wenn OP es unter Windows ausführen muss, wo Python und Bash keine Bürger der 1. Klasse sind. – Leon

1

edit: Ich sehe nichts besonderes über vorkompilierte Header in diesem Fall - jede Möglichkeit, die Erweiterung eines # include bedingt zu verhindern, wird tun.

Ich erreiche dies für Standard-Header enthält durch Umhüllen in einem ifdef, so dass die vorverarbeitete Ausgabe enthält #include "foo", aber nicht den Inhalt. Beispiel:

#ifdef PRECOMPILE 
#define TMP #include <stdio.h> 
TMP 
#undef TMP 
#else 
#include <stdio.h> 
#endif 

Dann übergeben Sie -DRECOMPILE zusammen mit -E.

Die vorverarbeitete Ausgabe enthält dann das nicht erweiterte #include. Ich finde dies nützlicher als die einfachere Alternative, das # include in #ifdef einzufügen, wenn die vorverarbeitete Ausgabe gelesen wird.

In erster Linie bedeutet dies, ich kann Macro-schweren Code durch den Präprozessor dann Clang-Format vor dem Kompilieren als normal ausführen, für eine weit verbesserte Debugging-Erfahrung.