Come chiamare il formato clang su una cartella del progetto cpp?


89

C'è un modo per chiamare qualcosa come clang-format --style=Webkitper un'intera cartella del progetto cpp, piuttosto che eseguirlo separatamente per ogni file?

Sto usando clang-format.pye vimper farlo, ma presumo che ci sia un modo per applicarlo una volta.

Risposte:


49

Che dire:

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

nella cartella del progetto. L'opzione -i lo rende inplace (per impostazione predefinita l'output formattato viene scritto su stdout).


1
o se stai utilizzando un file di configurazione e desideri formattare più tipi di file: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos

46
Sfortunatamente, ciò non ricadrà nelle sottodirectory.
Antimonio

4
Sì, * .cpp verrà espanso dalla shell. clang ha solo bisogno di un elenco di file. Le opzioni più avanzate (come il globbing ricorsivo) dipendono dalle caratteristiche della tua shell. Vedi unix.stackexchange.com/questions/49913/recursive-glob su come utilizzare **costrutto.
sbarzowski

E con clang-tidy?
Aaron Franke

@AaronFranke Usare *.cppper generare un elenco di file dovrebbe funzionare. Il clang-tidycomando consente di passare più file. `USAGE: clang-tidy [opzioni] <source0> [... <sourceN>]` In pratica, però, potrebbe non essere il modo migliore. Clang-tidy esegue un'analisi molto più approfondita, quindi richiede i flag del compilatore per ogni file ecc. Quando usavo clang-tidy, di solito avevo un "database di compilazione" - un file JSON con i comandi per ogni file e alcuni script che andavano sopra. Sono passati un paio d'anni, forse adesso c'è un modo migliore.
sbarzowski

90

Sfortunatamente, non c'è modo di applicare il formato clang in modo ricorsivo. *.cppcorrisponderà solo ai file nella directory corrente, non alle sottodirectory. Anche **/*non funziona.

Per fortuna, c'è una soluzione: prendere tutti i nomi di file con il findcomando e la pipa in Per esempio, se si desidera formattare tutti. .hE .cppfile nella directory foo/bar/ricorsivamente, si può fare

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

Vedi qui per ulteriori discussioni.


7
Bene, **/*.cppsembra funzionare in (ragionevolmente moderno) bash. Potrebbe essere necessario shopt -s globstarprima.
sbarzowski

1
Se stai usando CMake, questo post ti mostra come puoi usare CMake GLOB_RECURSEper trovare tutti i .cppfile e passarli a clang-format.
phoenix

5
La combinazione di finde xargsdovrebbe utilizzare find ... -print0e xargs -0 ...per garantire che tutti i tipi di nomi di file siano gestiti correttamente.
Alexander

5
Questo comando non riesce se in pwd sono presenti file .cpp o .h. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -irisolverà il problema.
nyanpasu64

29

Per prima cosa crea un .clang-formatfile se non esiste:

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

Scegli lo stile predefinito che preferisci o modifica il .clang-formatfile risultante .

configuratore in formato clang è utile.

Quindi esegui:

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

Altre estensioni dei file che cpp, hpp, cce cxxpuò essere utilizzato nell'espressione regolare, assicuratevi solo di separarli con \|.


Per -style=filec'è un modo per specificare un percorso di file personalizzato? Ho provato -style=~/.clang-formate non funziona.
Aaron Franke

Non che io sappia, a parte cambiare la directory corrente.
Alexander

La soluzione ghetto che ho escogitato è creare una funzione che esegua prima cp ~/.clang-format .il comando find nella tua risposta.
Aaron Franke

12

Di recente ho trovato uno script bash che fa esattamente ciò di cui hai bisogno:

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

Questo è uno script bash che verrà eseguito clang-format -isul tuo codice.

Caratteristiche:

  • Trova il percorso corretto clang-formatsu Ubuntu / Debian, che codifica la versione LLVM nel clang-formatnome del file
  • Corregge i file in modo ricorsivo
  • Rileva le estensioni di file più comuni utilizzate dai progetti C / C ++

Su Windows, l'ho usato con successo in Git Bash e WSL.


3

Per gli utenti Windows: se hai il supporto di Powershell 3.0, puoi fare:

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

Nota 1: utilizzare pushd .e popdse si desidera avere la stessa directory corrente prima e dopo lo script

Nota 2: lo script opera nella directory di lavoro corrente

Nota 3: questo può probabilmente essere scritto in una singola riga se questo è stato davvero importante per te


0

Sto usando il seguente comando per formattare in modo ricorsivo tutti i file Object-C nella cartella corrente :

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

Ho definito il seguente alias nel mio .bash_profileper semplificare le cose:

# 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

Ecco una soluzione che cerca in modo ricorsivo e convoglia tutti i file in formato clang come elenco di file in un unico comando. Esclude anche la directory "build" (io uso CMake), ma puoi semplicemente omettere il passaggio "grep" per rimuoverlo.

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

0

Nella bash moderna è possibile eseguire la scansione ricorsiva dell'albero dei file

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

Qui si presume che la fonte si trovi ./srce che .clang-formatcontenga le informazioni di formattazione.


Non penso che globstar sia attivo di default in bash, quindi dovresti impostarlo.
Eric Backus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.