Wie rufe ich das Clang-Format über einen CPP-Projektordner auf?


88

Gibt es eine Möglichkeit, so etwas wie clang-format --style=Webkiteinen gesamten cpp-Projektordner aufzurufen , anstatt ihn für jede Datei separat auszuführen?

Ich benutze clang-format.pyund vimmache das, aber ich gehe davon aus, dass es eine Möglichkeit gibt, dies einmal anzuwenden.

Antworten:


47

Wie wäre es mit:

clang-format -i -style=WebKit *.cpp *.h

im Projektordner. Die Option -i macht es an Ort und Stelle (standardmäßig wird die formatierte Ausgabe in stdout geschrieben).


1
oder wenn Sie eine Konfigurationsdatei verwenden und mehrere Dateitypen formatieren möchten: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
— mBardos

43
Leider wird dies nicht in Unterverzeichnisse zurückgeführt.
— Antimon

4
Ja, * .cpp wird von der Shell erweitert. clang braucht nur eine Liste von Dateien. Erweiterte Optionen (wie rekursives Globbing) hängen von den Funktionen Ihrer Shell ab. Informationen zur Verwendung von **Konstrukten finden Sie unter unix.stackexchange.com/questions/49913/recursive-glob .
— Sbarzowski

Was ist mit clang-tidy?
— Aaron Franke

@AaronFranke Das *.cppGenerieren einer Liste von Dateien sollte funktionieren. Der clang-tidyBefehl ermöglicht die Übergabe mehrerer Dateien. `USAGE: clang-tidy [options] <source0> [... <sourceN>]` In der Praxis ist dies jedoch möglicherweise nicht der beste Weg. Clang-tidy führt eine viel tiefere Analyse durch, daher sind die Compiler-Flags für jede Datei usw. erforderlich. Wenn ich clang-tidy verwendete, hatte ich normalerweise eine "Kompilierungsdatenbank" - eine JSON-Datei mit den Befehlen für jede Datei und einem Skript, das ausgeführt wurde darüber. Es war vor ein paar Jahren, vielleicht gibt es jetzt einen besseren Weg.
— Sbarzowski

88

Leider gibt es keine Möglichkeit, das Clang-Format rekursiv anzuwenden. *.cppstimmt nur mit Dateien im aktuellen Verzeichnis überein, nicht mit Unterverzeichnissen. Auch **/*funktioniert nicht.

Zum Glück gibt es eine Lösung: greift alle Dateinamen mit dem findBefehl und Rohr sie in zum Beispiel, wenn Sie alle formatieren möchten. .hUnd .cppDateien im Verzeichnis foo/bar/rekursiv, können Sie tun

find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i

Weitere Informationen finden Sie hier .


6
Nun, **/*.cppscheint in (einigermaßen moderner) Bash zu funktionieren. Möglicherweise müssen Sie shopt -s globstarvorher.
— Sbarzowski

1
Wenn Sie CMake verwenden, zeigt Ihnen dieser Beitrag , wie Sie mit CMake GLOB_RECURSEalle .cppDateien finden und an diese übergeben können clang-format.
— Phoenix

5
Die Kombination von findund xargssollte verwenden find ... -print0und xargs -0 ...sicherstellen, dass alle Arten von Dateinamen korrekt behandelt werden.
— Alexander

4
Dieser Befehl schlägt fehl, wenn in pwd CPP- oder H-Dateien vorhanden sind. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -iwird das Problem beheben.
— Nyanpasu64

29

Erstellen Sie zuerst eine .clang-formatDatei, falls diese nicht vorhanden ist:

clang-format -style=WebKit -dump-config > .clang-format

Wählen Sie den gewünschten vordefinierten Stil oder bearbeiten Sie die resultierende .clang-formatDatei.

Der Konfigurator im Clang-Format ist hilfreich.

Dann renne:

find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;

Andere Dateiendungen als cpp, hpp, ccund cxxkönnen im regulären Ausdruck verwendet werden, stellen Sie sicher , sie mit zu trennen \|.


Gibt -style=filees eine Möglichkeit, einen benutzerdefinierten Dateipfad anzugeben? Ich habe es versucht -style=~/.clang-formatund es funktioniert nicht.
— Aaron Franke

Nicht das ich wüsste, abgesehen vom Ändern des aktuellen Verzeichnisses.
— Alexander

Die Ghetto-Lösung, die ich mir ausgedacht habe, besteht darin, eine Funktion zu erstellen, die zuerst cp ~/.clang-format .den Befehl find in Ihrer Antwort ausführt.
— Aaron Franke

12

Ich habe kürzlich ein Bash-Skript gefunden, das genau das tut, was Sie brauchen:

https://github.com/eklitzke/clang-format-all

Dies ist ein Bash-Skript, das clang-format -iauf Ihrem Code ausgeführt wird.

Eigenschaften:

  • Findet den richtigen Pfad zu clang-formatUbuntu / Debian, das die LLVM-Version im clang-formatDateinamen codiert
  • Behebt Dateien rekursiv
  • Erkennt die am häufigsten von C / C ++ - Projekten verwendeten Dateierweiterungen

Unter Windows habe ich es erfolgreich in Git Bash und WSL verwendet.


3

Für Windows-Benutzer: Wenn Sie Powershell 3.0 unterstützen, können Sie Folgendes tun:

Get-ChildItem -Path . -Directory -Recurse |
    foreach {
        cd $_.FullName
        &clang-format -i -style=WebKit *.cpp
    }

Hinweis 1: Verwenden Sie pushd .und, popdwenn Sie vor und nach dem Skript dasselbe aktuelle Verzeichnis haben möchten

Hinweis 2: Das Skript wird im aktuellen Arbeitsverzeichnis ausgeführt

Hinweis 3: Dies kann wahrscheinlich in einer einzigen Zeile geschrieben werden, wenn Ihnen das wirklich wichtig war


0

Ich verwende den folgenden Befehl, um alle Objective-C-Dateien unter dem aktuellen Ordner rekursiv zu formatieren :

$ find . -name "*.m" -o -name "*.h" | sed 's| |\\ |g' | xargs clang-format -i

Ich habe den folgenden Alias ​​in meinem definiert .bash_profile, um die Sache zu vereinfachen:

# Format objC files (*.h and *.m) under the current folder, recursively
alias clang-format-all="find . -name \"*.m\" -o -name \"*.h\" | sed 's| |\\ |g' | xargs clang-format -i"

0

Hier ist eine Lösung, die rekursiv sucht und alle Dateien in einem Befehl als Dateiliste in das Clang-Format weiterleitet. Es schließt auch das "build" -Verzeichnis aus (ich verwende CMake), aber Sie können einfach den "grep" -Schritt weglassen, um das zu entfernen.

shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i

0

In der modernen Bash können Sie den Dateibaum rekursiv crawlen

for file_name in ./src/**/*.{cpp,h,hpp}; do
    if [ -f "$file_name" ]; then
        printf '%s\n' "$file_name"
        clang-format -i $file_name
    fi
done

Hier wird angenommen, dass sich die Quelle in befindet ./srcund .clang-formatdie Formatierungsinformationen enthält.


Ich glaube nicht, dass Globstar in Bash standardmäßig aktiviert ist, also müssten Sie es einstellen.
— Eric Backus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.