#.rst: # FindCXXFeatures # --------------- # # Check which features of the C++ standard the compiler supports # # When found it will set the following variables:: # # CXX11_COMPILER_FLAGS - the compiler flags needed to get C++11 features # CXX14_COMPILER_FLAGS - the compiler flags needed to get C++14 features # # CXXFeatures_auto_FOUND - auto keyword # CXXFeatures_class_override_final_FOUND - override and final keywords for classes and methods # CXXFeatures_constexpr_FOUND - constexpr keyword # CXXFeatures_cstdint_header_FOUND - cstdint header # CXXFeatures_decltype_FOUND - decltype keyword # CXXFeatures_defaulted_functions_FOUND - default keyword for functions # CXXFeatures_delegating_constructors_FOUND - delegating constructors # CXXFeatures_deleted_functions_FOUND - delete keyword for functions # CXXFeatures_func_identifier_FOUND - __func__ preprocessor constant # CXXFeatures_initializer_list_FOUND - initializer list # CXXFeatures_lambda_FOUND - lambdas # CXXFeatures_long_long_FOUND - long long signed & unsigned types # CXXFeatures_nullptr_FOUND - nullptr # CXXFeatures_rvalue_references_FOUND - rvalue references # CXXFeatures_sizeof_member_FOUND - sizeof() non-static members # CXXFeatures_static_assert_FOUND - static_assert() # CXXFeatures_variadic_templates_FOUND - variadic templates #============================================================================= # Copyright 2011-2013 Rolf Eike Beer # Copyright 2012 Andreas Weis # Copyright 2013 Jan Kundrát # Copyright 2016 Jack Poulson # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # - Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # - Redistributions in binary form must reproduce the above copyright notice, # this list of conditions and the following disclaimer in the documentation # and/or other materials provided with the distribution. # # - Neither the name of the owner nor the names of its contributors # may be used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT HOLDER OR CONTRIBUTORS 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. #============================================================================= if(NOT CMAKE_CXX_COMPILER_LOADED) message(FATAL_ERROR "CXXFeatures modules only works if language CXX is enabled") endif() # Check for needed compiler flags include(CheckCXXCompilerFlag) function(test_11_flags FLAG NAME) check_cxx_compiler_flag("${FLAG}" _HAS_${NAME}_FLAG) if(_HAS_${NAME}_FLAG) set(CXX11_COMPILER_FLAGS "${FLAG}" PARENT_SCOPE) endif() endfunction() function(test_14_flags FLAG NAME) check_cxx_compiler_flag("${FLAG}" _HAS_${NAME}_FLAG) if(_HAS_${NAME}_FLAG) set(CXX14_COMPILER_FLAGS "${FLAG}" PARENT_SCOPE) endif() endfunction() if(CMAKE_CXX_COMPILER_ID STREQUAL "XL") test_11_flags("-qlanglvl=extended0x" CXX11) test_14_flags("-qlanglvl=extended1y" CXX14) elseif (CMAKE_CXX_COMPILER_ID MATCHES "(Borland|Watcom)") # No C++11 or C++14 flag for those compilers, but check_cxx_compiler_flag() # can't detect because they either will not always complain (Borland) # or will hang (Watcom). elseif (CMAKE_CXX_COMPILER_ID MATCHES "Cray") test_11_flags("-h std=c++11" CXX11) test_14_flags("-h std=c++14" CXX14) if(NOT CXX14_COMPILER_FLAGS) message(FATAL_ERROR "Could not use -h std=c++14 with Cray C/C++") endif() elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" AND WIN32) # The Intel compiler on Windows may use these flags. test_11_flags("/Qstd=c++11" CXX11) test_14_flags("/Qstd=c++14" CXX14) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") # GCC needs -std=gnu++11 or -std=gnu++14 for the libquadmath literals; # Intel does not test_11_flags("-std=gnu++11" CXX11) test_14_flags("-std=gnu++14" CXX14) if(NOT CXX14_COMPILER_FLAGS) message(FATAL_ERROR "Could not use -std=gnu++14 with GCC") endif() else() test_11_flags("-std=c++11" CXX11) test_14_flags("-std=c++14" CXX14) if(NOT CXX14_COMPILER_FLAGS) message(FATAL_ERROR "Could not use -std=c++14 with unknown compiler") endif() endif() # TODO(poulson): Extend to test C++14 features such as [[deprecated]] function(cxx_check_feature FEATURE_NAME) set(RESULT_VAR "CXXFeatures_${FEATURE_NAME}_FOUND") if(DEFINED ${RESULT_VAR}) return() endif() set(_bindir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${FEATURE_NAME}") set(_SRCFILE_BASE ${CMAKE_CURRENT_LIST_DIR}/FindCXXFeatures/cxx11-${FEATURE_NAME}) set(_LOG_NAME "\"${FEATURE_NAME}\"") message(STATUS "Checking C++ support for ${_LOG_NAME}") set(_SRCFILE "${_SRCFILE_BASE}.cxx") set(_SRCFILE_FAIL_COMPILE "${_SRCFILE_BASE}_fail_compile.cxx") try_compile(${RESULT_VAR} "${_bindir}" "${_SRCFILE}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}" OUTPUT_VARIABLE _SRCFILE_COMPILE_PASS_OUTPUT) if(${RESULT_VAR} AND EXISTS ${_SRCFILE_FAIL_COMPILE}) try_compile(_TMP_RESULT "${_bindir}_fail_compile" "${_SRCFILE_FAIL_COMPILE}" COMPILE_DEFINITIONS "${CXX11_COMPILER_FLAGS}" OUTPUT_VARIABLE _SRCFILE_COMPILE_FAIL_OUTPUT) if(_TMP_RESULT) set(${RESULT_VAR} FALSE) else() set(${RESULT_VAR} TRUE) endif() endif() if(${RESULT_VAR}) message(STATUS "Checking C++ support for ${_LOG_NAME}: works") file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log "Checking C++ support for ${_LOG_NAME} passed.\n" "Compile pass output:\n${_SRCFILE_COMPILE_PASS_OUTPUT}\n" "Compile fail output:\n${_SRCFILE_COMPILE_FAIL_OUTPUT}\n") else() message(STATUS "Checking C++ support for ${_LOG_NAME}: not supported") file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "Checking C++ support for ${_LOG_NAME} failed.\n" "Compile pass output:\n${_SRCFILE_COMPILE_PASS_OUTPUT}\n" "Compile fail output:\n${_SRCFILE_COMPILE_FAIL_OUTPUT}\n") endif() set(${RESULT_VAR} "${${RESULT_VAR}}" CACHE INTERNAL "C++ support for ${_LOG_NAME}") endfunction(cxx_check_feature) set(_CXX_ALL_FEATURES auto class_override_final constexpr cstdint_header decltype defaulted_functions delegating_constructors deleted_functions func_identifier initializer_list lambda long_long nullptr rvalue_references sizeof_member static_assert variadic_templates ) if (CXXFeatures_FIND_COMPONENTS) foreach (_cxx_feature IN LISTS CXXFeatures_FIND_COMPONENTS) list(FIND _CXX_ALL_FEATURES "${_cxx_feature}" _feature_index) if (_feature_index EQUAL -1) message(FATAL_ERROR "Unknown component: '${_cxx_feature}'") endif () endforeach () unset(_feature_index) else () set(CXXFEATURES_FIND_COMPONENTS ${_CXX_ALL_FEATURES}) endif () foreach (_cxx_feature IN LISTS CXXFEATURES_FIND_COMPONENTS) cxx_check_feature(${_cxx_feature} ${FEATURE_NAME}) endforeach (_cxx_feature) include(FindPackageHandleStandardArgs) set(DUMMY_VAR TRUE) find_package_handle_standard_args(CXXFeatures REQUIRED_VARS DUMMY_VAR HANDLE_COMPONENTS) unset(DUMMY_VAR) unset(_CXX_ALL_FEATURES)