From e4ec257b1121900b3e04fb399f066c49c74e6d75 Mon Sep 17 00:00:00 2001 From: Andrey Astafyev Date: Sat, 12 Jun 2021 14:07:59 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B?= =?UTF-8?q?=20=D1=81=20=D1=84=D0=BB=D0=B0=D0=B3=D0=B0=D0=BC=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMLibBuildTypes.cmake | 14 ++- CMLibCompilerFlags.cmake | 219 ++++++++++++++++++++++++--------------- 2 files changed, 146 insertions(+), 87 deletions(-) diff --git a/CMLibBuildTypes.cmake b/CMLibBuildTypes.cmake index 47f83ef..1c14b42 100644 --- a/CMLibBuildTypes.cmake +++ b/CMLibBuildTypes.cmake @@ -1,5 +1,7 @@ cmake_policy(SET CMP0057 NEW) +option(CMLIB_ENABLE_WARNING_FLAGS "Enable autodetected warning flags" ON) + # Добавление конфигурации для профилирования if(CMAKE_CONFIGURATION_TYPES) if(NOT "Profile" IN_LIST CMAKE_CONFIGURATION_TYPES) @@ -35,7 +37,8 @@ if(CMAKE_BUILD_TYPE STREQUAL Profile) CACHE STRING "" FORCE) set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}" CACHE STRING "" FORCE) - set(CMAKE_STATIC_LINKER_FLAGS_PROFILE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE}" CACHE STRING "" FORCE) + set(CMAKE_STATIC_LINKER_FLAGS_PROFILE "${CMAKE_STATIC_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}" + CACHE STRING "" FORCE) set(CMAKE_MODULE_LINKER_FLAGS_PROFILE "${CMAKE_MODULE_LINKER_FLAGS_RELEASE} ${_gcc_profile_flags}" CACHE STRING "" FORCE) elseif(CMAKE_CXX_COMPILER_IS_Intel) @@ -53,12 +56,19 @@ elseif(CMAKE_BUILD_TYPE STREQUAL Debug) set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} ${_gcc_debug_flags}" CACHE STRING "" FORCE) string(REPLACE " ${_gcc_debug_flags}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${_gcc_debug_flags}" CACHE STRING "" FORCE) + if(CMLIB_ENABLE_WARNING_FLAGS) + set(CMAKE_CXX_FLAGS_DEBUG + "${CMAKE_CXX_FLAGS_DEBUG} ${CMLIB_DETECTED_CXX_FLAGS_DEBUG} ${_gcc_debug_flags}" CACHE STRING "" + FORCE) + else() + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${_gcc_debug_flags}" CACHE STRING "" FORCE) + endif() endif() set(CMAKE_VERBOSE_MAKEFILE ON CACHE BOOL "Enable generation of verbose build scripts." FORCE) set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "Enable generation of compile_commands.json." FORCE) set(DEBUG 1) elseif(CMAKE_BUILD_TYPE STREQUAL Release) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMLIB_DETECTED_CXX_FLAGS}" CACHE STRING "" FORCE) set(RELEASE 1) elseif(CMAKE_BUILD_TYPE STREQUAL None) # Режим None используется для статического анализа кода diff --git a/CMLibCompilerFlags.cmake b/CMLibCompilerFlags.cmake index 91d8eb9..9023444 100644 --- a/CMLibCompilerFlags.cmake +++ b/CMLibCompilerFlags.cmake @@ -1,7 +1,5 @@ # based on https://github.com/bluescarni/yacma -option(CMLIB_WARNING_FLAGS "Enable warning flags" ON) - include(CheckCXXCompilerFlag) macro(CHECK_ENABLE_CXX_FLAG flag) @@ -10,8 +8,8 @@ macro(CHECK_ENABLE_CXX_FLAG flag) unset(CMAKE_REQUIRED_QUIET) if(CHECK_CXX_FLAG) - message(STATUS "'${flag}': flag is enabled.") - add_compile_options("${flag}") + message(STATUS "'${flag}': flag is supported.") + string(CONCAT _CMLIB_DETECTED_CXX_FLAGS "${_CMLIB_DETECTED_CXX_FLAGS} ${flag}") else() message(STATUS "'${flag}': flag is NOT supported.") endif() @@ -19,6 +17,21 @@ macro(CHECK_ENABLE_CXX_FLAG flag) unset(CHECK_CXX_FLAG CACHE) endmacro() +macro(CHECK_ENABLE_DEBUG_CXX_FLAG flag) + set(CMAKE_REQUIRED_QUIET TRUE) + check_cxx_compiler_flag("${flag}" CHECK_CXX_FLAG_DEBUG) + unset(CMAKE_REQUIRED_QUIET) + + if(CHECK_CXX_FLAG_DEBUG) + message(STATUS "'${flag}': debug flag is supported.") + string(CONCAT _CMLIB_DETECTED_CXX_FLAGS_DEBUG "${_CMLIB_DETECTED_CXX_FLAGS_DEBUG} ${flag}") + else() + message(STATUS "'${flag}': debug flag is NOT supported.") + endif() + # NOTE: check_cxx_compiler stores variables in the cache. + unset(CHECK_CXX_FLAG_DEBUG CACHE) +endmacro() + function(cmlib_set_cxx_standard version) # Выбор стандарта по умолчанию (можно переопределить в проекте) set(CMAKE_CXX_STANDARD_REQUIRED YES PARENT_SCOPE) @@ -61,106 +74,142 @@ function(cmlib_set_cxx_standard version) endif() endfunction() -# cmake-format: off -if(LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE" AND - LSB_CODENAME STREQUAL "smolensk" AND - LSB_RELEASE STREQUAL "1.5") -# cmake-format: on - cmlib_set_cxx_standard(11) +if(NOT CMLIB_CXX_FLAGS_AUTODETECTION_DONE) + set(_CMLIB_DETECTED_CXX_FLAGS "") + set(_CMLIB_DETECTED_CXX_FLAGS_DEBUG "") - set(_CMAKE_TOOLCHAIN_PREFIX "x86_64-linux-gnu-" CACHE INTERNAL "" FORCE) - set(_CMAKE_TOOLCHAIN_SUFFIX "-4.7" CACHE INTERNAL "" FORCE) - set(_CMAKE_TOOLCHAIN_LOCATION "/usr/bin" CACHE INTERNAL "" FORCE) -else() - cmlib_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_cxx_flag(-Wshadow) + # Configuration bits specific for clang. + if(CMAKE_CXX_COMPILER_IS_CLANG) + # 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) endif() -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) - if(CMLIB_WARNING_FLAGS AND CMAKE_BUILD_TYPE STREQUAL "Debug") - check_enable_cxx_flag(-Wall) - check_enable_cxx_flag(-Wextra) - check_enable_cxx_flag(-Wnon-virtual-dtor) - check_enable_cxx_flag(-Wnoexcept) - check_enable_cxx_flag(-Wlogical-op) - check_enable_cxx_flag(-Wconversion) - check_enable_cxx_flag(-Wdeprecated) + # 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_cxx_flag(-Wold-style-cast) - check_enable_cxx_flag(-Wdisabled-optimization) + 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_cxx_flag(-ftemplate-backtrace-limit=0) - check_enable_cxx_flag(-fstack-protector-all) + check_enable_debug_cxx_flag(-ftemplate-backtrace-limit=0) + check_enable_debug_cxx_flag(-fstack-protector-all) # A few suggestion flags. - check_enable_cxx_flag(-Wsuggest-attribute=pure) - check_enable_cxx_flag(-Wsuggest-attribute=const) - check_enable_cxx_flag(-Wsuggest-attribute=noreturn) - check_enable_cxx_flag(-Wsuggest-attribute=format) + 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_cxx_flag(-Wodr) - check_enable_cxx_flag(-Wsuggest-final-types) - check_enable_cxx_flag(-Wsuggest-final-methods) - check_enable_cxx_flag(-Wsuggest-override) + 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_cxx_flag(-Wshift-negative-value) - check_enable_cxx_flag(-Wshift-overflow=2) - check_enable_cxx_flag(-Wduplicated-cond) - check_enable_cxx_flag(-Wnull-dereference) + 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_cxx_flag(-Wrestrict) - check_enable_cxx_flag(-Waligned-new) + 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_cxx_flag(-Wcast-align=strict) + 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_cxx_flag(-fdiagnostics-show-option) + check_enable_debug_cxx_flag(-fdiagnostics-show-option) - check_enable_cxx_flag(-pedantic) - check_enable_cxx_flag(-Wcast-align) - check_enable_cxx_flag(-Wcast-qual) - check_enable_cxx_flag(-Wctor-dtor-privacy) - check_enable_cxx_flag(-Wdisabled-optimization) - check_enable_cxx_flag(-Wformat=2) - check_enable_cxx_flag(-Winit-self) - check_enable_cxx_flag(-Wmissing-include-dirs) - check_enable_cxx_flag(-Woverloaded-virtual) - check_enable_cxx_flag(-Wredundant-decls) - check_enable_cxx_flag(-Wsign-promo) - check_enable_cxx_flag(-Wstrict-overflow=5) - check_enable_cxx_flag(-Wundef) - check_enable_cxx_flag(-Wno-unused) - check_enable_cxx_flag(-Wno-variadic-macros) - check_enable_cxx_flag(-Wno-parentheses) - check_enable_cxx_flag(-Wstrict-null-sentinel) - check_enable_cxx_flag(-Wshadow-all) + 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() -endif() -if(CMAKE_CXX_COMPILER_IS_GCC) - check_enable_cxx_flag(-fdiagnostics-color=auto) - # 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_cxx_flag(-Wno-maybe-uninitialized) - 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) + if(CMAKE_CXX_COMPILER_IS_GCC) + check_enable_cxx_flag(-fdiagnostics-color=auto) + # 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() -endif() -if(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k") - check_enable_cxx_flag(-Wno-invalid-offsetof) - list(APPEND CMAKE_LIBRARY_PATH "/usr/lib/e2k-linux-gnu") + # cmake-format: off + if(LSB_DISTRIBUTOR_ID STREQUAL "AstraLinuxSE" AND + LSB_CODENAME STREQUAL "smolensk" AND + LSB_RELEASE STREQUAL "1.5") + # cmake-format: on + cmlib_set_cxx_standard(11) + + set(_CMAKE_TOOLCHAIN_PREFIX "x86_64-linux-gnu-" CACHE INTERNAL "" FORCE) + set(_CMAKE_TOOLCHAIN_SUFFIX "-4.7" CACHE INTERNAL "" FORCE) + set(_CMAKE_TOOLCHAIN_LOCATION "/usr/bin" CACHE INTERNAL "" FORCE) + else() + cmlib_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() + + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "e2k") + check_enable_debug_cxx_flag(-Wno-invalid-offsetof) + list(APPEND CMAKE_LIBRARY_PATH "/usr/lib/e2k-linux-gnu") + endif() + + # Set the cache variables. + set(CMLIB_DETECTED_CXX_FLAGS "${_CMLIB_DETECTED_CXX_FLAGS}" CACHE INTERNAL "") + set(CMLIB_DETECTED_CXX_FLAGS_DEBUG "${_CMLIB_DETECTED_CXX_FLAGS_DEBUG}" CACHE INTERNAL "") + set(CMLIB_CXX_FLAGS_AUTODETECTION_DONE YES CACHE INTERNAL "") endif()