Package: cmake-pre-commit-hooks
pre-commit hooksThis is apre-commithooks repo that integrates C/C++ linters/formatters to work with
CMake-based projects.clang-format,clang-tidy,cppcheck,cpplint,lizardandiwyuIt is largely based on the work foundhere. The main difference with POCC's
pre-commit hooks is that the ones from this repository will do a CMake configuration step prior to running any
pre-commit hooks. This is done in order to have CMake generate the compilation database file that can then be used by
the various hooks (using the-DCMAKE_EXPORT_COMPILE_COMMANDS=ONCMake option).This repository is only has Python-based pre-commit hooks.Current known issuesCurrently, the hooks that depend on having a compilation database generated by CMake (e.g.clang-tidy,cppcheck)
are not working on Windows if you are not using theNinjaorMakefilegenerators.Currently, arguments set in a TOML configuration file (pyproject.toml,cmake_pc_hooks.tomlor else) are applied
to all hooks. Future improvements may allow to customize arguments on a per-hook basis.Example usageAssuming that you have the following directory structure for your projectsroot
├── .pre-commit-config.yaml
├── CMakeLists.txt
└── src
    └── err.cppwith the following file contents:.pre-commit-config.yamlrepos:-repo:https://github.com/Takishima/cmake-pre-commit-hooksrev:v1.8.0hooks:-id:clang-format-id:clang-tidyargs:[--checks=readability-magic-numbers,--warnings-as-errors=*]-id:cppcheck-id:include-what-you-useCMakeLists.txtcmake_minimum_required(VERSION3.15)project(LANGUAGECXX)add_library(mylibSTATICsrc/err.cpp)src/err.cpp#include<string>intmain(){inti;return10;}Running pre-commit on the above project will lead to an output similar to this one:$ pre-commit run --all-files
clang-format.............................................................Failed
- hook id: clang-format
- exit code: 1

src/err.cpp
====================
<  int main() { int i; return 10; }
---
>  int main() {
>    int i;
>    return 10;
>  }

clang-tidy...............................................................Failed
- hook id: clang-tidy
- exit code: 1

/tmp/temp/src/err.cpp:2:28: error: 10 is a magic number; consider replacing it with a named constant [readability-magic-numbers,-warnings-as-errors]
int main() { int i; return 10; }
                           ^

cppcheck.................................................................Failed
- hook id: cppcheck
- exit code: 1

/tmp/temp/src/err.cpp:2:18: style: Unused variable: i [unusedVariable]
int main() { int i; return 10; }
                 ^
include-what-you-use.....................................................Failed
- hook id: include-what-you-use
- exit code: 1

Problem with /usr/local/bin/iwyu_tool.py: Include-What-You-Use violations found

/tmp/temp/src/err.cpp should add these lines:
/tmp/temp/src/err.cpp should remove these lines:
- #include <string>  // lines 1-1
The full include-list for /tmp/temp/src/err.cpp:
---Note that your mileage may vary depending on the version of the tools. The example above was generated usingclang-format12.0.0,clang-tidy12.0.0,cppcheck2.4.1 andinclude-what-you-use0.16.Using the HooksPython 3.8+ is required to use these hooks as all 3 invoking scripts are written in it. As this is also the minimum
version of pre-commit, this should not be an issue.Running multiple hooks in parallel is currently supported by using thefastenerPython package. If the hooks are run
in parallel, only one of the hooks will run the CMake configure step while the others will simply wait until the call to
CMake ends to continue. In the case where the hooks are run serially, all the hooks will be running the CMake configure
step. However, if nothing changed in your CMake configuration, this should not cost too much time.InstallationFor installing the various utilities, refer to your package manager documentation. Some guidance can also be foundhere.Hook InfoHook InfoTypeLanguagesclang-formatFormatterC, C++, ObjCclang-tidyStatic code analyzerC, C++, ObjCcppcheckStatic code analyzerC, C++cpplintStatic code analyzerC, C++include-what-you-useStatic code analyzerC, C++lizardCode complexity analyzerC/C++, ObjC, ...Hook optionsSince v1.1.0 all hooks that depend on a compilation database (e.g.clang-tidy,cppcheck,include-what-you-use)
will attempt to generate a CMake build directory before running the actual command.These hooks accept all the most common CMake options:CMake optionsDescription-S <path-to-source>Explicitly specify a source directory.-B <path-to-build>Explicitly specify a build directory.-D <var>[:<type>]=<value>Create or update a cmake cache entry.-U <globbing_expr>Remove matching entries from CMake cache.-G <generator-name>Specify a build system generator.-T <toolset-name>Specify toolset name if supported by generator.-A <platform-name>Specify platform name if supported by generator.--preset <preset>Specify a configure preset.-WdevEnable developer warnings.-Wno-devSuppress developer warnings.-Werror=devMake developer warnings errors.-Wno-error=devMake developer warnings not errors.One important thing to note (particularly for those that intend to use this on CIs), you may specify the build directory
argument (-B) multiple times. The hooks will then simply cycle through all of the values provided and choose the first
directory that contains a configured CMake project (by looking at the presence of theCMakeCache.txtfile). This may
be useful if you already have a build directory available somewhere that you would like to reuse. In the case where
none of the provided options is viable, the first one will automatically be selected as the build directory.In addition to the above CMake options, the hooks also accept the following:Other hook optionsDescriptionNote--all-at-oncePass all filenames to the command at onceSince v1.4.0--cleanPerform a clean CMake buildSince v1.4.0--cmakeSpecify path to CMake executableSince v1.4.0--detect-configured-filesEnable cmake tracing and detection of configured filesSince v1.9.0--dump-tomlDump the current configuration as TOML on stdoutSince v1.9.0--no-automatic-discoveryDisable automatic build directory discoverySince v1.9.0--no-cmake-configureDo not call CMake configureSince v1.9.2--read-json-dbAppend file list from compile databaseSince v1.7.0--linuxLinux-only CMake optionsSince v1.3.0--macMacOS-only CMake optionsSince v1.3.0--winWindows-only CMake optionsSince v1.3.0NB: by specifying--all-at-oncethe linter/formatter command will only be called once for all the files instead of
calling the command once per file.NB: Since v1.6.0, the--debugcommand line argument has been removed. Use theLOGLEVELenvironment variable instead
to control the level of verbosity of each of the commands. To show all debug messages, setLOGLEVEL=DEBUGin your
environment variables when running the hooks.NB: by specifying--read-json-dbthe hook will read the list of files from thecompile_commands.jsongenerated by
CMake and will append those files to the list of files to process regardless of the list of files otherwise passed on
the command line.NB: by specifying--no-cmake-configurethe hook will not attempt to create a compilation database by using
CMake. However, if one is present, then it will be used by the relevant hooks.Usage example:repos:-repo:https://github.com/Takishima/cmake-pre-commit-hooksrev:v1.8.0hooks:-id:cppcheckargs:[-DBUILD_TESTING=ON,--unix="-DCMAKE_CXX_COMPILER=g++-10",--win="-DCMAKE_CXX_COMPILER=cl.exe"-Bpath/to/build_dir,-Bpath/to/other_build_dir,-Spath/to/src_dir]In the example above, the any hooks requiring a compilation database will first search for a build directorypath/to/build_dirand thenpath/to/other_build_dir. If any of those is deemed valid (ie. is a CMake build directory
that contains some CMake cache files), then it will be used. If none qualify, the hooks will default to usingpath/to/build_diras a build directory, creating it as necessary.Also, builds on Linux and MacOS will set the C++ compiler tog++-10, while builds on Windows will be usingcl.exe. This is done by looking at the value returned byplatform.system().TOML supportSince v1.9.0, the hooks support loading the CLI arguments from TOML files. This can be used to configure all the hooks
for a particular repository using either of:pyproject.tomlcmake_pc_hooks.tomlTOML file specified using--config=/path/to/file.tomlCommand line argumentsNote that each step in the above list is overridden by the steps that happenafterit. For example, CLI arguments
will always override any arguments read from any TOML file.A good place to start if you plan on creating a TOML configuration file is to use the hooks using the CLI arguments as
you would normally and then run the hook manually and with the addition of--dump-toml. This will output a
TOML-formatted configuration on the standard output for all the parameters thatdivergefrom their default values.For example, running the following command (assuming that no valid TOML configuration exists):cmake-pc-clang-format-hooktests/cmake_bad/bad.cpp--dump-toml-B/tmp/build-Ssource-Wdev--no-automatic-discoverywill result in the following output:automatic_discovery=falsesource_dir="source"build_dir=["/tmp/build",]dev_warnings=trueCMake configured file detectionSince v1.9.0, the hooks support the use of CMake with trace mode enabled in order to keep track of files that are
generated using calls to theconfigure_file(...)CMake function. If--detect-configured-filesis specified on the
command line (or in some TOML configuration file), the hooks will attempt to locate those generated files and
automatically add them to the list of processed files for any hook invocation.Hook Option ComparisonHook OptionsFix In PlaceEnable all ChecksSet key/valueclang-format-iclang-tidy--fix-errors[^1]-checks=*-warnings-as-errors=*[^2]cppcheck-enable=allinclude-what-you-use[^1]:-fixwill fail if there are compiler errors.-fix-errorswill-fixand fix compiler errors if it can, like missing semicolons.[^2]: Be careful with-checks=*; some checks can have self-contradictory rules in newer versions of LLVM (9+). For
example, modernize wants to usetrailing return typebut Fuchsiadisallows it.The '--' doubledash optionOptions after--like-std=c++11will be interpreted correctly forclang-tidy. Make sure they sequentially follow
the--argument in the hook's args list.Standalone HooksIf you want to have predictable return codes for your C linters outside of pre-commit, these hooks are available viaPyPI.  Install it withpip install cmake-pre-commit-hooks.  They
are named ascmake-pc-$cmd-hook, soclang-formatbecomescmake-pc-clang-format-hook.