Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 11 additions & 46 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.16...3.23)
CMAKE_MINIMUM_REQUIRED(VERSION 3.21)

# strongly encouraged to enable this globally to avoid conflicts between
# -Wpedantic being enabled and -std=c++20 and -std=gnu++20 for example
Expand All @@ -18,51 +18,25 @@ ENDIF()

SET(CMAKE_CXX_STANDARD ${CXX_STANDARD})

GET_PROPERTY(BUILDING_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
IF(BUILDING_MULTI_CONFIG)
IF(NOT CMAKE_BUILD_TYPE)
# Make sure that all supported configuration types have their
# associated conan packages available. You can reduce this
# list to only the configuration types you use, but only if one
# is not forced-set on the command line for VS
MESSAGE(TRACE "Setting up multi-config build types")
SET(CMAKE_CONFIGURATION_TYPES
Debug
Release
RelWithDebInfo
MinSizeRel
CACHE STRING "Enabled build types" FORCE)
ELSE()
MESSAGE(TRACE "User chose a specific build type, so we are using that")
SET(CMAKE_CONFIGURATION_TYPES
${CMAKE_BUILD_TYPE}
CACHE STRING "Enabled build types" FORCE)
ENDIF()
ENDIF()
INCLUDE(cmake/BuildingConfig.cmake)
SETUP_MULTI_CONFIG()

INCLUDE(cmake/StandardProjectSettings.cmake)
INCLUDE(cmake/PreventInSourceBuilds.cmake)
INCLUDE(cmake/CodeFormat.cmake)
INCLUDE(cmake/InterproceduralOptimization.cmake)
ENABLE_IPO()

EXECUTE_PROCESS(
COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE GIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
# fetch git hash information for configure version template file
INCLUDE(cmake/GitInformation.cmake)
GET_GIT_HASH()

CONFIGURE_FILE("templates/version.hpp.in" "${CMAKE_BINARY_DIR}/generated/include/version.hpp" ESCAPE_QUOTES)

# Link this 'library' to set the c++ standard / compile-time options requested
ADD_LIBRARY(project_options INTERFACE)
TARGET_COMPILE_FEATURES(project_options INTERFACE cxx_std_${CXX_STANDARD})

IF(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
IF(ENABLE_BUILD_WITH_TIME_TRACE)
TARGET_COMPILE_OPTIONS(project_options INTERFACE -ftime-trace)
ENDIF()
ENDIF()

# Link this 'library' to use the warnings specified in CompilerWarnings.cmake
ADD_LIBRARY(project_warnings INTERFACE)

Expand All @@ -84,18 +58,9 @@ ENABLE_DOXYGEN()
# allow for static analysis options
INCLUDE(cmake/StaticAnalyzers.cmake)

IF(ENABLE_PCH)
# This sets a global PCH parameter, each project will build its own PCH, which is a good idea if any #define's change
#
# consider breaking this out per project as necessary
TARGET_PRECOMPILE_HEADERS(
project_options
INTERFACE
<vector>
<string>
<map>
<utility>)
ENDIF()
# enabled precompiled headers
INCLUDE(cmake/PrecompiledHeader.cmake)
ENABLE_PCH()

INCLUDE(cmake/Conan.cmake)
RUN_CONAN()
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Ongoing project of the Zühlke Germany **Modern C++ Topic Group**.
With this project, we want to provide an example and starting point for C++ projects (embedded and otherwise), especially regarding tooling.

The project has initially been forked/copied from [Jason Turner's cpp_starter_project](https://github.com/lefticus/cpp_starter_project) and is customised by Zühlke members and adapted to [Jason Turner's cmake_conan_boilerplate_template](https://github.com/cpp-best-practices/cmake_conan_boilerplate_template).

It also uses CMake structure from [Jason Turner's cmake_template](https://github.com/cpp-best-practices/cmake_template) repository.

## Build Status

Expand Down
23 changes: 23 additions & 0 deletions cmake/BuildingConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
FUNCTION(SETUP_MULTI_CONFIG)
GET_PROPERTY(BUILDING_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
IF(BUILDING_MULTI_CONFIG)
IF(NOT CMAKE_BUILD_TYPE)
# Make sure that all supported configuration types have their
# associated conan packages available. You can reduce this
# list to only the configuration types you use, but only if one
# is not forced-set on the command line for VS
MESSAGE(TRACE "Setting up multi-config build types")
SET(CMAKE_CONFIGURATION_TYPES
Debug
Release
RelWithDebInfo
MinSizeRel
CACHE STRING "Enabled build types" FORCE)
ELSE()
MESSAGE(TRACE "User chose a specific build type, so we are using that")
SET(CMAKE_CONFIGURATION_TYPES
${CMAKE_BUILD_TYPE}
CACHE STRING "Enabled build types" FORCE)
ENDIF()
ENDIF()
ENDFUNCTION()
2 changes: 1 addition & 1 deletion cmake/CompilerWarnings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
# https://github.com/lefticus/cppbestpractices/blob/master/02-Use_the_Tools_Available.md

FUNCTION(SET_PROJECT_WARNINGS project_name)
OPTION(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" TRUE)

SET(MSVC_WARNINGS
/W4 # Baseline reasonable warnings
Expand Down Expand Up @@ -47,6 +46,7 @@ FUNCTION(SET_PROJECT_WARNINGS project_name)
-Wnull-dereference # warn if a null dereference is detected
-Wdouble-promotion # warn if float is implicit promoted to double
-Wformat=2 # warn on security issues around functions that format output (ie printf)
-Wimplicit-fallthrough # warn on statements that fallthrough without an explicit annotation
)

IF(WARNINGS_AS_ERRORS)
Expand Down
50 changes: 48 additions & 2 deletions cmake/Doxygen.cmake
Original file line number Diff line number Diff line change
@@ -1,10 +1,56 @@
FUNCTION(ENABLE_DOXYGEN)
IF(ENABLE_DOXYGEN)
# If not specified, use the top readme file as the first page
IF((NOT DOXYGEN_USE_MDFILE_AS_MAINPAGE) AND EXISTS "${PROJECT_SOURCE_DIR}/README.md")
SET(DOXYGEN_USE_MDFILE_AS_MAINPAGE "${PROJECT_SOURCE_DIR}/README.md")
ENDIF()

# set better defaults for doxygen
IS_VERBOSE(_is_verbose)
IF(NOT ${_is_verbose})
SET(DOXYGEN_QUIET YES)
ENDIF()
SET(DOXYGEN_CALLER_GRAPH YES)
SET(DOXYGEN_CALL_GRAPH YES)
SET(DOXYGEN_EXTRACT_ALL YES)
FIND_PACKAGE(Doxygen REQUIRED dot)
DOXYGEN_ADD_DOCS(doxygen-docs ${PROJECT_SOURCE_DIR})
SET(DOXYGEN_GENERATE_TREEVIEW YES)
# svg files are much smaller than jpeg and png, and yet they have higher quality
SET(DOXYGEN_DOT_IMAGE_FORMAT svg)
SET(DOXYGEN_DOT_TRANSPARENT YES)

# If not specified, exclude the vcpkg files and the files CMake downloads under _deps (like project_options)
IF(NOT DOXYGEN_EXCLUDE_PATTERNS)
SET(DOXYGEN_EXCLUDE_PATTERNS "${CMAKE_CURRENT_BINARY_DIR}/vcpkg_installed/*" "${CMAKE_CURRENT_BINARY_DIR}/_deps/*")
ENDIF()

IF("${DOXYGEN_THEME}" STREQUAL "")
SET(DOXYGEN_THEME "awesome-sidebar")
ENDIF()

IF("${DOXYGEN_THEME}" STREQUAL "awesome" OR "${DOXYGEN_THEME}" STREQUAL "awesome-sidebar")
# use a modern doxygen theme
# https://github.com/jothepro/doxygen-awesome-css v2.0.0
FETCHCONTENT_DECLARE(_doxygen_theme
URL https://github.com/jothepro/doxygen-awesome-css/archive/refs/tags/v2.2.0.zip)
FETCHCONTENT_MAKEAVAILABLE(_doxygen_theme)
IF("${DOXYGEN_THEME}" STREQUAL "awesome" OR "${DOXYGEN_THEME}" STREQUAL "awesome-sidebar")
SET(DOXYGEN_HTML_EXTRA_STYLESHEET "${_doxygen_theme_SOURCE_DIR}/doxygen-awesome.css")
ENDIF()
IF("${DOXYGEN_THEME}" STREQUAL "awesome-sidebar")
SET(DOXYGEN_HTML_EXTRA_STYLESHEET ${DOXYGEN_HTML_EXTRA_STYLESHEET}
"${_doxygen_theme_SOURCE_DIR}/doxygen-awesome-sidebar-only.css")
ENDIF()
ELSE()
# use the original doxygen theme
ENDIF()

# find doxygen and dot if available
FIND_PACKAGE(Doxygen REQUIRED OPTIONAL_COMPONENTS dot)

# add doxygen-docs target
MESSAGE(STATUS "Adding `doxygen-docs` target that builds the documentation.")
DOXYGEN_ADD_DOCS(doxygen-docs ALL ${PROJECT_SOURCE_DIR}
COMMENT "Generating documentation - entry file: ${CMAKE_CURRENT_BINARY_DIR}/html/index.html")

ENDIF()
ENDFUNCTION()
10 changes: 10 additions & 0 deletions cmake/GitInformation.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FUNCTION(GET_GIT_HASH)
EXECUTE_PROCESS(
COMMAND git log -1 --format=%h
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
OUTPUT_VARIABLE HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)

SET(GIT_HASH ${HASH} PARENT_SCOPE)
ENDFUNCTION()
11 changes: 11 additions & 0 deletions cmake/InterproceduralOptimization.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
FUNCTION(ENABLE_IPO)
IF(ENABLE_IPO)
INCLUDE(CheckIPOSupported)
CHECK_IPO_SUPPORTED(RESULT result OUTPUT output)
IF(result)
SET(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
ELSE()
MESSAGE(SEND_ERROR "IPO is not supported: ${output}")
ENDIF()
ENDIF()
ENDFUNCTION()
42 changes: 18 additions & 24 deletions cmake/Options.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,36 @@ IF(NOT MSVC)
OPTION(ENABLE_BUILD_WITH_TIME_TRACE "Enable -ftime-trace to generate time tracing .json files on clang" OFF)
ENDIF()

OPTION(BUILD_SHARED_LIBS "Enable compilation of shared libraries" OFF)
OPTION(ENABLE_TESTING "Enable Test Builds" ON)
OPTION(ENABLE_FUZZING "Enable Fuzzing Builds" OFF)

# Very basic PCH example
OPTION(ENABLE_PCH "Enable Precompiled Headers" OFF)

option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF)
option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF)
option(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF)
# static analyzers
OPTION(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF)
OPTION(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF)
OPTION(ENABLE_INCLUDE_WHAT_YOU_USE "Enable static analysis with include-what-you-use" OFF)

# tooling
OPTION(ENABLE_CACHE "Enable cache if available" ON)
option(ENABLE_DOXYGEN "Enable doxygen doc builds of source" OFF)
OPTION(ENABLE_DOXYGEN "Enable doxygen doc builds of source" OFF)

# Sanitizers
OPTION(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" FALSE)
OPTION(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" FALSE)
OPTION(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" FALSE)
OPTION(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" FALSE)
OPTION(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" FALSE)

OPTION(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" FALSE)

OPTION(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR "Enable undefined behavior sanitizer" OFF)
OPTION(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF)
OPTION(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF)
OPTION(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF)
OPTION(ENABLE_SANITIZER_LEAK "Enable leak sanitizer" OFF)

# others
OPTION(ENABLE_COVERAGE "Enable coverage reporting for gcc/clang" OFF)
OPTION(ENABLE_IPO "Enable Interprocedural Optimization, aka Link Time Optimization (LTO)" OFF)
OPTION(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" ON)
OPTION(BUILD_SHARED_LIBS "Enable compilation of shared libraries" OFF)
OPTION(ENABLE_TESTING "Enable Test Builds" ON)
OPTION(ENABLE_FUZZING "Enable Fuzzing Builds" OFF)

# examples
OPTION(CPP_STARTER_USE_SML "Enable compilation of SML sample" OFF)
OPTION(CPP_STARTER_USE_BOOST_BEAST "Enable compilation of boost beast sample" OFF)
OPTION(CPP_STARTER_USE_CROW "Enable compilation of crow sample" OFF)
OPTION(CPP_STARTER_USE_CPPZMQ_PROTO "Enable compilation of protobuf and cppzmq sample" OFF)
OPTION(CPP_STARTER_USE_EMBEDDED_TOOLCHAIN "Enable compilation of an example cortex m4 project" OFF)

# Note: by default ENABLE_DEVELOPER_MODE is True
# This means that all analysis (sanitizers, static analysis)
# is enabled and all warnings are treated as errors
# if you want to switch this behavior, change TRUE to FALSE
SET(ENABLE_DEVELOPER_MODE
TRUE
CACHE BOOL "Enable 'developer mode'")
14 changes: 14 additions & 0 deletions cmake/PrecompiledHeader.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FUNCTION(ENABLE_PCH)
IF(ENABLE_PCH)
# This sets a global PCH parameter, each project will build its own PCH, which is a good idea if any #define's change
#
# consider breaking this out per project as necessary
TARGET_PRECOMPILE_HEADERS(
project_options
INTERFACE
<vector>
<string>
<map>
<utility>)
ENDIF()
ENDFUNCTION()
37 changes: 23 additions & 14 deletions cmake/StandardProjectSettings.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,32 @@ ENDIF()
# Generate compile_commands.json to make it easier to work with clang based tools
SET(CMAKE_EXPORT_COMPILE_COMMANDS ON)

IF(ENABLE_IPO)
INCLUDE(CheckIPOSupported)
CHECK_IPO_SUPPORTED(
RESULT
result
OUTPUT
output)
IF(result)
SET(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
# Enhance error reporting and compiler messages
IF(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
IF(ENABLE_BUILD_WITH_TIME_TRACE)
TARGET_COMPILE_OPTIONS(project_options INTERFACE -ftime-trace)
ENDIF()

IF(WIN32)
# On Windows cuda nvcc uses cl and not clang
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C>:-fcolor-diagnostics> $<$<COMPILE_LANGUAGE:CXX>:-fcolor-diagnostics>)
ELSE()
MESSAGE(SEND_ERROR "IPO is not supported: ${output}")
ADD_COMPILE_OPTIONS(-fcolor-diagnostics)
ENDIF()
ENDIF()
IF(CMAKE_CXX_COMPILER_ID MATCHES ".*Clang")
ADD_COMPILE_OPTIONS(-fcolor-diagnostics)
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
ADD_COMPILE_OPTIONS(-fdiagnostics-color=always)
IF(WIN32)
# On Windows cuda nvcc uses cl and not gcc
ADD_COMPILE_OPTIONS($<$<COMPILE_LANGUAGE:C>:-fdiagnostics-color=always>
$<$<COMPILE_LANGUAGE:CXX>:-fdiagnostics-color=always>)
ELSE()
ADD_COMPILE_OPTIONS(-fdiagnostics-color=always)
ENDIF()
ELSEIF(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION GREATER 1900)
ADD_COMPILE_OPTIONS(/diagnostics:column)
ELSE()
MESSAGE(STATUS "No colored compiler diagnostic set for '${CMAKE_CXX_COMPILER_ID}' compiler.")
ENDIF()

# run vcvarsall when msvc is used
INCLUDE("${CMAKE_CURRENT_LIST_DIR}/VCEnvironment.cmake")
RUN_VCVARSALL()
Loading