From e6ebc814dfa022680038a3855eb1eee56f6015f0 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:24:31 -0500 Subject: Fortran: Add infrastructure to detect compiler version (#15372) Fortran does not offer syntax to compose a string literal at preprocessing time from numeric compuations. Instead encode each digit of each component as a separate INFO string and compose them in CMake code after extraction. Support MAJOR, MINOR, PATCH, and TWEAK components with up to 8 digits each. --- Modules/CMakeDetermineCompilerId.cmake | 41 ++++++++++++++++++++++++++++- Modules/CMakeDetermineFortranCompiler.cmake | 41 +++++++++++++++++++++++++++++ Modules/CMakeFortranCompilerId.F.in | 22 ++++++++++++++++ 3 files changed, 103 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index dfed00e..d22a867 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -409,12 +409,28 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) # Read the compiler identification string from the executable file. set(COMPILER_ID) set(COMPILER_VERSION) + set(COMPILER_VERSION_MAJOR 0) + set(COMPILER_VERSION_MINOR 0) + set(COMPILER_VERSION_PATCH 0) + set(COMPILER_VERSION_TWEAK 0) + set(HAVE_COMPILER_VERSION_MAJOR 0) + set(HAVE_COMPILER_VERSION_MINOR 0) + set(HAVE_COMPILER_VERSION_PATCH 0) + set(HAVE_COMPILER_VERSION_TWEAK 0) + set(DIGIT_VALUE_1 1) + set(DIGIT_VALUE_2 10) + set(DIGIT_VALUE_3 100) + set(DIGIT_VALUE_4 1000) + set(DIGIT_VALUE_5 10000) + set(DIGIT_VALUE_6 100000) + set(DIGIT_VALUE_7 1000000) + set(DIGIT_VALUE_8 10000000) set(PLATFORM_ID) set(ARCHITECTURE_ID) set(SIMULATE_ID) set(SIMULATE_VERSION) file(STRINGS ${file} - CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") + CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 38 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") set(COMPILER_ID_TWICE) foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS}) if("${info}" MATCHES "INFO:compiler\\[([^]\"]*)\\]") @@ -433,6 +449,15 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}") string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}") endif() + foreach(comp MAJOR MINOR PATCH TWEAK) + foreach(digit 1 2 3 4 5 6 7 8 9) + if("${info}" MATCHES "INFO:compiler_version_${comp}_digit_${digit}\\[([0-9])\\]") + set(value ${CMAKE_MATCH_1}) + math(EXPR COMPILER_VERSION_${comp} "${COMPILER_VERSION_${comp}} + ${value} * ${DIGIT_VALUE_${digit}}") + set(HAVE_COMPILER_VERSION_${comp} 1) + endif() + endforeach() + endforeach() if("${info}" MATCHES "INFO:simulate\\[([^]\"]*)\\]") set(SIMULATE_ID "${CMAKE_MATCH_1}") endif() @@ -445,6 +470,20 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file) endif() endforeach() + # Construct compiler version from components if needed. + if(NOT DEFINED COMPILER_VERSION AND HAVE_COMPILER_VERSION_MAJOR) + set(COMPILER_VERSION "${COMPILER_VERSION_MAJOR}") + if(HAVE_COMPILER_VERSION_MINOR) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_MINOR}") + if(HAVE_COMPILER_VERSION_PATCH) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_PATCH}") + if(HAVE_COMPILER_VERSION_TWEAK) + set(COMPILER_VERSION "${COMPILER_VERSION}.${COMPILER_VERSION_TWEAK}") + endif() + endif() + endif() + endif() + # Detect the exact architecture from the PE header. if(WIN32) # The offset to the PE signature is stored at 0x3c. diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake index a4bb86c..3a27127 100644 --- a/Modules/CMakeDetermineFortranCompiler.cmake +++ b/Modules/CMakeDetermineFortranCompiler.cmake @@ -119,6 +119,47 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN) set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V") set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler") + set(_version_info "") + foreach(m MAJOR MINOR PATCH TWEAK) + set(_COMP "_${m}") + set(_version_info "${_version_info} +#if defined(COMPILER_VERSION${_COMP})") + foreach(d 1 2 3 4 5 6 7 8) + set(_version_info "${_version_info} +# undef DEC +# undef HEX +# define DEC(n) DEC_${d}(n) +# define HEX(n) HEX_${d}(n) +# if COMPILER_VERSION${_COMP} == 0 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[0]' +# elif COMPILER_VERSION${_COMP} == 1 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[1]' +# elif COMPILER_VERSION${_COMP} == 2 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[2]' +# elif COMPILER_VERSION${_COMP} == 3 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[3]' +# elif COMPILER_VERSION${_COMP} == 4 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[4]' +# elif COMPILER_VERSION${_COMP} == 5 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[5]' +# elif COMPILER_VERSION${_COMP} == 6 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[6]' +# elif COMPILER_VERSION${_COMP} == 7 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[7]' +# elif COMPILER_VERSION${_COMP} == 8 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[8]' +# elif COMPILER_VERSION${_COMP} == 9 + PRINT *, 'INFO:compiler_version${_COMP}_digit_${d}[9]' +# endif +") + endforeach() + set(_version_info "${_version_info} +#endif") + endforeach() + set(CMAKE_Fortran_COMPILER_ID_VERSION_INFO "${_version_info}") + unset(_version_info) + unset(_COMP) + # Try to identify the compiler. set(CMAKE_Fortran_COMPILER_ID) include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 5349505..955ca85 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -134,4 +134,26 @@ PRINT *, 'INFO:arch[X86]' # endif #endif + +#if 0 +! Encode compiler version digits +#endif +#define DEC_8(n) (((n) / 10000000) % 10) +#define DEC_7(n) (((n) / 1000000) % 10) +#define DEC_6(n) (((n) / 100000) % 10) +#define DEC_5(n) (((n) / 10000) % 10) +#define DEC_4(n) (((n) / 1000) % 10) +#define DEC_3(n) (((n) / 100) % 10) +#define DEC_2(n) (((n) / 10) % 10) +#define DEC_1(n) (((n) ) % 10) +#define HEX_8(n) ((n)>>28 & 0xF) +#define HEX_7(n) ((n)>>24 & 0xF) +#define HEX_6(n) ((n)>>20 & 0xF) +#define HEX_5(n) ((n)>>16 & 0xF) +#define HEX_4(n) ((n)>>12 & 0xF) +#define HEX_3(n) ((n)>>8 & 0xF) +#define HEX_2(n) ((n)>>4 & 0xF) +#define HEX_1(n) ((n) & 0xF) +@CMAKE_Fortran_COMPILER_ID_VERSION_INFO@ + END -- cgit v0.12 From 2e09c4230f601ef5d744a2e43643e214a149ba39 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:26:14 -0500 Subject: Fortran: Detect Intel compiler version Port logic from the "Compiler/Intel-DetermineCompiler" module into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 955ca85..956576d 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -4,6 +4,17 @@ #endif #if defined(__INTEL_COMPILER) || defined(__ICC) PRINT *, 'INFO:compiler[Intel]' +# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100) +# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10) +# if defined(__INTEL_COMPILER_UPDATE) +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE) +# else +# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10) +# endif +# if defined(__INTEL_COMPILER_BUILD_DATE) +# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE) +# endif + # if defined(_MSC_VER) PRINT *, 'INFO:simulate[MSVC]' # if _MSC_VER >= 1800 -- cgit v0.12 From aa77b631d9fc94e7ba69929560d4592e1ab12a04 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:27:22 -0500 Subject: Fortran: Detect SunPro compiler version Port logic from "Compiler/SunPro-*DetermineCompiler" modules into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 956576d..5e8f646 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -33,8 +33,16 @@ PRINT *, 'INFO:simulate_version[013.00]' # endif # endif -#elif defined(__SUNPRO_F90) || defined(__SUNPRO_F95) +#elif defined(__SUNPRO_F95) PRINT *, 'INFO:compiler[SunPro]' +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F95>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F95>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F95 & 0xF) +#elif defined(__SUNPRO_F90) + PRINT *, 'INFO:compiler[SunPro]' +# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_F90>>8) +# define COMPILER_VERSION_MINOR HEX(__SUNPRO_F90>>4 & 0xF) +# define COMPILER_VERSION_PATCH HEX(__SUNPRO_F90 & 0xF) #elif defined(_CRAYFTN) PRINT *, 'INFO:compiler[Cray]' #elif defined(__G95__) -- cgit v0.12 From 49562a77f7223befa21a5b72625dc10f807ce788 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:28:45 -0500 Subject: Fortran: Detect PathScale compiler version Port logic from the "Compiler/PathScale-DetermineCompiler" module into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 5e8f646..fcffaa2 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -49,6 +49,11 @@ PRINT *, 'INFO:compiler[G95]' #elif defined(__PATHSCALE__) PRINT *, 'INFO:compiler[PathScale]' +# define COMPILER_VERSION_MAJOR DEC(__PATHCC__) +# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__) +# if defined(__PATHCC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__) +# endif #elif defined(__ABSOFT__) PRINT *, 'INFO:compiler[Absoft]' #elif defined(__GNUC__) -- cgit v0.12 From 8c8b77a5dede8d1ad3110124b93973db8d879d79 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:29:33 -0500 Subject: Fortran: Detect GNU compiler version Port logic from the "Compiler/GNU-DetermineCompiler" module into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index fcffaa2..14ce395 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -58,6 +58,11 @@ PRINT *, 'INFO:compiler[Absoft]' #elif defined(__GNUC__) PRINT *, 'INFO:compiler[GNU]' +# define COMPILER_VERSION_MAJOR DEC(__GNUC__) +# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__) +# if defined(__GNUC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__) +# endif #elif defined(__IBMC__) # if defined(__COMPILER_VER__) PRINT *, 'INFO:compiler[zOS]' -- cgit v0.12 From 302d47b1fe19fb794800faa548d4cb9a8e89220a Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:30:19 -0500 Subject: Fortran: Detect XL and VisualAge compiler versions Port logic from the "Compiler/XL-*-DetermineCompiler" and "Compiler/VisualAge-*-DetermineCompiler" modules into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 14ce395..4c172a8 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -68,8 +68,14 @@ PRINT *, 'INFO:compiler[zOS]' # elif __IBMC__ >= 800 PRINT *, 'INFO:compiler[XL]' +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) # else PRINT *, 'INFO:compiler[VisualAge]' +# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100) +# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10) +# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10) # endif #elif defined(__PGI) PRINT *, 'INFO:compiler[PGI]' -- cgit v0.12 From 0033faac1d5641c370646e089ca19cd527a8d842 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:31:45 -0500 Subject: Fortran: Detect PGI compiler version Port logic from the "Compiler/PGI-DetermineCompiler" module into "CMakeFortranCompilerId.F.in". --- Modules/CMakeFortranCompilerId.F.in | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 4c172a8..98ec7f3 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -79,6 +79,11 @@ # endif #elif defined(__PGI) PRINT *, 'INFO:compiler[PGI]' +# define COMPILER_VERSION_MAJOR DEC(__PGIC__) +# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__) +# endif #elif defined(_SGI_COMPILER_VERSION) || defined(_COMPILER_VERSION) PRINT *, 'INFO:compiler[MIPSpro]' # if 0 -- cgit v0.12 From c6e1f4647576801b27fbb25652fe3e947564be27 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:32:28 -0500 Subject: Fortran: Detect G95 compiler version The __G95__ and __G95_MINOR__ preprocessor symbols encode the compiler version as decimal digits. --- Modules/CMakeFortranCompilerId.F.in | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Modules/CMakeFortranCompilerId.F.in b/Modules/CMakeFortranCompilerId.F.in index 98ec7f3..2533d3f 100644 --- a/Modules/CMakeFortranCompilerId.F.in +++ b/Modules/CMakeFortranCompilerId.F.in @@ -47,6 +47,8 @@ PRINT *, 'INFO:compiler[Cray]' #elif defined(__G95__) PRINT *, 'INFO:compiler[G95]' +# define COMPILER_VERSION_MAJOR DEC(__G95__) +# define COMPILER_VERSION_MINOR DEC(__G95_MINOR__) #elif defined(__PATHSCALE__) PRINT *, 'INFO:compiler[PathScale]' # define COMPILER_VERSION_MAJOR DEC(__PATHCC__) -- cgit v0.12 From f611406fe9045e2861ccc8a9fd8b9daa39982553 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:37:23 -0500 Subject: Fortran: Test that CMAKE_Fortran_COMPILER_VERSION is set (#15372) Update the CMakeOnly.CompilerIdFortran test to require that the variable is set instead of just warning. We already require it for C and CXX. --- Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt index 3a2bdeb..02e4668 100644 --- a/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt +++ b/Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt @@ -4,19 +4,11 @@ project(CompilerIdFortran Fortran) foreach(v CMAKE_Fortran_COMPILER CMAKE_Fortran_COMPILER_ID - ) - if(${v}) - message(STATUS "${v}=[${${v}}]") - else() - message(SEND_ERROR "${v} not set!") - endif() -endforeach() -foreach(v CMAKE_Fortran_COMPILER_VERSION ) if(${v}) message(STATUS "${v}=[${${v}}]") else() - message(WARNING "${v} not set!") + message(SEND_ERROR "${v} not set!") endif() endforeach() -- cgit v0.12 From 4cf3589ed6b71dbc2bf95bc16d079ef469511538 Mon Sep 17 00:00:00 2001 From: Brad King Date: Tue, 17 Feb 2015 13:38:31 -0500 Subject: Help: Add notes for topic 'compiler-version-Fortran' --- Help/release/dev/compiler-version-Fortran.rst | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 Help/release/dev/compiler-version-Fortran.rst diff --git a/Help/release/dev/compiler-version-Fortran.rst b/Help/release/dev/compiler-version-Fortran.rst new file mode 100644 index 0000000..e10b206 --- /dev/null +++ b/Help/release/dev/compiler-version-Fortran.rst @@ -0,0 +1,6 @@ +compiler-version-Fortran +------------------------ + +* The version of some Fortran compilers is now detected and stored in the + :variable:`CMAKE_Fortran_COMPILER_VERSION _COMPILER_VERSION>` + variable. -- cgit v0.12