Skip to content

Instantly share code, notes, and snippets.

@ttonnellier
Last active April 16, 2020 13:46
Show Gist options
  • Save ttonnellier/a6559db8ac16e35ac4335b7ff0147c4b to your computer and use it in GitHub Desktop.
Save ttonnellier/a6559db8ac16e35ac4335b7ff0147c4b to your computer and use it in GitHub Desktop.
cmake_minimum_required(VERSION 3.13)
project(
project
VERSION 1.0
DESCRIPTION "project"
LANGUAGES CXX)
# Standard Project Settings Set a default build type if none was specified
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(
STATUS "Setting build type to 'RelWithDebInfo' as none was specified.")
set(CMAKE_BUILD_TYPE
RelWithDebInfo
CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui, ccmake
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
else()
message(STATUS "Build type: " ${CMAKE_BUILD_TYPE})
endif()
find_program(CCACHE ccache)
option(ENABLE_CCACHE "Enable CCACHE" OFF)
# set(ENABLE_CCACHE OFF)
if(CCACHE)
if(ENABLE_CCACHE)
message(STATUS "Ccache enabled")
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE})
endif()
else()
message(STATUS "ccache not found cannot use")
endif()
# Generate compile_commands.json to make it easier to work with clang based
# tools
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(ENABLE_IPO
"Enable Iterprocedural Optimization, aka Link Time Optimization (LTO)"
OFF)
# set(ENABLE_IPO OFF)
if(ENABLE_IPO)
message(STATUS "IPO enabled")
include(CheckIPOSupported)
check_ipo_supported(RESULT result OUTPUT output)
if(result)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
else()
message(SEND_ERROR "IPO is not supported: ${output}")
endif()
endif()
# ############# Standard Project Settings
# Warnings
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
# set(WARNINGS_AS_ERRORS OFF)
set(CLANG_WARNINGS
-Wall
-Wextra # reasonable and standard
-Wshadow # warn the user if a variable declaration shadows one from a
# parent context
-Wnon-virtual-dtor # warn the user if a class with virtual functions has a
# non-virtual destructor. This helps catch hard to track
# down memory errors
-Wold-style-cast # warn for c-style casts
-Wcast-align # warn for potential performance problem casts
-Wunused # warn on anything being unused
-Woverloaded-virtual # warn if you overload (not override) a virtual
# function
-Wpedantic # warn if non-standard C++ is used
-Wconversion # warn on type conversions that may lose data
-Wsign-conversion # warn on sign conversions
-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)
)
if(WARNINGS_AS_ERRORS)
set(CLANG_WARNINGS ${CLANG_WARNINGS} -Werror)
endif()
set(GCC_WARNINGS
${CLANG_WARNINGS}
-Wmisleading-indentation # warn if identation implies blocks where blocks do
# not exist
-Wduplicated-cond # warn if if / else chain has duplicated conditions
-Wduplicated-branches # warn if if / else branches have duplicated code
-Wlogical-op # warn about logical operations being used where bitwise were
# probably wanted
-Wuseless-cast # warn if you perform a cast to the same type
-Wundef
-Wlogical-op
-Wmissing-declarations
-Wredundant-decls
-Woverloaded-virtual)
if(MSVC)
set(PROJECT_WARNINGS ${MSVC_WARNINGS})
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(PROJECT_WARNINGS ${CLANG_WARNINGS})
else()
set(PROJECT_WARNINGS ${GCC_WARNINGS})
endif()
# ############# Warnings
# clang-tidy
option(ENABLE_CPPCHECK "Enable static analysis with cppcheck" OFF)
option(ENABLE_CLANG_TIDY "Enable static analysis with clang-tidy" OFF)
# set(ENABLE_CPPCHECK ON) set(ENABLE_CLANG_TIDY OFF)
if(ENABLE_CPPCHECK)
message(STATUS "cpp_check enabled")
find_program(CPPCHECK cppcheck)
if(CPPCHECK)
set(CMAKE_CXX_CPPCHECK ${CPPCHECK} --suppress=missingInclude --enable=all
--inconclusive -i ${CMAKE_SOURCE_DIR})
else()
message(SEND_ERROR "cppcheck requested but executable not found")
endif()
endif()
if(ENABLE_CLANG_TIDY)
message(STATUS "clang-tidy enabled")
find_program(CLANGTIDY clang-tidy)
if(CLANGTIDY)
set(CMAKE_CXX_CLANG_TIDY ${CLANGTIDY} "-checks=*,-clang-analyzer-alpha.*")
else()
message(SEND_ERROR "clang-tidy requested but executable not found")
endif()
endif()
# ##############################################################################
set(SANITIZERS "")
option(ENABLE_SANITIZER_ADDRESS "Enable address sanitizer" OFF)
if(ENABLE_SANITIZER_ADDRESS)
message(STATUS "Address sanitizer enabled")
list(APPEND SANITIZERS "address")
endif()
option(ENABLE_SANITIZER_MEMORY "Enable memory sanitizer" OFF)
if(ENABLE_SANITIZER_MEMORY)
message(STATUS "Memory sanitizer enabled")
list(APPEND SANITIZERS "memory")
endif()
option(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR
"Enable undefined behavior sanitizer" OFF)
if(ENABLE_SANITIZER_UNDEFINED_BEHAVIOR)
message(STATUS "Undef behav sanitizer enabled")
list(APPEND SANITIZERS "undefined")
endif()
option(ENABLE_SANITIZER_THREAD "Enable thread sanitizer" OFF)
if(ENABLE_SANITIZER_THREAD)
message(STATUS "Thread sanitizer enabled")
list(APPEND SANITIZERS "thread")
endif()
list(JOIN SANITIZERS "," LIST_OF_SANITIZERS)
# generate source files list
file(GLOB_RECURSE source_files src/*)
include_directories(src)
# binary
add_executable(project ${source_files})
target_compile_features(project PUBLIC cxx_std_17)
target_compile_options(project PUBLIC ${PROJECT_WARNINGS})
set_target_properties(project PROPERTIES OUTPUT_NAME ../project)
target_link_libraries(project -pthread)
if(CMAKE_BUILD_TYPE STREQUAL "Release")
# CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_SUPPORTS_MARCH_NATIVE)
# if(COMPILER_SUPPORTS_MARCH_NATIVE)
target_compile_options(
project PUBLIC "$<$<CONFIG:RELEASE>:-march=native;-funroll-loops>")
endif()
if(LIST_OF_SANITIZERS)
if(NOT "${LIST_OF_SANITIZERS}" STREQUAL "")
target_compile_options(project PUBLIC -fsanitize=${LIST_OF_SANITIZERS})
target_link_libraries(project -fsanitize=${LIST_OF_SANITIZERS})
endif()
endif()
if(DEFINED ENV{MKLROOT})
message(STATUS "MKL found in " $ENV{MKLROOT})
add_definitions("-DENABLE_MKL")
target_include_directories(project PUBLIC $ENV{MKLROOT}/include)
target_link_libraries(
project
-L$ENV{MKLROOT}/lib/intel64
-Wl,--no-as-needed
-lmkl_intel_lp64
-lmkl_intel_thread
-lmkl_core
-liomp5
-lpthread
-lm
-ldl)
endif()
if(CLANG_TIDY)
if(CLANG_TIDY_EXE)
set_target_properties(project PROPERTIES CXX_CLANG_TIDY "${DO_CLANG_TIDY}")
endif()
endif()
option(ENABLE_DOXYGEN "Enable doxygen doc builds of source" OFF)
if(ENABLE_DOXYGEN)
message(STATUS "Doxygen enabled")
set(DOXYGEN_CALLER_GRAPH ON)
set(DOXYGEN_CALL_GRAPH ON)
set(DOXYGEN_EXTRACT_ALL ON)
find_package(Doxygen REQUIRED dot)
doxygen_add_docs(doxygen-docs ${source_files})
endif()
find_program(CLANGFORMAT clang-format)
if(CLANGFORMAT)
message(STATUS "clangformat make rule added")
add_custom_target(clangformat COMMAND ${CLANGFORMAT} -style=file -i
${source_files})
endif()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment