diff --git a/CMakeLists.txt b/CMakeLists.txt index af0a90edb..849cedda7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ project( ) # We use additional modules that cmake needs to know about -set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/" "${CMAKE_SOURCE_DIR}/cmake/Modules/") # Output the compilation database set(CMAKE_EXPORT_COMPILE_COMMANDS @@ -63,38 +63,13 @@ if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) set(MASTER_PROJECT ON) endif() -if(MSVC) - add_compile_options(/W4) -else() - add_compile_options(-Wall -Wextra -pedantic) -endif(MSVC) - # If this option is set we are building using continous integration option(CI_BUILD "Enable build options for building in the CI server" OFF) -# Default not to run the clang-tidy checks, default to whatever our CI_BUILD is -option(ENABLE_CLANG_TIDY "Enable building with clang-tidy checks.") -if(ENABLE_CLANG_TIDY) - # Search for clang-tidy first as this is the version installed in CI - find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy) - message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXECUTABLE}") - if(NOT CLANG_TIDY_EXECUTABLE) - message(FATAL_ERROR "clang-tidy not found.") - endif() - - # Report clang-tidy executable details - execute_process(COMMAND "${CLANG_TIDY_EXECUTABLE}" "--version" OUTPUT_VARIABLE CLANG_TIDY_VERSION) - string(REGEX REPLACE ".*LLVM version ([0-9.]*).*" "\\1" CLANG_TIDY_VERSION "${CLANG_TIDY_VERSION}") - message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXECUTABLE} ${CLANG_TIDY_VERSION}") - - # Build clang-tidy command line - set(CLANG_TIDY_ARGS "${CLANG_TIDY_EXECUTABLE}" "--use-color" "--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy") - if(CI_BUILD) - set(CLANG_TIDY_ARGS "${CLANG_TIDY_EXECUTABLE}" "-warnings-as-errors=*") - endif(CI_BUILD) - set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_ARGS}" "--extra-arg=-std=c++14") - set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_ARGS}" "--extra-arg=-std=c99") -endif(ENABLE_CLANG_TIDY) +# Include files to set up the compiler options +include(ClangTidy) +include(CompilerOptions) +include(Sanitizers) # If we are doing a CI build then we want to enable -Werror when compiling warnings are bad. We will also make it fail # if clang-tidy has an error @@ -106,19 +81,11 @@ if(CI_BUILD) endif() endif(CI_BUILD) -# Make the compiler display colours always (even when we build with ninja) -if(CMAKE_CXX_COMPILER_ID MATCHES GNU) - add_compile_options(-fdiagnostics-color=always) -endif() -if(CMAKE_CXX_COMPILER_ID MATCHES Clang) - add_compile_options(-fcolor-diagnostics) -endif() - # Add the src directory add_subdirectory(src) # Add the tests directory -option(BUILD_TESTS "Builds all of the NUClear unit tests." TRUE) +option(BUILD_TESTS "Builds all of the NUClear unit tests." OFF) if(BUILD_TESTS) enable_testing() add_subdirectory(tests) diff --git a/cmake/ClangTidy.cmake b/cmake/ClangTidy.cmake new file mode 100644 index 000000000..e1d6f051f --- /dev/null +++ b/cmake/ClangTidy.cmake @@ -0,0 +1,22 @@ +# Default not to run the clang-tidy checks, default to whatever our CI_BUILD is +option(ENABLE_CLANG_TIDY "Enable building with clang-tidy checks.") +if(ENABLE_CLANG_TIDY) + # Search for clang-tidy-15 first as this is the version installed in CI + find_program(CLANG_TIDY_EXECUTABLE NAMES clang-tidy-15 clang-tidy) + if(NOT CLANG_TIDY_EXECUTABLE) + message(FATAL_ERROR "clang-tidy-15 not found.") + endif() + + # Report clang-tidy executable details + execute_process(COMMAND "${CLANG_TIDY_EXECUTABLE}" "--version" OUTPUT_VARIABLE CLANG_TIDY_VERSION) + string(REGEX REPLACE ".*LLVM version ([0-9.]*).*" "\\1" CLANG_TIDY_VERSION "${CLANG_TIDY_VERSION}") + message(STATUS "Found clang-tidy: ${CLANG_TIDY_EXECUTABLE} ${CLANG_TIDY_VERSION}") + + # Build clang-tidy command line + set(CLANG_TIDY_ARGS "${CLANG_TIDY_EXECUTABLE}" "--use-color" "--config-file=${PROJECT_SOURCE_DIR}/.clang-tidy") + if(CI_BUILD) + set(CLANG_TIDY_ARGS "${CLANG_TIDY_EXECUTABLE}" "-warnings-as-errors=*") + endif(CI_BUILD) + set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_ARGS}" "--extra-arg=-std=c++14") + set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_ARGS}" "--extra-arg=-std=c99") +endif(ENABLE_CLANG_TIDY) diff --git a/cmake/CompilerOptions.cmake b/cmake/CompilerOptions.cmake new file mode 100644 index 000000000..4f8bcde79 --- /dev/null +++ b/cmake/CompilerOptions.cmake @@ -0,0 +1,7 @@ +# Make the compiler display colours always (even when we build with ninja) +if(CMAKE_CXX_COMPILER_ID MATCHES GNU) + add_compile_options(-fdiagnostics-color=always) +endif() +if(CMAKE_CXX_COMPILER_ID MATCHES Clang) + add_compile_options(-fcolor-diagnostics) +endif() diff --git a/cmake/Sanitizers.cmake b/cmake/Sanitizers.cmake new file mode 100644 index 000000000..91877a300 --- /dev/null +++ b/cmake/Sanitizers.cmake @@ -0,0 +1,47 @@ +############################################################################### +### Options for enabling different sanitisers. ### +### ### +### User beware: ### +### Not all sanitisers can be enabled at the same time. ### +############################################################################### +option(USE_ASAN "Enable address sanitization" OFF) +if(USE_ASAN) + add_compile_options(-fsanitize=address -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) + add_link_options(-fsanitize=address) + link_libraries(asan) +endif(USE_ASAN) + +option(USE_LSAN "Enable leak sanitization" OFF) +if(USE_LSAN) + add_compile_options(-fsanitize=leak -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) + add_link_options(-fsanitize=leak) + link_libraries(lsan) +endif(USE_LSAN) + +option(USE_TSAN "Enable thread sanitization" OFF) +if(USE_TSAN) + add_compile_options(-fsanitize=thread -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) + add_link_options(-fsanitize=thread) + link_libraries(tsan) +endif(USE_TSAN) + +option(USE_UBSAN "Enable undefined behaviour sanitization" OFF) +if(USE_UBSAN) + add_compile_options(-fsanitize=undefined -fno-omit-frame-pointer -U_FORTIFY_SOURCE -fno-common) + add_link_options(-fsanitize=undefined) + link_libraries(ubsan) +endif(USE_UBSAN) + +# Option for enabling code profiling. Disabled by default +option(ENABLE_PROFILING "Compile with profiling support enabled." OFF) +if(ENABLE_PROFILING) + if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") + message( + WARNING + "Profiling is enabled but no debugging symbols will be kept in the compiled binaries. This may cause fine-grained profilling data to be lost." + ) + endif() + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pg -fprofile-arcs") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pg -fprofile-arcs") + set(CMAKE_LINKER "${CMAKE_LINKER_FLAGS} -pg -fprofile-arcs") +endif(ENABLE_PROFILING)