¿Cómo llamar a clang-format sobre una carpeta de proyecto cpp?

87

¿Hay alguna manera de llamar a algo como clang-format --style=Webkitpara una carpeta de proyecto cpp completa, en lugar de ejecutarlo por separado para cada archivo?

Estoy usando clang-format.pyy vimpara hacer esto, pero supongo que hay una manera de aplicar esto una vez.

usuario3639557
fuente

Respuestas:

46

Qué pasa:

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

en la carpeta del proyecto. La opción -i lo coloca en su lugar (de forma predeterminada, la salida formateada se escribe en stdout).

sbarzowski
fuente
1
o si está utilizando un archivo de configuración y desea formatear varios tipos de archivos: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos
41
Desafortunadamente, eso no se repetirá en subdirectorios.
Antimony
4
Sí, el shell expandirá * .cpp. clang solo necesita una lista de archivos. Las opciones más avanzadas (como el globbing recursivo) dependen de las características de su shell. Consulte unix.stackexchange.com/questions/49913/recursive-glob sobre cómo utilizar la **construcción.
sbarzowski
¿Y con clang-tidy?
Aaron Franke
@AaronFranke Usar *.cpppara generar una lista de archivos debería funcionar. El clang-tidycomando permite pasar varios archivos. `USO: clang-tidy [opciones] <source0> [... <sourceN>]` Sin embargo, en la práctica puede que no sea la mejor manera. Clang-tidy realiza un análisis mucho más profundo, por lo que requiere las banderas del compilador para cada archivo, etc. Cuando usé clang-tidy, usualmente tenía una "base de datos de compilación": un archivo JSON con los comandos para cada archivo y algún script que fue encima de eso. Fue hace un par de años, tal vez ahora haya una mejor manera.
sbarzowski
85

Desafortunadamente, no hay forma de aplicar el formato clang de forma recursiva. *.cppsolo coincidirá con los archivos del directorio actual, no con los subdirectorios. Incluso **/*no funciona.

Afortunadamente, hay una solución: tome todos los nombres de archivo con el findcomando y canalícelos. Por ejemplo, si desea formatear todos los archivos .hy .cppen el directorio de forma foo/bar/recursiva, puede hacerlo

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

Vea aquí para una discusión adicional.

Antimonio
fuente
6
Bueno, **/*.cppparece funcionar en bash (razonablemente moderno). Es posible que lo necesite shopt -s globstarantes.
sbarzowski
1
Si está usando CMake, esta publicación le muestra cómo puede usar CMake GLOB_RECURSEpara encontrar todos los .cpparchivos y pasarlos a clang-format.
phoenix
4
La combinación de findy xargsdebe usar find ... -print0y xargs -0 ...para garantizar que todos los tipos de nombres de archivo se manejen correctamente.
Alexander
3
Este comando falla si existe algún archivo .cpp o .h en pwd. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -isolucionará el problema.
nyanpasu64
26

Primero cree un .clang-formatarchivo si no existe:

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

Elija el estilo predefinido que desee o edite el .clang-formatarchivo resultante .

El configurador de formato clang es útil.

Entonces corre:

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

Otras extensiones de archivo que cpp, hpp, ccy cxxpueden ser utilizados en la expresión regular, sólo asegúrese de separarlos con \|.

Alejandro
fuente
Por -style=filehay una manera para especificar una ruta de archivo personalizado? Lo intenté -style=~/.clang-formaty no funciona.
Aaron Franke
No que yo sepa, aparte de cambiar el directorio actual.
Alexander
La solución del ghetto que se me ocurrió es crear una función que primero se ejecute y cp ~/.clang-format .luego el comando de búsqueda en su respuesta.
Aaron Franke
12

Recientemente encontré un script bash que hace exactamente lo que necesitas:

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

Este es un script bash que se ejecutará clang-format -ien su código.

caracteristicas:

  • Encuentra la ruta correcta clang-formaten Ubuntu / Debian, que codifica la versión LLVM en el clang-formatnombre del archivo
  • Corrige archivos de forma recursiva
  • Detecta las extensiones de archivo más comunes utilizadas por proyectos C / C ++

En Windows, lo usé con éxito en Git Bash y WSL.

Julius Bullinger
fuente
3

Para los usuarios de Windows: si tiene soporte para Powershell 3.0, puede hacer:

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

Note1: Use pushd .y popdsi desea tener el mismo directorio actual antes y después del script

Nota 2: el script opera en el directorio de trabajo actual

Nota 3: esto probablemente se pueda escribir en una sola línea si eso fue realmente importante para usted

Tim Meyer
fuente
0

Estoy usando el siguiente comando para formatear todos los archivos de objetivo-C en la carpeta actual de forma recursiva :

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

He definido el siguiente alias en mi .bash_profilepara facilitar las cosas:

# 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"
Marcelosalloum
fuente
0

Aquí hay una solución que busca de forma recursiva y canaliza todos los archivos al formato clang como una lista de archivos en un solo comando. También excluye el directorio "build" (yo uso CMake), pero puede omitir el paso "grep" para eliminarlo.

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