include_guard(GLOBAL) # based on https://github.com/bluescarni/yacma include(CheckCXXCompilerFlag) macro(CHECK_ENABLE_CXX_FLAG flag) set(CMAKE_REQUIRED_QUIET TRUE) check_cxx_compiler_flag("${flag}" CHECK_CXX_FLAG) unset(CMAKE_REQUIRED_QUIET) # cmake-format: off if(CHECK_CXX_FLAG) myx_cmake_message_notice("'${flag}': flag is supported.") string(CONCAT _MYX_CMAKE_DETECTED_CXX_FLAGS "${_MYX_CMAKE_DETECTED_CXX_FLAGS} ${flag}") else() myx_cmake_message_status("'${flag}': flag is NOT supported.") endif() # cmake-format: on # NOTE: check_cxx_compiler stores variables in the cache. unset(CHECK_CXX_FLAG CACHE) endmacro() macro(CHECK_ENABLE_DEBUG_CXX_FLAG flag) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(CMAKE_REQUIRED_QUIET TRUE) check_cxx_compiler_flag("${flag}" CHECK_CXX_FLAG_DEBUG) unset(CMAKE_REQUIRED_QUIET) # cmake-format: off if(CHECK_CXX_FLAG_DEBUG) myx_cmake_message_notice("'${flag}': debug flag is supported.") string(CONCAT _MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG "${_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG} ${flag}") else() myx_cmake_message_status("'${flag}': debug flag is NOT supported.") endif() # cmake-format: on # NOTE: check_cxx_compiler stores variables in the cache. unset(CHECK_CXX_FLAG_DEBUG CACHE) endif() endmacro() function(myx_cmake_set_cxx_standard version) # cmake-format: off # Выбор стандарта по умолчанию (можно переопределить в проекте) set(CMAKE_CXX_STANDARD_REQUIRED YES PARENT_SCOPE) if(version EQUAL 11) set(CMAKE_CXX_STANDARD 11 PARENT_SCOPE) set(CMAKE_CXX_EXTENSIONS YES PARENT_SCOPE) endif() if(version EQUAL 14) set(CMAKE_CXX_STANDARD 14 PARENT_SCOPE) set(CMAKE_CXX_EXTENSIONS YES PARENT_SCOPE) endif() if(version EQUAL 17) if(${CMAKE_VERSION} VERSION_LESS "3.10.0") check_cxx_compiler_flag(-std=gnu++17 HAVE_FLAG_STD_GNUXX17) if(HAVE_FLAG_STD_GNUXX17) add_compile_options("-std=gnu++17") else() check_cxx_compiler_flag(-std=gnu++1z HAVE_FLAG_STD_GNUXX1Z) if(HAVE_FLAG_STD_GNUXX1Z) add_compile_options("-std=gnu++1z") else() check_cxx_compiler_flag(-std=c++17 HAVE_FLAG_STD_CXX17) if(HAVE_FLAG_STD_CXX17) add_compile_options("-std=c++17") else() check_cxx_compiler_flag(-std=c++1z HAVE_FLAG_STD_CXX1Z) if(HAVE_FLAG_STD_CXX1Z) add_compile_options("-std=c++1z") endif() endif() endif() endif() else() set(CMAKE_CXX_STANDARD 17 PARENT_SCOPE) set(CMAKE_CXX_EXTENSIONS YES PARENT_SCOPE) endif() endif() # cmake-format: on endfunction() if(NOT MYX_CMAKE_CXX_FLAGS_AUTODETECTION_DONE) set(_MYX_CMAKE_DETECTED_CXX_FLAGS "") set(_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG "") # Configuration bits specific for clang. if(CMAKE_CXX_COMPILER_IS_CLANG) if(CMAKE_COLOR_MAKEFILE) check_enable_cxx_flag(-fcolor-diagnostics) endif() # For now it seems like -Wshadow from clang behaves better than GCC's, just # enable it here for the time being. check_enable_debug_cxx_flag(-Wshadow) # New warnings in clang 8. NOTE: a few issues with macros here, let's # disable for now. CHECK_ENABLE_DEBUG_CXX_FLAG(-Wextra-semi-stmt) New # warnings in clang 10. check_enable_debug_cxx_flag(-Wtautological-overlap-compare) check_enable_debug_cxx_flag(-Wtautological-compare) check_enable_debug_cxx_flag(-Wtautological-bitwise-compare) check_enable_debug_cxx_flag(-Wbitwise-conditional-parentheses) check_enable_debug_cxx_flag(-Wrange-loop-analysis) check_enable_debug_cxx_flag(-Wmisleading-indentation) check_enable_debug_cxx_flag(-Wc99-designator) check_enable_debug_cxx_flag(-Wreorder-init-list) check_enable_debug_cxx_flag(-Wsizeof-pointer-div) check_enable_debug_cxx_flag(-Wsizeof-array-div) check_enable_debug_cxx_flag(-Wxor-used-as-pow) check_enable_debug_cxx_flag(-Wfinal-dtor-non-final-class) # NOTE: this is a new flag in Clang 13 which seems to give # incorrect warnings for UDLs. check_enable_debug_cxx_flag(-Wno-reserved-identifier) endif() # Common configuration for GCC, clang and Intel. if(CMAKE_CXX_COMPILER_IS_CLANG OR CMAKE_CXX_COMPILER_IS_INTEL OR CMAKE_CXX_COMPILER_IS_GCC) check_enable_debug_cxx_flag(-Wall) check_enable_debug_cxx_flag(-Wextra) check_enable_debug_cxx_flag(-Wnon-virtual-dtor) check_enable_debug_cxx_flag(-Wnoexcept) check_enable_debug_cxx_flag(-Wlogical-op) check_enable_debug_cxx_flag(-Wconversion) check_enable_debug_cxx_flag(-Wdeprecated) # This limit is supposed to be at least 1024 in C++11, but for some reason # clang sets this to 256, and gcc to 900. check_enable_cxx_flag(-ftemplate-depth=1024) check_enable_debug_cxx_flag(-Wold-style-cast) check_enable_debug_cxx_flag(-Wdisabled-optimization) # This is useful when the compiler decides the template backtrace is too # verbose. check_enable_debug_cxx_flag(-ftemplate-backtrace-limit=0) check_enable_debug_cxx_flag(-fstack-protector-all) # A few suggestion flags. check_enable_debug_cxx_flag(-Wsuggest-attribute=pure) check_enable_debug_cxx_flag(-Wsuggest-attribute=const) check_enable_debug_cxx_flag(-Wsuggest-attribute=noreturn) check_enable_debug_cxx_flag(-Wsuggest-attribute=format) # From GCC 5. check_enable_debug_cxx_flag(-Wodr) check_enable_debug_cxx_flag(-Wsuggest-final-types) check_enable_debug_cxx_flag(-Wsuggest-final-methods) check_enable_debug_cxx_flag(-Wsuggest-override) # From GCC 6. check_enable_debug_cxx_flag(-Wshift-negative-value) check_enable_debug_cxx_flag(-Wshift-overflow=2) check_enable_debug_cxx_flag(-Wduplicated-cond) check_enable_debug_cxx_flag(-Wnull-dereference) # From GCC 7. check_enable_debug_cxx_flag(-Wrestrict) check_enable_debug_cxx_flag(-Waligned-new) check_enable_debug_cxx_flag(-fdiagnostics-parseable-fixits) check_enable_debug_cxx_flag(-fdiagnostics-generate-patch) # From GCC 8. check_enable_debug_cxx_flag(-Wcast-align=strict) # This is supposed to produce a nice graphical visualization of mismatching # template errors. check_enable_cxx_flag(-fdiagnostics-show-template-tree) check_enable_debug_cxx_flag(-fdiagnostics-show-option) check_enable_debug_cxx_flag(-pedantic) check_enable_debug_cxx_flag(-Wcast-align) check_enable_debug_cxx_flag(-Wcast-qual) check_enable_debug_cxx_flag(-Wctor-dtor-privacy) check_enable_debug_cxx_flag(-Wdisabled-optimization) check_enable_debug_cxx_flag(-Wformat=2) check_enable_debug_cxx_flag(-Winit-self) check_enable_debug_cxx_flag(-Wmissing-include-dirs) check_enable_debug_cxx_flag(-Woverloaded-virtual) check_enable_debug_cxx_flag(-Wredundant-decls) check_enable_debug_cxx_flag(-Wsign-promo) check_enable_debug_cxx_flag(-Wstrict-overflow=5) check_enable_debug_cxx_flag(-Wundef) check_enable_debug_cxx_flag(-Wno-unused) check_enable_debug_cxx_flag(-Wno-variadic-macros) check_enable_debug_cxx_flag(-Wno-parentheses) check_enable_debug_cxx_flag(-Wstrict-null-sentinel) check_enable_debug_cxx_flag(-Wshadow-all) endif() if(CMAKE_CXX_COMPILER_IS_GCC) if(CMAKE_COLOR_MAKEFILE) check_enable_cxx_flag(-fdiagnostics-color=auto) endif() # The -Wmaybe-uninitialized flag is enabled by -Wall, but it is known to # emit a lot of possibly spurious warnings. Let's just disable it. check_enable_debug_cxx_flag(-Wno-maybe-uninitialized) # New in GCC 9. check_enable_debug_cxx_flag(-Waddress-of-packed-member) if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "5.999") # NOTE: GCC >= 6 seems to be wrongly warning about visibility attributes # in some situations: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80947 # Let's just disable the warning for now. check_enable_cxx_flag(-Wno-attributes) endif() endif() # cmake-format: off if(MYX_CMAKE_LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE" AND MYX_CMAKE_LSB_CODENAME STREQUAL "smolensk" AND MYX_CMAKE_LSB_RELEASE_VERSION STREQUAL "1.5") # cmake-format: on myx_cmake_set_cxx_standard(11) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k") myx_cmake_set_cxx_standard(14) check_enable_debug_cxx_flag(-Wno-invalid-offsetof) list(APPEND CMAKE_LIBRARY_PATH "/usr/lib/e2k-linux-gnu") else() myx_cmake_set_cxx_standard(17) # -Wshadow gives a lot of false positives with GCC 4.7.2 in Astra Linux 1.5 if(CMAKE_CXX_COMPILER_IS_GCC) check_enable_debug_cxx_flag(-Wshadow) endif() endif() # cmake-format: off # Set the cache variables. set(MYX_CMAKE_DETECTED_CXX_FLAGS "${_MYX_CMAKE_DETECTED_CXX_FLAGS}" CACHE INTERNAL "") set(MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG "${_MYX_CMAKE_DETECTED_CXX_FLAGS_DEBUG}" CACHE INTERNAL "") set(MYX_CMAKE_CXX_FLAGS_AUTODETECTION_DONE YES CACHE INTERNAL "") # cmake-format: on endif()