MantisBT - CMake
View Issue Details
0015372CMakeCMakepublic2015-01-26 13:102015-07-08 08:57
Kelly Thompson 
Brad King 
normalminoralways
closedfixed 
LinuxRHEL6.6
CMake 3.1.1 
CMake 3.3CMake 3.3 
0015372: CMAKE_Fortran_COMPILER_VERSION is never set but FindOpenMP.cmake depends on it
I am trying to use FindOpenMP.cmake provided by cmake/3.1.1 but it is returning the wrong value for ${OpenMP_Fortran_FLAGS} because the value of CMAKE_Fortran_COMPILER_VERSION is never set by CMake.

When using ifort 15, FindOpenMP returns the deprecated value for older versions of ifort (ver < 15.0.0.20140528).
The missing value for CMAKE_Fortran_COMPILER_VERSION does not appear to depend on the compiler chosen. Running cmake with the CMakeLists.txt provided below shows that the value is blank:

cmake_minimum_required(VERSION 3.1)
project(nofortranver CXX Fortran)
find_package(OpenMP)
message("
CMAKE_Fortran_COMPILER_ID = ${CMAKE_Fortran_COMPILER_ID}
CMAKE_Fortran_COMPILER_VERSION = ${CMAKE_Fortran_COMPILER_VERSION}
")
No tags attached.
patch v1-0001-Fortran-Detect-compiler-version-15372.patch (7,027) 2015-02-03 16:21
https://public.kitware.com/Bug/file/5372/v1-0001-Fortran-Detect-compiler-version-15372.patch
Issue History
2015-01-26 13:10Kelly ThompsonNew Issue
2015-01-26 13:27Brad KingNote Added: 0037818
2015-01-26 20:40Kelly ThompsonNote Added: 0037827
2015-02-03 16:21Brad KingFile Added: v1-0001-Fortran-Detect-compiler-version-15372.patch
2015-02-03 16:23Brad KingNote Added: 0037898
2015-02-19 09:33Brad KingNote Added: 0038000
2015-02-19 09:33Brad KingAssigned To => Brad King
2015-02-19 09:33Brad KingStatusnew => resolved
2015-02-19 09:33Brad KingResolutionopen => fixed
2015-02-19 09:33Brad KingFixed in Version => CMake 3.3
2015-02-19 09:33Brad KingTarget Version => CMake 3.3
2015-07-08 08:57Robert MaynardNote Added: 0039054
2015-07-08 08:57Robert MaynardStatusresolved => closed

Notes
(0037818)
Brad King   
2015-01-26 13:27   
The CMAKE_<LANG>_COMPILER_VERSION documentation:

 http://www.cmake.org/cmake/help/v3.1/variable/CMAKE_LANG_COMPILER_VERSION.html [^]

warns that it may not be set for everything. Currently it is not set for Fortran at all IIRC.

The reason is that Fortran provides no good way to encode the result of preprocessor version macro evaluations as a literal "INFO:..." string in the binary for the compiler id detection to extract. For C and CXX we encode using compile-time expressions like ('0'+d) for each digit in a char[] array. This is not possible in Fortran so another approach needs to be found.
(0037827)
Kelly Thompson   
2015-01-26 20:40   
It looks like CMakeFortranCompilerID.F.in is setup to 'print *' these 'INFO:' strings. While it probably wouldn't work in all cases (e.g. cross compiling), why not attempt to run the binary created from CMakeFortranCompilerID.F.in? For example, in CMakeDetermineCompilerId.cmake:

diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index dfed00e..3aa64fb 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -413,8 +413,17 @@ function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
     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_]+\\[[^]]*\\]")
+ if( lang MATCHES Fortran )
+ execute_process(
+ COMMAND ${file}
+ OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_STRINGS
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+ endif()
+ if( NOT CMAKE_${lang}_COMPILER_ID_STRINGS MATCHES "INFO:compiler" )
+ file(STRINGS ${file}
+ CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
+ endif()
     set(COMPILER_ID_TWICE)

Along with these changes in CMakeFortranCompilerId.F.in

--- a/Modules/CMakeFortranCompilerId.F.in
+++ b/Modules/CMakeFortranCompilerId.F.in
@@ -3,7 +3,55 @@
 ! Identify the compiler
 #endif
 #if defined(__INTEL_COMPILER) || defined(__ICC)
- PRINT *, 'INFO:compiler[Intel]'
+
+ character(len=10) :: str_compiler_major
+ character(len=10) :: str_compiler_minor
+ character(len=10) :: str_compiler_patch
+ character(len=10) :: str_compiler_tweak
+ character(len=40) :: str_compiler_version
+ integer :: compiler_major
+ integer :: compiler_minor
+ integer :: compiler_patch
+ integer :: compiler_tweak
+
+ compiler_major = __INTEL_COMPILER/100
+ compiler_minor = mod(__INTEL_COMPILER/10,10)
+# if defined(__INTEL_COMPILER_UPDATE)
+ compiler_patch = __INTEL_COMPILER_UPDATE
+#else
+ compiler_patch = mod(__INTEL_COMPILER,10)
+#endif
+# if defined(__INTEL_COMPILER_BUILD_DATE)
+ compiler_tweak = __INTEL_COMPILER_BUILD_DATE
+# endif
+
+ write( str_compiler_major, "(I10)") compiler_major
+ write( str_compiler_minor, "(I10)") compiler_minor
+ write( str_compiler_patch, "(I10)") compiler_patch
+ write( str_compiler_tweak, "(I10)") compiler_tweak
+ str_compiler_major = adjustl(str_compiler_major)
+ str_compiler_minor = adjustl(str_compiler_minor)
+ str_compiler_patch = adjustl(str_compiler_patch)
+ str_compiler_tweak = adjustl(str_compiler_tweak)
+ str_compiler_version = trim(str_compiler_major) // '.'
+ & // trim(str_compiler_minor) // '.'
+ & // trim(str_compiler_patch) // '.'
+ & // trim(str_compiler_tweak)
+
+ print *, 'INFO:compiler[Intel]'
+ print *, 'INFO:compiler_version[' ,
+ & trim( adjustl(str_compiler_version)) , ']'
+
 # if defined(_MSC_VER)
         PRINT *, 'INFO:simulate[MSVC]'
 # if _MSC_VER >= 1800
(0037898)
Brad King   
2015-02-03 16:23   
I came up with an approach to encode the Fortran compiler version one digit at a time, and then compose the digits in CMake code. Please try

 v1-0001-Fortran-Detect-compiler-version-15372.patch

Currently I only added the mapping for GNU Fortran. See the change to "Modules/CMakeFortranCompilerId.F.in":

+# 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

This needs to be done for other compiler vendors too. For vendors that encode their decimal digits in hexadecimal digits, we need to use HEX() instead of DEC().
(0038000)
Brad King   
2015-02-19 09:33   
Re 0015372:0037898: I've implemented this approach:

 Fortran: Add infrastructure to detect compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=e6ebc814 [^]

 Fortran: Detect Intel compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=2e09c423 [^]

 Fortran: Detect SunPro compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=aa77b631 [^]

 Fortran: Detect PathScale compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=49562a77 [^]

 Fortran: Detect GNU compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=8c8b77a5 [^]

 Fortran: Detect XL and VisualAge compiler versions
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=302d47b1 [^]

 Fortran: Detect PGI compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=0033faac [^]

 Fortran: Detect G95 compiler version
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=c6e1f464 [^]

 Fortran: Test that CMAKE_Fortran_COMPILER_VERSION is set
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=f611406f [^]

 Help: Add notes for topic 'compiler-version-Fortran'
 http://cmake.org/gitweb?p=cmake.git;a=commitdiff;h=4cf3589e [^]
(0039054)
Robert Maynard   
2015-07-08 08:57   
Closing resolved issues that have not been updated in more than 4 months.