Como chamar o clang-format sobre uma pasta de projeto cpp?


87

Existe uma maneira de chamar algo como clang-format --style=Webkit para uma pasta de projeto cpp inteira, em vez de executá-lo separadamente para cada arquivo?

Estou usando clang-format.pye vimpara fazer isso, mas presumo que haja uma maneira de aplicar isso uma vez.

Respostas:


46

A respeito:

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

na pasta do projeto. A opção -i o torna local (por padrão, a saída formatada é gravada em stdout).


1
ou se você estiver usando um arquivo de configuração e quiser formatar vários tipos de arquivo: clang-format-3.6 -i -style=file *.cpp *.h *.hpp
mBardos

41
Infelizmente, isso não será redirecionado para subdiretórios.
Antimônio

4
Sim, * .cpp será expandido pelo shell. o clang só precisa de uma lista de arquivos. Opções mais avançadas (como globbing recursivo) dependem dos recursos do seu shell. Consulte unix.stackexchange.com/questions/49913/recursive-glob sobre como usar a **construção.
sbarzowski de

Que tal com clang-tidy?
Aaron Franke

@AaronFranke Usar *.cpppara gerar uma lista de arquivos deve funcionar. O clang-tidycomando permite a passagem de vários arquivos. `USO: clang-tidy [options] <source0> [... <sourceN>]` Na prática, pode não ser a melhor maneira. O Clang-tidy realiza uma análise muito mais profunda, por isso requer os sinalizadores do compilador para cada arquivo etc. Quando eu usava o clang-tidy, geralmente tinha um "banco de dados de compilação" - um arquivo JSON com os comandos para cada arquivo e algum script que foi acima dele. Foi há alguns anos, talvez haja uma maneira melhor agora.
sbarzowski 01 de

85

Infelizmente, não há como aplicar o formato clang recursivamente. *.cppcorresponderá apenas aos arquivos do diretório atual, não aos subdiretórios. Mesmo **/*não funciona.

Felizmente, há uma solução: pegar todos os nomes de arquivos com o findcomando e da tubulação-los em Por exemplo, se você deseja formatar todos. .hE .cpparquivos no diretório foo/bar/de forma recursiva, você pode fazer

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

Veja aqui uma discussão adicional.


6
Bem, **/*.cppparece funcionar em bash (razoavelmente moderno). Você pode precisar shopt -s globstarantes.
sbarzowski

1
Se você estiver usando o CMake, este artigo mostra como você pode usar o CMake GLOB_RECURSEpara encontrar todos os .cpparquivos e passá-los para clang-format.
Phoenix,

4
A combinação de finde xargsdeve usar find ... -print0e xargs -0 ...para garantir que todos os tipos de nomes de arquivo sejam tratados corretamente.
Alexander

3
Este comando falhará se qualquer arquivo .cpp ou .h existir em pwd. find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -ivai resolver o problema.
nyanpasu64

26

Primeiro crie um .clang-formatarquivo se ele não existir:

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

Escolha o estilo predefinido de sua preferência ou edite o .clang-formatarquivo resultante .

configurador de formato clang é útil.

Então corra:

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

Outras extensões de arquivo que cpp, hpp, cce cxxpodem ser usados na expressão regular, apenas certifique-se de separá-los com \|.


Para -style=filese existe uma maneira para especificar um caminho de arquivo de costume? Eu tentei -style=~/.clang-formate não deu certo.
Aaron Franke

Não que eu saiba, além de alterar o diretório atual.
Alexander

A solução do gueto que descobri é criar uma função que primeiro execute cp ~/.clang-format .o comando find em sua resposta.
Aaron Franke

12

Recentemente, encontrei um script bash que faz exatamente o que você precisa:

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

Este é um script bash que será executado clang-format -iem seu código.

Características:

  • Encontra o caminho certo para clang-formatno Ubuntu / Debian, que codifica a versão LLVM no clang-formatnome do arquivo
  • Corrige arquivos recursivamente
  • Detecta as extensões de arquivo mais comuns usadas por projetos C / C ++

No Windows, usei-o com sucesso no Git Bash e WSL.


3

Para usuários do Windows: Se você tiver suporte para Powershell 3.0, você pode fazer:

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

Nota 1: Use pushd .e popdse quiser ter o mesmo diretório atual antes e depois do script

Nota 2: o script opera no diretório de trabalho atual

Nota 3: Isso provavelmente pode ser escrito em uma única linha se isso for realmente importante para você


0

Estou usando o seguinte comando para formatar todos os arquivos Objectivo-C na pasta atual recursivamente :

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

Eu defini o seguinte alias no meu .bash_profilepara facilitar as coisas:

# 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

Aqui está uma solução que pesquisa recursivamente e canaliza todos os arquivos para o formato clang como uma lista de arquivos em um comando. Também exclui o diretório "build" (eu uso o CMake), mas você pode simplesmente omitir o passo "grep" para removê-lo.

shopt -s globstar extglob failglob && ls **/*.@(h|hpp|hxx|c|cpp|cxx) | grep -v build | tr '\n' ' ' | xargs clang-format -i
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.