How to call clang-format over a cpp project folder?
Solution 1
What about:
clang-format -i -style=WebKit *.cpp *.h
in the project folder. The -i option makes it inplace (by default formatted output is written to stdout).
Solution 2
Unfortunately, there is no way to apply clang-format recursively. *.cpp
will only match files in the current directory, not subdirectories. Even **/*
doesn't work.
Luckily, there is a solution: grab all the file names with the find
command and pipe them in. For example, if you want to format all .h
and .cpp
files in the directory foo/bar/
recursively, you can do
find foo/bar/ -iname *.h -o -iname *.cpp | xargs clang-format -i
See here for additional discussion.
Solution 3
First create a .clang-format
file if it doesn't exist:
clang-format -style=WebKit -dump-config > .clang-format
Choose whichever predefined style you like, or edit the resulting .clang-format
file.
clang-format configurator is helpful.
Then run:
find . -regex '.*\.\(cpp\|hpp\|cc\|cxx\)' -exec clang-format -style=file -i {} \;
Other file extensions than cpp
, hpp
, cc
and cxx
can be used in the regular expression, just make sure to separate them with \|
.
Solution 4
I recently found a bash-script which does exactly what you need:
https://github.com/eklitzke/clang-format-all
This is a bash script that will run
clang-format -i
on your code.Features:
- Finds the right path to
clang-format
on Ubuntu/Debian, which encode the LLVM version in theclang-format
filename- Fixes files recursively
- Detects the most common file extensions used by C/C++ projects
On Windows, I used it successfully in Git Bash and WSL.
Solution 5
When you use Windows (CMD) but don't want to use the PowerShell cannon to shoot this fly, try this:
for /r %t in (*.cpp *.h) do clang-format -i -style=WebKit "%t"
Don't forget to duplicate the two %
s if in a cmd script.
Related videos on Youtube
user3639557
Updated on July 08, 2022Comments
-
user3639557 almost 2 years
Is there a way to call something like
clang-format --style=Webkit
for an entire cpp project folder, rather than running it separately for each file?I am using
clang-format.py
andvim
to do this, but I assume there is a way to apply this once. -
mBardos over 8 yearsor if you are using a config file and want to format multiple file types:
clang-format-3.6 -i -style=file *.cpp *.h *.hpp
-
Antimony about 8 yearsUnfortunately, that won't recurse into subdirectories.
-
sbarzowski about 8 yearsYes, *.cpp will be expanded by the shell. clang just needs a list of files. More advanced options (like recursive globbing) depend on the features of your shell. See unix.stackexchange.com/questions/49913/recursive-glob on how to use
**
construct. -
sbarzowski about 8 yearsWell,
**/*.cpp
seems to work in (reasonably modern) bash. You may need toshopt -s globstar
before. -
phoenix about 7 yearsIf you are using CMake, this post shows you how you can use CMake's
GLOB_RECURSE
to find all.cpp
files and pass them toclang-format
. -
Alexander over 6 yearsThe combination of
find
andxargs
should usefind ... -print0
andxargs -0 ...
to ensure that all types of filenames are handled correctly. -
nyanpasu64 almost 6 yearsThis command fails if any .cpp or .h files exist in pwd.
find foo/bar/ -iname '*.h' -o -iname '*.cpp' | xargs clang-format -i
will fix the issue. -
Aaron Franke over 4 yearsFor
-style=file
is there a way to specify a custom file path? I tried-style=~/.clang-format
and it doesn't work. -
Alexander over 4 yearsNot that I know of, apart from changing the current directory.
-
Aaron Franke over 4 yearsThe ghetto solution I came up with is to make a function which first runs
cp ~/.clang-format .
then the find command in your answer. -
Aaron Franke almost 4 yearsWhat about with
clang-tidy
? -
sbarzowski almost 4 years@AaronFranke Using
*.cpp
to generate a list of files should work. Theclang-tidy
command allows passing multiple files. ` USAGE: clang-tidy [options] <source0> [... <sourceN>] ` In practice that may not be the best way, though. Clang-tidy performs a much deeper analysis, so it requires the compiler flags for each file etc. When I used clang-tidy, I usually had a "compilation database" – a JSON file with the commands for each file and some script which went over it. It was a couple years back, maybe there is a better way now. -
Aaron Franke almost 4 yearsWhat if my C++ files are in subfolders?
-
sbarzowski almost 4 yearsYou can use
**
. See: unix.stackexchange.com/questions/49913/recursive-glob. -
vlad_tepesch almost 4 yearsdoes not work for me - only get
invalid argument
errors. Even with double-
onstyle
-
sbarzowski almost 4 years@vlad_tepesch What exactly doesn't work? What command are you running exactly and what is the full error message (you might want to use pastebin for that)?
-
Eric Backus over 3 yearsI don't think globstar is on by default in bash, so you'd need to set it.
-
Anton Breusov about 3 yearsInteresting but it doesn't work for me on macOS. But this version (with -E flag and without escaping special symbols does):
find -E . -regex '.*\.(cpp|hpp|cc|cxx)' -exec clang-format -style=file -i {} \;
-
Alexander about 3 yearsThanks for the info, Anton Breusov.
-E
does not work here on Arch Linux, but-regextype egrep
does. Does-regextype egrep
work on macOS too?