diff --git a/CMakeLists.txt b/CMakeLists.txt index a7787910d..879d56ee8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,12 @@ read_version("${CMAKE_CURRENT_SOURCE_DIR}/version.pri" VER_MAJOR VER_MINOR VER_B project(qBittorrent VERSION ${VER_MAJOR}.${VER_MINOR}.${VER_BUGFIX}.${VER_BUILD}) +# check for invalid compiler version/CXX standard as early as possible +include(FunctionQbtCXXCompilerAndModeCheck) +qbt_minimum_cxx_mode_check(14) +message(STATUS "Building in C++${CMAKE_CXX_STANDARD} mode.\n" + "Make sure libtorrent was built with the same C++ mode for ABI compatibility.") + set(PROJECT_VERSION "${VER_MAJOR}.${VER_MINOR}.${VER_BUGFIX}") if (NOT VER_BUILD EQUAL 0) diff --git a/cmake/Modules/FunctionQbtCXXCompilerAndModeCheck.cmake b/cmake/Modules/FunctionQbtCXXCompilerAndModeCheck.cmake new file mode 100644 index 000000000..5e64fc55b --- /dev/null +++ b/cmake/Modules/FunctionQbtCXXCompilerAndModeCheck.cmake @@ -0,0 +1,24 @@ +# Function for ensuring the build does not use a lower than the required minimum C++ mode, _min_std. +# It fails the build if: +# - the compiler does not fully support _min_std +# - the user specified a mode lower than _min_std via the CMAKE_CXX_STANDARD variable +# If both checks are successful, it sets the following variables at the PARENT_SCOPE: +# - CMAKE_CXX_STANDARD with the value _min_std, if it was not already set to a value >= _min_std +# - CMAKE_CXX_STANDARD_REQUIRED with the value ON + +function(qbt_minimum_cxx_mode_check _min_std) + # ensure the compiler fully supports the minimum required C++ mode. + if(NOT CMAKE_CXX${_min_std}_STANDARD__HAS_FULL_SUPPORT) + message(FATAL_ERROR "${PROJECT_NAME} requires a compiler with full C++${_min_std} support") + endif() + + # now we know that the compiler fully supports the minimum required C++ mode, + # but we must still prevent the user or compiler from forcing/defaulting to an insufficient C++ mode + if(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD ${_min_std} PARENT_SCOPE) + elseif((CMAKE_CXX_STANDARD VERSION_LESS ${_min_std}) OR (CMAKE_CXX_STANDARD VERSION_EQUAL 98)) + message(FATAL_ERROR "${PROJECT_NAME} has to be built with at least C++${_min_std} mode.") + endif() + + set(CMAKE_CXX_STANDARD_REQUIRED ON PARENT_SCOPE) +endfunction() diff --git a/cmake/Modules/MacroQbtCompilerSettings.cmake b/cmake/Modules/MacroQbtCompilerSettings.cmake index 851a4471e..22fe3a2cc 100644 --- a/cmake/Modules/MacroQbtCompilerSettings.cmake +++ b/cmake/Modules/MacroQbtCompilerSettings.cmake @@ -24,11 +24,6 @@ macro(qbt_set_compiler_options) #"-Wno-error=sign-conversion -Wno-error=float-equal" ) - # GCC 4.8 has problems with std::array and its initialization - if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU" AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.9) - list(APPEND _GCC_COMMON_CXX_FLAGS "-Wno-error=missing-field-initializers") - endif() - include(CheckCXXCompilerFlag) # check for -pedantic check_cxx_compiler_flag(-pedantic _PEDANTIC_IS_SUPPORTED) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7aa76955c..d9e625e54 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,14 +1,3 @@ -set(CMAKE_CXX_STANDARD_REQUIRED True) - -# If C++14 is available, use it as libtorent ABI depends on 11/14 version -if (cxx_std_14 IN_LIST CMAKE_CXX_COMPILE_FEATURES) - message(STATUS "Building in C++14 mode") - set(CMAKE_CXX_STANDARD "14") -else() - message(STATUS "Building in C++11 mode") - set(CMAKE_CXX_STANDARD "11") -endif() - include(MacroQbtCompilerSettings) qbt_set_compiler_options()