Index: kde-modules/KDECompilerSettings.cmake =================================================================== --- kde-modules/KDECompilerSettings.cmake +++ kde-modules/KDECompilerSettings.cmake @@ -186,6 +186,8 @@ # Language and toolchain features ############################################################ +include(ECMAddCompilerFlag) + # Pick sensible versions of the C and C++ standards. # Note that MSVC does not have equivalent flags; the features are either # supported or they are not. @@ -369,20 +371,12 @@ # Make some warnings errors set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror=return-type") endif() -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR - (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)) - # -Wvla: use of variable-length arrays (an extension to C++) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wvla") -endif() -if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR - (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)) - include(CheckCXXCompilerFlag) - check_cxx_compiler_flag(-Wdate-time HAVE_DATE_TIME) - if (HAVE_DATE_TIME) - # -Wdate-time: warn if we use __DATE__ or __TIME__ (we want to be able to reproduce the exact same binary) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wdate-time") - endif() -endif() +ecm_add_cxx_compiler_flags_conditionally(FLAGS -Wvla + CONDITION CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR + (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)) +ecm_add_cxx_compiler_flags_conditionally(FLAGS -Wdate-time + CONDITION (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) OR + (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5)) if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0") @@ -492,12 +486,12 @@ set (CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--export-all-symbols") endif() -if (CMAKE_GENERATOR STREQUAL "Ninja" AND - ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR - (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5))) +if (CMAKE_GENERATOR STREQUAL "Ninja") # Force colored warnings in Ninja's output, if the compiler has -fdiagnostics-color support. # Rationale in https://github.com/ninja-build/ninja/issues/814 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fdiagnostics-color=always") + ecm_add_cxx_compiler_flags_conditionally(FLAGS -fdiagnostics-color=always + CONDITION ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) OR + (CMAKE_CXX_COMPILER_ID MATCHES "Clang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.5))) endif() include("${ECM_MODULE_DIR}/ECMEnableSanitizers.cmake") Index: kde-modules/KDEFrameworkCompilerSettings.cmake =================================================================== --- kde-modules/KDEFrameworkCompilerSettings.cmake +++ kde-modules/KDEFrameworkCompilerSettings.cmake @@ -61,18 +61,10 @@ add_definitions(-DQT_STRICT_ITERATORS) endif() -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pedantic") -endif() +ecm_add_cxx_compiler_flags_conditionally(FLAGS -pedantic + CONDITION CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") -if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant" ) - endif() -endif() +ecm_add_cxx_compiler_flags_conditionally(FLAGS -Wzero-as-null-pointer-constant + CONDITION CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0") -if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS "5.0.0") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wzero-as-null-pointer-constant" ) - endif() -endif() +ecm_add_cxx_compiler_flags_conditionally(FLAGS -Wzero-as-null-pointer-constant CONDITION CMAKE_CXX_COMPILER_ID MATCHES "Clang") Index: modules/ECMAddCompilerFlag.cmake =================================================================== --- /dev/null +++ modules/ECMAddCompilerFlag.cmake @@ -0,0 +1,106 @@ +#============================================================================= +# Copyright 2018 René J.V. Bertin +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +include(CMakeParseArguments) +include(CheckCXXCompilerFlag) +include(CheckCCompilerFlag) + +# ECM_ADD_CXX_COMPILER_FLAGS_CONDITIONALLY(FLAGS +# [CONDITION ] +# ) +# add or to CMAKE_CXX_FLAGS if the compiler supports them. +# Support is determined by the CONDITION expression if provided or by +# querying the compiler directly otherwise. The compiler is also queried +# when using a Clang C++ compiler on APPLE. +# examples: +# Check +# ecm_add_cxx_compiler_flags_conditionally(FLAGS -a -b -c CONDITION CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang") +# ecm_add_cxx_compiler_flags_conditionally(FLAGS -d -e -f) +# +# C-language equivalent: +# ECM_ADD_C_COMPILER_FLAGS_CONDITIONALLY(FLAGS +# [CONDITION ] +# ) + + +function (ECM_ADD_CXX_COMPILER_FLAGS_CONDITIONALLY) + set(_OPTIONS_ARGS) + set(_ONE_VALUE_ARGS) + set(_MULTI_VALUE_ARGS FLAGS CONDITION) + + cmake_parse_arguments(EASCXXFLAGS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} ) + if(NOT EASCXXFLAGS_FLAGS) + message( FATAL_ERROR "ecm_add_cxx_compiler_flags_conditionally: 'FLAGS' is a required argument." ) + endif() + # if the user provided supported_if conditions, evaluate them now: + if (NOT EASCXXFLAGS_CONDITION OR (${EASCXXFLAGS_CONDITION})) + # without conditions, or with Clang on APPLE we'll need to ask the compiler directly. + # (Clang on APPLE needs verification because of Apple's llvm versions which cannot be + # (matched easily to stock llvm versions. + if(NOT EASCXXFLAGS_CONDITION OR (APPLE AND CMAKE_CXX_COMPILER_ID MATCHES "Clang")) + # one flag at a time: + foreach(flag IN ITEMS ${EASCXXFLAGS_FLAGS}) + # use a standardised and informative cached test variable + set(HASFLAG "${CMAKE_CXX_COMPILER_ID}++_ACCEPTS${flag}") + check_cxx_compiler_flag(${flag} ${HASFLAG}) + if ({${HASFLAG}}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}" PARENT_SCOPE) + endif() + endforeach() + else() + # all flags can be appended at once + string(REPLACE ";" " " FLAGS "${EASCXXFLAGS_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAGS}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (ECM_ADD_C_COMPILER_FLAGS_CONDITIONALLY) + set(_OPTIONS_ARGS) + set(_ONE_VALUE_ARGS) + set(_MULTI_VALUE_ARGS FLAGS CONDITION) + + cmake_parse_arguments(EASCFLAGS "${_OPTIONS_ARGS}" "${_ONE_VALUE_ARGS}" "${_MULTI_VALUE_ARGS}" ${ARGN} ) + if(NOT EASCFLAGS_FLAGS) + message( FATAL_ERROR "ecm_add_c_compiler_flags_conditionally: 'FLAGS' is a required argument." ) + endif() + if (NOT EASCFLAGS_CONDITION OR (${EASCFLAGS_CONDITION})) + if(NOT EASCFLAGS_CONDITION OR (APPLE AND CMAKE_C_COMPILER_ID MATCHES "Clang")) + # one flag at a time: + foreach(flag IN ITEMS ${EASCFLAGS_FLAGS}) + set(HASFLAG "${CMAKE_C_COMPILER_ID}_ACCEPTS${flag}") + check_c_compiler_flag(${flag} ${HASFLAG}) + if ({${HASFLAG}}) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${flag}" PARENT_SCOPE) + endif() + endforeach() + else() + string(REPLACE ";" " " FLAGS "${EASCFLAGS_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${FLAGS}" PARENT_SCOPE) + endif() + endif() +endfunction() +