From 66f48992ddd1401f8e9f4f876a737c2c62c209f8 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Tue, 12 Nov 2019 13:32:01 -0800 Subject: [PATCH] Add a 'clang-format' build target If clang-format can be found at config time, then a build target will be established that allows you to `make clang-format`. Running this does not cause any actual compiles, but will reformat all the .h and .cpp files in the code base, according to the .clang-format configuration. Cache variables CLANG_FORMAT_INCLUDES and CLANG_FORMAT_EXCLUDES provides patterns for any files to include (default: `"*.h;*.cpp"`) or exclude, respectively. Files that you are sure should never be reformatted can be added explicitly to the CLANG_FORMAT_EXCLUDES default in clang-format.cmake. Note that there will be some source modules which, in whole or in part, you know you don't want to be reformatted (sometimes a nonstandard formatting is much clearer than anything clang-format can be coaxed into doing, such is often the case for tables). In that case you can turn it off with the comment // clang-format off ... code that is excluded from reformatting ... // clang-format on The CMake implementation of finding clang-format and adding this target was largely borrowed from that in OpenImageIO's build system (also the same BSD-3-Clause license). This patch only establishes the build-time target so that you can run it by hand, but does not (in this commit) reformat any of the source. There are a LOT of diffs! We may want to fine-tune the .clang-format for a while before we take the plunge of actually checking in the reformatted code and then enforcing the formatting thereafter. (Pro tip: run `make clang-format` only when you have no uncommitted edits. If you then don't like the formatting it imposes, you can back out of it all with `git checkout HEAD --force`.) --- CMakeLists.txt | 8 +++++++ cmake/clang-format.cmake | 51 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 cmake/clang-format.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 37fbf17442..c289e53bf2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,6 +24,10 @@ endif() project(OpenEXRMetaProject) +# Search for custom modules in our cmake directory +list (APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake") + + # An "official" way to make this a super-project # basically overrides the find_package to not find anything # for stuff we're including locally @@ -84,3 +88,7 @@ option(OPENEXR_VIEWERS_ENABLE "Enables configuration of the viewers module" ON) if(OPENEXR_VIEWERS_ENABLE) add_subdirectory(OpenEXR_Viewers) endif() + +# Including this module will add a `clang-format` target to the build if +# the clang-format executable can be found. +include(clang-format) diff --git a/cmake/clang-format.cmake b/cmake/clang-format.cmake new file mode 100644 index 0000000000..717cec970a --- /dev/null +++ b/cmake/clang-format.cmake @@ -0,0 +1,51 @@ +# SPDX-License-Identifier: BSD-3-Clause +# Copyright Contributors to the OpenEXR Project. +# +# This module was partially adapted from OpenImageIO, also under the +# same BSD-3-Clause license. + +########################################################################### +# clang-format options +# +# clang-format is a source code reformatter that is part of the LLVM tools. +# It can be used to check adherence to project code formatting rules and +# correct any deviations. If clang-format is found on the system, a +# "clang-format" build target will trigger a reformatting. +# +set (CLANG_FORMAT_ROOT "" CACHE PATH "clang-format executable's directory (will search if not specified") +set (CLANG_FORMAT_INCLUDES "*.h" "*.cpp" + CACHE STRING "Glob patterns to include for clang-format") +set (CLANG_FORMAT_EXCLUDES "" + CACHE STRING "Glob patterns to exclude for clang-format") + +# Look for clang-format. If not in the ordinary execution path, you can +# hint at it with either CLANG_FORMAT_ROOT or LLVM_ROOT (as a CMake variable +# or as an environment variable). +find_program (CLANG_FORMAT_EXE + NAMES clang-format bin/clang-format + HINTS ${CLANG_FORMAT_ROOT} + ENV CLANG_FORMAT_ROOT + LLVM_ROOT + ENV LLVM_ROOT + DOC "Path to clang-format executable") + +# If clang-format was foudn, set up a custom `clang-format` target that will +# reformat all source code with filenames patterns matching +# CLANG_FORMAT_INCLUDES and excluding CLANG_FORMAT_EXCLUDES. +if (CLANG_FORMAT_EXE) + message (STATUS "clang-format found: ${CLANG_FORMAT_EXE}") + # Start with the list of files to include when formatting... + file (GLOB_RECURSE FILES_TO_FORMAT ${CLANG_FORMAT_INCLUDES}) + # ... then process any list of excludes we are given + foreach (_pat ${CLANG_FORMAT_EXCLUDES}) + file (GLOB_RECURSE _excl ${_pat}) + list (REMOVE_ITEM FILES_TO_FORMAT ${_excl}) + endforeach () + #message (STATUS "clang-format file list: ${FILES_TO_FORMAT}") + file (COPY ${CMAKE_CURRENT_SOURCE_DIR}/.clang-format + DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + add_custom_target (clang-format + COMMAND "${CLANG_FORMAT_EXE}" -i -style=file ${FILES_TO_FORMAT} ) +else () + message (STATUS "clang-format not found.") +endif ()