1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
# Copyright (C) 2013-2020 Daniel Scharrer
#
# This software is provided 'as-is', without any express or implied
# warranty. In no event will the author(s) be held liable for any damages
# arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose,
# including commercial applications, and to alter it and redistribute it
# freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not
# claim that you wrote the original software. If you use this software
# in a product, an acknowledgment in the product documentation would be
# appreciated but is not required.
# 2. Altered source versions must be plainly marked as such, and must not be
# misrepresented as being the original software.
# 3. This notice may not be removed or altered from any source distribution.
include(CheckCXXSourceCompiles)
include(CompileCheck)
set(CXX_VERSION 2003)
get_filename_component(CXX_CHECK_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(CXX_CHECK_DIR "${CXX_CHECK_DIR}/check")
function(enable_cxx_version version)
set(versions 17 14 11)
if(MSVC)
if(NOT version LESS 2011 AND NOT MSVC_VERSION LESS 1600)
set(CXX_VERSION 2011)
if(NOT version LESS 2017 AND NOT MSVC_VERSION LESS 1911)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++17")
set(CXX_VERSION 2017)
elseif(NOT version LESS 2014 AND NOT MSVC_VERSION LESS 1910)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /std:c++14")
set(CXX_VERSION 2014)
elseif(NOT version LESS 2014 AND NOT MSVC_VERSION LESS 1900)
# Only introduced with update 3 of MSVC 2015
add_cxxflag("/std:c++14")
if(FLAG_FOUND)
set(CXX_VERSION 2014)
endif()
endif()
endif()
else()
set(FLAG_FOUND 0)
foreach(ver IN LISTS versions)
if(NOT version LESS 20${ver} AND NOT FLAG_FOUND)
add_cxxflag("-std=c++${ver}")
if(FLAG_FOUND)
set(CXX_VERSION 20${ver})
break()
endif()
endif()
endforeach()
if(NOT FLAG_FOUND)
# Check if the compiler supports the -std flag at all
# Don't actually use the flag to allow for compiler extensions a la -sdt=gnu++03
check_compiler_flag(FLAG_FOUND "-std=c++03")
if(NOT FLAG_FOUND)
check_compiler_flag(FLAG_FOUND "-std=c++98")
endif()
endif()
if(NOT FLAG_FOUND)
# Compiler does not support he -std flag, assume the highest supported C++ version is available
# by default or can be enabled by CMake and rely on tests for individual features.
foreach(ver IN LISTS versions)
if(NOT version LESS 20${ver})
set(CXX_VERSION 20${ver})
break()
endif()
endforeach()
endif()
if(SET_WARNING_FLAGS AND NOT CXX_VERSION LESS 2011)
add_cxxflag("-pedantic")
endif()
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}" PARENT_SCOPE)
set(CXX_VERSION ${CXX_VERSION} PARENT_SCOPE)
# Tell CMake about our desired C++ version so that it doesn't override our value with a lower version.
# We check -std ourselves first because
# - This feature is new in CMake 3.1
# - Not all CMake versions know how to check for all C++ versions
# - CMake doesn't tell us what versions are available
if(NOT CMAKE_VERSION VERSION_LESS 3.12)
set(max_cxx_standard 20)
elseif(NOT CMAKE_VERSION VERSION_LESS 3.8)
set(max_cxx_standard 17)
else()
set(max_cxx_standard 14)
endif()
foreach(ver IN LISTS versions)
if(NOT CXX_VERSION LESS 20${ver} AND NOT max_cxx_standard LESS ver)
set(CMAKE_CXX_STANDARD ${ver} PARENT_SCOPE)
set(CMAKE_CXX_STANDARD_REQUIRED OFF PARENT_SCOPE)
set(CMAKE_CXX_EXTENSIONS OFF PARENT_SCOPE)
break()
endif()
endforeach()
endfunction(enable_cxx_version)
function(check_cxx version feature resultvar)
set(result)
if(NOT CXX_VERSION LESS 20${version} OR (ARGC GREATER 3 AND ARGV3 STREQUAL "ALWAYS"))
if(MSVC AND ARGC GREATER 3)
if(NOT MSVC_VERSION LESS ARGV3)
set(result 1)
endif()
else()
string(REGEX REPLACE "[^a-zA-Z0-9_][^a-zA-Z0-9_]*" "-" check "${feature}")
string(REGEX REPLACE "^--*" "" check "${check}")
string(REGEX REPLACE "--*$" "" check "${check}")
set(file "${CXX_CHECK_DIR}/cxx${version}-${check}.cpp")
set(old_CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(old_CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
strip_warning_flags(CMAKE_CXX_FLAGS)
strip_warning_flags(CMAKE_EXE_LINKER_FLAGS)
check_compile(result "${file}" "${feature}" "C++${version} feature")
set(CMAKE_CXX_FLAGS "${old_CMAKE_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${old_CMAKE_EXE_LINKER_FLAGS}")
endif()
endif()
if(NOT DEFINED result OR result STREQUAL "")
set(${resultvar} OFF PARENT_SCOPE)
else()
set(${resultvar} ON PARENT_SCOPE)
endif()
endfunction()
macro(check_cxx11 feature resultvar)
check_cxx(11 ${ARGV})
endmacro()
macro(check_cxx14 feature resultvar)
check_cxx(14 ${ARGV})
endmacro()
macro(check_cxx17 feature resultvar)
check_cxx(17 ${ARGV})
endmacro()
|