| # Detect the langauge standards supported by the current compilers. | |
| # | |
| # Usage: detect_supported_cxx_standards(<var_prefix> <lang> <standards>) | |
| # | |
| # - var_prefix: Used to name result variables, | |
| # e.g. ${var_prefix}_${lang}_XX_SUPPORTED will be TRUE or FALSE. Defined for | |
| # each XX in ${standards}. | |
| # - lang: The language to test: C, CXX, or CUDA. | |
| # - standards: List of any standard versions. | |
| # | |
| # Example: detect_supported_cxx_standards(PROJ CXX 11 14 17) | |
| # - Sets the following variables in the parent scope to TRUE or FALSE: | |
| # - PROJ_CXX_11_SUPPORTED | |
| # - PROJ_CXX_14_SUPPORTED | |
| # - PROJ_CXX_17_SUPPORTED | |
| # | |
| function(detect_supported_standards prefix lang) | |
| string(TOLOWER "${lang}_std" feature_prefix) | |
| foreach(standard IN LISTS ARGN) | |
| set(var_name "${prefix}_${lang}_${standard}_SUPPORTED") | |
| if ("${feature_prefix}_${standard}" IN_LIST CMAKE_${lang}_COMPILE_FEATURES) | |
| set(${var_name} TRUE) | |
| else() | |
| set(${var_name} FALSE) | |
| endif() | |
| if (standard EQUAL 17 AND | |
| (lang STREQUAL "CXX" OR lang STREQUAL "CUDA") AND | |
| ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND | |
| CMAKE_CXX_COMPILER_VERSION VERSION_LESS 7) OR | |
| (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND | |
| CMAKE_CXX_COMPILER_VERSION VERSION_LESS 8))) | |
| # Special cases: | |
| # gcc < 7 and clang < 8 don't fully support C++17. | |
| # They accept the flag and have partial support, but nvcc will refuse | |
| # to enable it and falls back to the default dialect for the current | |
| # CXX compiler version. This breaks our CI. | |
| # CMake's COMPILE_FEATURES var reports that these compilers support C++17, | |
| # but we can't rely on it, so manually disable the dialect in these cases. | |
| set(${var_name} FALSE) | |
| endif() | |
| message(STATUS "Testing ${lang}${standard} Support: ${${var_name}}") | |
| set(${var_name} ${${var_name}} PARENT_SCOPE) | |
| endforeach() | |
| endfunction() | |