diff --git a/.cmake-format b/.cmake-format new file mode 100644 index 0000000..a52c7d6 --- /dev/null +++ b/.cmake-format @@ -0,0 +1,56 @@ +format: + tab_size: 2 + line_width: 100 + dangle_parens: true + +parse: + additional_commands: + cpmaddpackage: + pargs: + nargs: '*' + flags: [] + spelling: CPMAddPackage + kwargs: &cpmaddpackagekwargs + NAME: 1 + FORCE: 1 + VERSION: 1 + GIT_TAG: 1 + DOWNLOAD_ONLY: 1 + GITHUB_REPOSITORY: 1 + GITLAB_REPOSITORY: 1 + GIT_REPOSITORY: 1 + SVN_REPOSITORY: 1 + SVN_REVISION: 1 + SOURCE_DIR: 1 + DOWNLOAD_COMMAND: 1 + FIND_PACKAGE_ARGUMENTS: 1 + NO_CACHE: 1 + GIT_SHALLOW: 1 + URL: 1 + URL_HASH: 1 + URL_MD5: 1 + DOWNLOAD_NAME: 1 + DOWNLOAD_NO_EXTRACT: 1 + HTTP_USERNAME: 1 + HTTP_PASSWORD: 1 + OPTIONS: + + cpmfindpackage: + pargs: + nargs: '*' + flags: [] + spelling: CPMFindPackage + kwargs: *cpmaddpackagekwargs + packageproject: + pargs: + nargs: '*' + flags: [] + spelling: packageProject + kwargs: + NAME: 1 + VERSION: 1 + INCLUDE_DIR: 1 + INCLUDE_DESTINATION: 1 + BINARY_DIR: 1 + COMPATIBILITY: 1 + VERSION_HEADER: 1 + DEPENDENCIES: + diff --git a/.github/workflows/style.yml b/.github/workflows/style.yml index 64f8321..4851931 100644 --- a/.github/workflows/style.yml +++ b/.github/workflows/style.yml @@ -16,8 +16,10 @@ jobs: steps: - uses: actions/checkout@v1 - - name: Install clang-format - run: brew install clang-format + - name: Install format dependencies + run: | + brew install clang-format + pip install cmake_format pyyaml - name: configure run: cmake -Htest -Bbuild diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a2f77d..4efa094 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,8 @@ cmake_minimum_required(VERSION 3.14 FATAL_ERROR) # ---- Project ---- # Note: update this to your new project's name and version -project(Greeter +project( + Greeter VERSION 1.0 LANGUAGES CXX ) @@ -11,7 +12,10 @@ project(Greeter # ---- Include guards ---- if(PROJECT_SOURCE_DIR STREQUAL PROJECT_BINARY_DIR) - message(FATAL_ERROR "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there.") + message( + FATAL_ERROR + "In-source builds not allowed. Please make a new directory (called a build directory) and run CMake from there." + ) endif() # ---- Add dependencies via CPM ---- @@ -28,16 +32,16 @@ CPMAddPackage( # ---- Add source files ---- -# Note: globbing sources is considered bad practice as CMake's generators may not detect new files automatically. -# Keep that in mind when changing files, or explicitly mention them here. -FILE(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h") -FILE(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp") +# Note: globbing sources is considered bad practice as CMake's generators may not detect new files +# automatically. Keep that in mind when changing files, or explicitly mention them here. +file(GLOB_RECURSE headers CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/include/*.h") +file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp") # ---- Create library ---- -# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface target: -# add_library(Greeter INTERFACE) -# set_target_properties(Greeter PROPERTIES INTERFACE_COMPILE_FEATURES cxx_std_17) +# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface +# target: add_library(Greeter INTERFACE) set_target_properties(Greeter PROPERTIES +# INTERFACE_COMPILE_FEATURES cxx_std_17) add_library(Greeter ${headers} ${sources}) @@ -46,20 +50,18 @@ set_target_properties(Greeter PROPERTIES CXX_STANDARD 17) # being a cross-platform target, we enforce standards conformance on MSVC target_compile_options(Greeter PUBLIC "$<$:/permissive->") -# Link dependencies (if required) -# target_link_libraries(Greeter PUBLIC cxxopts) +# Link dependencies (if required) target_link_libraries(Greeter PUBLIC cxxopts) -target_include_directories(Greeter - PUBLIC - $ - $ +target_include_directories( + Greeter PUBLIC $ + $ ) # ---- Create an installable target ---- # this allows users to install and find the library via `find_package()`. -# the location where the project's version header will be placed -# should match the project's regular header paths +# the location where the project's version header will be placed should match the project's regular +# header paths string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION) packageProject( diff --git a/README.md b/README.md index c2f8a53..075eb30 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ This template is the result of learnings from many previous projects and should - Integrated test suite - Continuous integration via [GitHub Actions](https://help.github.com/en/actions/) - Code coverage via [codecov](https://codecov.io) -- Code formatting enforced by [clang-format](https://clang.llvm.org/docs/ClangFormat.html) via [Format.cmake](https://github.com/TheLartians/Format.cmake) +- Code formatting enforced by [clang-format](https://clang.llvm.org/docs/ClangFormat.html) and [cmake-format](https://github.com/cheshirekow/cmake_format) via [Format.cmake](https://github.com/TheLartians/Format.cmake) - Reproducible dependency management via [CPM.cmake](https://github.com/TheLartians/CPM.cmake) - Installable target with automatic versioning information and header generation via [PackageProject.cmake](https://github.com/TheLartians/PackageProject.cmake) - Automatic [documentation](https://thelartians.github.io/ModernCppStarter) and deployment with [Doxygen](https://www.doxygen.nl) and [GitHub Pages](https://pages.github.com) @@ -68,7 +68,8 @@ To collect code coverage information, run CMake with the `-DENABLE_TEST_COVERAGE ### Run clang-format -Use the following commands from the project's root directory to run clang-format (must be installed on the host system). +Use the following commands from the project's root directory to check and fix C++ and CMake source style. +This requires _clang-format_, _cmake-format_ and _pyyaml_ to be installed on the current system. ```bash cmake -Htest -Bbuild/test @@ -80,7 +81,7 @@ cmake --build build/test --target format cmake --build build/test --target fix-format ``` -See [Format.cmake](https://github.com/TheLartians/Format.cmake) for more options. +See [Format.cmake](https://github.com/TheLartians/Format.cmake) for details. ### Build the documentation diff --git a/cmake/tools.cmake b/cmake/tools.cmake index b0b8c30..bba1d86 100644 --- a/cmake/tools.cmake +++ b/cmake/tools.cmake @@ -1,41 +1,59 @@ -# this file contains a list of tools that can be activated and downloaded on-demand -# each tool is enabled during configuration by passing an additional `-DUSE_=` argument to CMake +# this file contains a list of tools that can be activated and downloaded on-demand each tool is +# enabled during configuration by passing an additional `-DUSE_=` argument to CMake # only activate tools for top level project -if (NOT PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) +if(NOT PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) return() endif() include(${CMAKE_CURRENT_LIST_DIR}/CPM.cmake) -# enables sanitizers support using the the `USE_SANITIZER` flag -# available values are: Address, Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined' -if (USE_SANITIZER OR USE_STATIC_ANALYZER) +# enables sanitizers support using the the `USE_SANITIZER` flag available values are: Address, +# Memory, MemoryWithOrigins, Undefined, Thread, Leak, 'Address;Undefined' +if(USE_SANITIZER OR USE_STATIC_ANALYZER) CPMAddPackage( NAME StableCoder-cmake-scripts GITHUB_REPOSITORY StableCoder/cmake-scripts GIT_TAG 3d2d5a9fb26f0ce24e3e4eaeeff686ec2ecfb3fb ) - - if (USE_SANITIZER) + + if(USE_SANITIZER) include(${StableCoder-cmake-scripts_SOURCE_DIR}/sanitizers.cmake) endif() - if (USE_STATIC_ANALYZER) - if ("clang-tidy" IN_LIST USE_STATIC_ANALYZER) - SET(CLANG_TIDY ON CACHE INTERNAL "") + if(USE_STATIC_ANALYZER) + if("clang-tidy" IN_LIST USE_STATIC_ANALYZER) + set(CLANG_TIDY + ON + CACHE INTERNAL "" + ) else() - SET(CLANG_TIDY OFF CACHE INTERNAL "") + set(CLANG_TIDY + OFF + CACHE INTERNAL "" + ) endif() - if ("iwyu" IN_LIST USE_STATIC_ANALYZER) - SET(IWYU ON CACHE INTERNAL "") + if("iwyu" IN_LIST USE_STATIC_ANALYZER) + set(IWYU + ON + CACHE INTERNAL "" + ) else() - SET(IWYU OFF CACHE INTERNAL "") + set(IWYU + OFF + CACHE INTERNAL "" + ) endif() - if ("cppcheck" IN_LIST USE_STATIC_ANALYZER) - SET(CPPCHECK ON CACHE INTERNAL "") + if("cppcheck" IN_LIST USE_STATIC_ANALYZER) + set(CPPCHECK + ON + CACHE INTERNAL "" + ) else() - SET(CPPCHECK OFF CACHE INTERNAL "") + set(CPPCHECK + OFF + CACHE INTERNAL "" + ) endif() include(${StableCoder-cmake-scripts_SOURCE_DIR}/tools.cmake) @@ -46,9 +64,8 @@ if (USE_SANITIZER OR USE_STATIC_ANALYZER) endif() endif() -# enables CCACHE support through the USE_CCACHE flag -# possible values are: YES, NO or equivalent -if (USE_CCACHE) +# enables CCACHE support through the USE_CCACHE flag possible values are: YES, NO or equivalent +if(USE_CCACHE) CPMAddPackage( NAME Ccache.cmake GITHUB_REPOSITORY TheLartians/Ccache.cmake diff --git a/documentation/CMakeLists.txt b/documentation/CMakeLists.txt index 3947179..e6f11b2 100644 --- a/documentation/CMakeLists.txt +++ b/documentation/CMakeLists.txt @@ -6,10 +6,7 @@ project(GreeterDocs) include(../cmake/CPM.cmake) -CPMAddPackage( - NAME Greeter - SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. -) +CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) CPMAddPackage( NAME MCSS @@ -27,15 +24,9 @@ set(DOXYGEN_PROJECT_VERSION ${Greeter_VERSION}) set(DOXYGEN_PROJECT_ROOT "${CMAKE_CURRENT_LIST_DIR}/..") set(DOXYGEN_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doxygen") -configure_file( - ${CMAKE_CURRENT_LIST_DIR}/Doxyfile - ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile -) +configure_file(${CMAKE_CURRENT_LIST_DIR}/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile) -configure_file( - ${CMAKE_CURRENT_LIST_DIR}/conf.py - ${CMAKE_CURRENT_BINARY_DIR}/conf.py -) +configure_file(${CMAKE_CURRENT_LIST_DIR}/conf.py ${CMAKE_CURRENT_BINARY_DIR}/conf.py) add_custom_target( GenerateDocs diff --git a/standalone/CMakeLists.txt b/standalone/CMakeLists.txt index 19a4993..20a1ed8 100644 --- a/standalone/CMakeLists.txt +++ b/standalone/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) -project(GreeterStandalone - LANGUAGES CXX -) +project(GreeterStandalone LANGUAGES CXX) # --- Import tools ---- @@ -16,15 +14,10 @@ CPMAddPackage( NAME cxxopts GITHUB_REPOSITORY jarro2783/cxxopts VERSION 2.2.0 - OPTIONS - "CXXOPTS_BUILD_EXAMPLES Off" - "CXXOPTS_BUILD_TESTS Off" + OPTIONS "CXXOPTS_BUILD_EXAMPLES Off" "CXXOPTS_BUILD_TESTS Off" ) -CPMAddPackage( - NAME Greeter - SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. -) +CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) # ---- Create standalone executable ---- @@ -32,9 +25,6 @@ file(GLOB sources CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp) add_executable(GreeterStandalone ${sources}) -set_target_properties(GreeterStandalone PROPERTIES - CXX_STANDARD 17 - OUTPUT_NAME "Greeter" -) +set_target_properties(GreeterStandalone PROPERTIES CXX_STANDARD 17 OUTPUT_NAME "Greeter") target_link_libraries(GreeterStandalone Greeter cxxopts) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9709b45..c78ea7e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,8 +1,6 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR) -project(GreeterTests - LANGUAGES CXX -) +project(GreeterTests LANGUAGES CXX) # ---- Options ---- @@ -23,19 +21,20 @@ CPMAddPackage( GIT_TAG 2.3.7 ) -if (TEST_INSTALLED_VERSION) +if(TEST_INSTALLED_VERSION) find_package(Greeter REQUIRED) else() - CPMAddPackage( - NAME Greeter - SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/.. - ) + CPMAddPackage(NAME Greeter SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/..) endif() CPMAddPackage( NAME Format.cmake GITHUB_REPOSITORY TheLartians/Format.cmake - VERSION 1.5.2 + VERSION 1.6 + OPTIONS # enable cmake formatting + "FORMAT_CHECK_CMAKE ON" + # skip CPM.cmake + "CMAKE_FORMAT_EXCLUDE cmake/CPM.cmake" ) # ---- Create binary ---- @@ -47,8 +46,8 @@ target_link_libraries(GreeterTests doctest Greeter) set_target_properties(GreeterTests PROPERTIES CXX_STANDARD 17) # enable compiler warnings -if (NOT TEST_INSTALLED_VERSION) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") +if(NOT TEST_INSTALLED_VERSION) + if(CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID MATCHES "GNU") target_compile_options(Greeter PUBLIC -Wall -pedantic -Wextra -Werror) elseif(MSVC) target_compile_options(Greeter PUBLIC /W4 /WX) @@ -58,18 +57,17 @@ endif() # ---- Add GreeterTests ---- -ENABLE_TESTING() +enable_testing() -# Note: doctest and similar testing frameworks can automatically configure CMake tests -# For other testing frameworks add the tests target instead: -# ADD_TEST(GreeterTests GreeterTests) +# Note: doctest and similar testing frameworks can automatically configure CMake tests For other +# testing frameworks add the tests target instead: ADD_TEST(GreeterTests GreeterTests) include(${doctest_SOURCE_DIR}/scripts/cmake/doctest.cmake) doctest_discover_tests(GreeterTests) # ---- code coverage ---- -if (ENABLE_TEST_COVERAGE) +if(ENABLE_TEST_COVERAGE) target_compile_options(Greeter PUBLIC -O0 -g -fprofile-arcs -ftest-coverage) target_link_options(Greeter PUBLIC -fprofile-arcs -ftest-coverage) endif()