From ddec418a8f27e62ae9f37cd03d28a42eeaa1527f Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 5 Jun 2014 13:16:56 +0200 Subject: Features: Add compiler version support to WriteCompilerDetectionHeader. --- Modules/WriteCompilerDetectionHeader.cmake | 51 +++++++++++++++++++++- .../WriteCompilerDetectionHeader/CMakeLists.txt | 7 +++ Tests/Module/WriteCompilerDetectionHeader/main.cpp | 12 +++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index 3f8d835..561a558 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -52,7 +52,15 @@ # Feature Test Macros # =================== # -# For each compiler, a preprocessor test of the compiler version is generated +# For each compiler, a preprocessor macro is generated matching +# ``_COMPILER_IS_`` which has the content either ``0`` +# or ``1``, depending on the compiler in use. Preprocessor macros for +# compiler version components are generated matching +# ``_COMPILER_VERSION_MAJOR`` ``_COMPILER_VERSION_MINOR`` +# and ``_COMPILER_VERSION_PATCH`` containing decimal values +# for the corresponding compiler version components, if defined. +# +# A preprocessor test is generated based on the compiler version # denoting whether each feature is enabled. A preprocessor macro # matching ``_COMPILER_``, where ```` is the # upper-case ```` name, is generated to contain the value @@ -166,6 +174,8 @@ function(_load_compiler_variables CompilerId lang) foreach(feature ${ARGN}) set(_cmake_feature_test_${CompilerId}_${feature} ${_cmake_feature_test_${feature}} PARENT_SCOPE) endforeach() + include("${CMAKE_ROOT}/Modules/Compiler/${CompilerId}-DetermineCompiler.cmake" OPTIONAL) + set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE) endfunction() function(write_compiler_detection_header @@ -210,11 +220,20 @@ function(write_compiler_detection_header GNU Clang ) + + set(_hex_compilers ADSP Borland Embarcadero SunPro) + foreach(_comp ${_WCD_COMPILERS}) list(FIND compilers ${_comp} idx) if (idx EQUAL -1) message(FATAL_ERROR "Unsupported compiler ${_comp}.") endif() + if (NOT _need_hex_conversion) + list(FIND _hex_compilers ${_comp} idx) + if (NOT idx EQUAL -1) + set(_need_hex_conversion TRUE) + endif() + endif() endforeach() set(file_content " @@ -228,6 +247,21 @@ function(write_compiler_detection_header set(file_content "${file_content}\n${_WCD_PROLOG}\n") endif() + if (_need_hex_conversion) + set(file_content "${file_content} +#define ${prefix_arg}_DEC(X) (X) +#define ${prefix_arg}_HEX(X) ( \\ + ((X)>>28 & 0xF) * 10000000 + \\ + ((X)>>24 & 0xF) * 1000000 + \\ + ((X)>>20 & 0xF) * 100000 + \\ + ((X)>>16 & 0xF) * 10000 + \\ + ((X)>>12 & 0xF) * 1000 + \\ + ((X)>>8 & 0xF) * 100 + \\ + ((X)>>4 & 0xF) * 10 + \\ + ((X) & 0xF) \\ + )\n") + endif() + foreach(feature ${_WCD_FEATURES}) if (feature MATCHES "^cxx_") list(APPEND _langs CXX) @@ -271,6 +305,21 @@ function(write_compiler_detection_header # if !(${_cmake_oldestSupported_${compiler}}) # error Unsupported compiler version # endif\n") + + set(PREFIX ${prefix_arg}_) + if (_need_hex_conversion) + set(MACRO_DEC ${prefix_arg}_DEC) + set(MACRO_HEX ${prefix_arg}_HEX) + else() + set(MACRO_DEC) + set(MACRO_HEX) + endif() + string(CONFIGURE "${_compiler_id_version_compute_${compiler}}" VERSION_BLOCK @ONLY) + set(file_content "${file_content}${VERSION_BLOCK}\n") + set(PREFIX) + set(MACRO_DEC) + set(MACRO_HEX) + set(pp_if "elif") foreach(feature ${${_lang}_features}) string(TOUPPER ${feature} feature_upper) diff --git a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt index ab0ebc3..645cc65 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt +++ b/Tests/Module/WriteCompilerDetectionHeader/CMakeLists.txt @@ -35,6 +35,10 @@ if (NOT CMAKE_CXX_COMPILE_FEATURES AND NOT CMAKE_C_COMPILE_FEATURES) return() endif() +string(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" COMPILER_VERSION_MAJOR "${CMAKE_CXX_COMPILER_VERSION}") +string(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" COMPILER_VERSION_MINOR "${CMAKE_CXX_COMPILER_VERSION}") +string(REGEX REPLACE "^[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" COMPILER_VERSION_PATCH "${CMAKE_CXX_COMPILER_VERSION}") + macro(set_defines target true_defs false_defs) set(defines) foreach(def ${true_defs}) @@ -46,6 +50,9 @@ macro(set_defines target true_defs false_defs) target_compile_definitions(${target} PRIVATE ${defines} + EXPECTED_COMPILER_VERSION_MAJOR=${COMPILER_VERSION_MAJOR} + EXPECTED_COMPILER_VERSION_MINOR=${COMPILER_VERSION_MINOR} + EXPECTED_COMPILER_VERSION_PATCH=${COMPILER_VERSION_PATCH} ) endmacro() diff --git a/Tests/Module/WriteCompilerDetectionHeader/main.cpp b/Tests/Module/WriteCompilerDetectionHeader/main.cpp index 8b4ea52..b807ad5 100644 --- a/Tests/Module/WriteCompilerDetectionHeader/main.cpp +++ b/Tests/Module/WriteCompilerDetectionHeader/main.cpp @@ -13,6 +13,18 @@ #error cxx_variadic_templates expected availability did not match. #endif +#if !CHECK(VERSION_MAJOR) +#error Compiler major version did not match. +#endif + +#if !CHECK(VERSION_MINOR) +#error Compiler minor version did not match. +#endif + +#if !CHECK(VERSION_PATCH) +#error Compiler patch version did not match. +#endif + int main() { return 0; -- cgit v0.12