From 1482cb1d119dff1fb8ee64456d2c8ec28b299c56 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Sat, 21 Dec 2019 17:03:00 +0100 Subject: [PATCH] cmake: Add clang-format support This does not rely on the "integrated" clang-format, but instead uses a custom target to achieve the goal. Supports file filtering (to ensure that clang-format only affects supported files), automatic dependency by the project (always run before build), multiple targets and a global target. Options are: - TARGETS ...: Targets to add clang-format support to. - DEPENDENCY: Add a dependency to the given targets so that clang-format runs before building. - REGEX: Filter out files of the given targets, defaults to '\.(h|hpp|c|cpp)'. - GLOBAL: Add a global CLANG_FORMAT target. --- CMakeLists.txt | 31 +++++++++++++----- cmake/ClangToolkit.cmake | 71 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 cmake/ClangToolkit.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index fe3a299..8be3f63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -16,8 +16,7 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA # CMake Setup -CMake_Minimum_Required(VERSION 3.8.0) -Include("cmake/util.cmake") +cmake_minimum_required(VERSION 3.8.0) # Automatic Versioning set(VERSION_MAJOR 0) @@ -28,7 +27,7 @@ set(PROJECT_COMMIT "N/A") if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git") set(GIT_RESULT "") set(GIT_OUTPUT "") - EXECUTE_PROCESS( + execute_process( COMMAND git rev-list --count --topo-order ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}..HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT @@ -38,7 +37,7 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git") if(GIT_RESULT EQUAL 0) set(VERSION_TWEAK ${GIT_OUTPUT}) endif() - EXECUTE_PROCESS( + execute_process( COMMAND git rev-parse HEAD WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} RESULT_VARIABLE GIT_RESULT @@ -51,7 +50,7 @@ if(EXISTS "${CMAKE_CURRENT_LIST_DIR}/.git") endif() # Define Project -PROJECT( +project( obs-stream-effects VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_TWEAK} ) @@ -64,6 +63,13 @@ set(PROJECT_COPYRIGHT_YEARS "2018 - 2019") # Setup / Bootstrap ################################################################################ +# Search Path +set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/;${CMAKE_MODULE_PATH}") + +# CMake Modules +include("util") +include("ClangToolkit") + # Detect Build Type if("${CMAKE_SOURCE_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}") set(PropertyPrefix "") @@ -80,9 +86,6 @@ else() set(ARCH "x64") endif() -# Search Path -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/modules/") - # All Warnings, Extra Warnings, Pedantic if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") # using Clang @@ -199,7 +202,7 @@ endif() # CMake Modules if(${PropertyPrefix}OBS_DOWNLOAD) - include("cmake/DownloadProject.cmake") + include("DownloadProject") endif() # Load OBS Studio @@ -264,6 +267,10 @@ set(PROJECT_LIBRARIES set(PROJECT_TEMPLATES "${PROJECT_SOURCE_DIR}/cmake/version.hpp.in" "${PROJECT_SOURCE_DIR}/cmake/module.cpp.in" + "${PROJECT_SOURCE_DIR}/cmake/ClangToolkit.cmake" + "${PROJECT_SOURCE_DIR}/cmake/DownloadProject.cmake" + "${PROJECT_SOURCE_DIR}/cmake/DownloadProject.CmakeLists.cmake.in" + "${PROJECT_SOURCE_DIR}/cmake/util.cmake" ) if(WIN32) list(APPEND PROJECT_TEMPLATES @@ -412,6 +419,12 @@ add_library(${PROJECT_NAME} MODULE ${PROJECT_PRIVATE} ) +# Clang-Format +clang_format( + TARGETS ${PROJECT_NAME} + DEPENDENCY +) + # Include Directories target_include_directories(${PROJECT_NAME} PUBLIC diff --git a/cmake/ClangToolkit.cmake b/cmake/ClangToolkit.cmake new file mode 100644 index 0000000..9ee4c74 --- /dev/null +++ b/cmake/ClangToolkit.cmake @@ -0,0 +1,71 @@ +set(CLANG_FORMAT_BIN "clang-format" CACHE PATH "Path (or name) of the clang-format binary") + +function(clang_format) + cmake_parse_arguments( + PARSE_ARGV 0 + _CLANG_FORMAT + "DEPENDENCY;GLOBAL" + "REGEX" + "TARGETS" + ) + + if(NOT EXISTS ${CLANG_FORMAT_BIN}) + find_program(clang_format_bin_tmp ${CLANG_FORMAT_BIN}) + if(clang_format_bin_tmp) + set(CLANG_FORMAT_BIN "${clang_format_bin_tmp}" CACHE PATH "Path (or name) of the clang-format binary") + unset(clang_format_bin_tmp) + else() + message(FATAL_ERROR "Clang: Could not find clang-format at path '${CLANG_FORMAT_BIN}'.") + endif() + endif() + + if(NOT _CLANG_FORMAT_FILTER) + set(_CLANG_FORMAT_FILTER "\.(h|hpp|c|cpp)$") + endif() + + foreach(_target ${_CLANG_FORMAT_TARGETS}) +# get_target_property(target_name ${_target} NAME) + + get_target_property(target_sources_rel ${_target} SOURCES) + set(target_sources "") + foreach(source_relative ${target_sources_rel}) + get_filename_component(source_absolute ${source_relative} ABSOLUTE) + list(APPEND target_sources ${source_absolute}) + endforeach() + list(FILTER target_sources INCLUDE REGEX "${_CLANG_FORMAT_FILTER}") + unset(target_sources_rel) + + get_target_property(target_source_dir_rel ${_target} SOURCE_DIR) + get_filename_component(target_source_dir ${target_source_dir_rel} ABSOLUTE) + unset(target_source_dir_rel) + + add_custom_target(${_target}_CLANG-FORMAT + COMMAND + ${CLANG_FORMAT_BIN} + -style=file + -i + ${target_sources} + COMMENT + "clang-format: Formatting ${_target}..." + WORKING_DIRECTORY + ${target_source_dir_rel} + ) + + if(_CLANG_FORMAT_DEPENDENCY) + add_dependencies(${_target} ${_target}_CLANG-FORMAT) + endif() + + if(_CLANG_FORMAT_GLOBAL) + if(TARGET CLANG-FORMAT) + add_dependencies(CLANG-FORMAT ${_target}_CLANG-FORMAT) + else() + add_custom_target(CLANG-FORMAT + DEPENDS + ${_target}_CLANG-FORMAT + COMMENT + "clang-format: Formatting..." + ) + endif() + endif() + endforeach() +endfunction()