CMakeDetermineFortranCompiler.cmake 10.7 KB
Newer Older
1

2 3 4 5 6 7 8 9 10 11
#=============================================================================
# Copyright 2004-2009 Kitware, Inc.
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
12
# (To distribute this file outside of CMake, substitute the full
13 14
#  License text for the above reference.)

15 16
# determine the compiler to use for Fortran programs
# NOTE, a generator may set CMAKE_Fortran_COMPILER before
Bill Hoffman's avatar
Bill Hoffman committed
17
# loading this file to force a compiler.
18
# use environment variable FC first if defined by user, next use
19
# the cmake variable CMAKE_GENERATOR_FC which can be defined by a generator
Bill Hoffman's avatar
Bill Hoffman committed
20
# as a default compiler
21

22 23 24 25 26
include(${CMAKE_ROOT}/Modules/CMakeDetermineCompiler.cmake)
include(Platform/${CMAKE_SYSTEM_NAME}-Fortran OPTIONAL)
if(NOT CMAKE_Fortran_COMPILER_NAMES)
  set(CMAKE_Fortran_COMPILER_NAMES f95)
endif()
27

28
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
29 30
elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
  set(CMAKE_Fortran_COMPILER_XCODE_TYPE sourcecode.fortran.f90)
31
  _cmake_find_compiler_path(Fortran)
32 33 34
else()
  if(NOT CMAKE_Fortran_COMPILER)
    # prefer the environment variable CC
35
    if(NOT $ENV{FC} STREQUAL "")
36 37 38 39 40 41 42 43
      get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
      if(CMAKE_Fortran_FLAGS_ENV_INIT)
        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
      endif()
      if(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
      else()
        message(FATAL_ERROR "Could not find compiler set in environment variable FC:\n$ENV{FC}.")
      endif()
44
    endif()
45 46 47 48 49 50

    # next try prefer the compiler specified by the generator
    if(CMAKE_GENERATOR_FC)
      if(NOT CMAKE_Fortran_COMPILER_INIT)
        set(CMAKE_Fortran_COMPILER_INIT ${CMAKE_GENERATOR_FC})
      endif()
51
    endif()
52

53
    # finally list compilers to try
54
    if(NOT CMAKE_Fortran_COMPILER_INIT)
55 56
      # Known compilers:
      #  f77/f90/f95: generic compiler names
57
      #  ftn: Cray fortran compiler wrapper
58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
      #  g77: GNU Fortran 77 compiler
      #  gfortran: putative GNU Fortran 95+ compiler (in progress)
      #  fort77: native F77 compiler under HP-UX (and some older Crays)
      #  frt: Fujitsu F77 compiler
      #  pathf90/pathf95/pathf2003: PathScale Fortran compiler
      #  pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers
      #  xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers
      #  lf95: Lahey-Fujitsu F95 compiler
      #  fl32: Microsoft Fortran 77 "PowerStation" compiler
      #  af77: Apogee F77 compiler for Intergraph hardware running CLIX
      #  epcf90: "Edinburgh Portable Compiler" F90
      #  fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha
      #  ifc: Intel Fortran 95 compiler for Linux/x86
      #  efc: Intel Fortran 95 compiler for IA64
      #
      #  The order is 95 or newer compilers first, then 90,
      #  then 77 or older compilers, gnu is always last in the group,
      #  so if you paid for a compiler it is picked by default.
      set(CMAKE_Fortran_COMPILER_LIST
77
        ftn
78 79 80 81 82 83 84 85 86 87 88 89 90
        ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95
        fort gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77
        frt pgf77 xlf fl32 af77 g77 f77
        )

      # Vendor-specific compiler names.
      set(_Fortran_COMPILER_NAMES_GNU       gfortran gfortran-4 g95 g77)
      set(_Fortran_COMPILER_NAMES_Intel     ifort ifc efc)
      set(_Fortran_COMPILER_NAMES_Absoft    af95 af90 af77)
      set(_Fortran_COMPILER_NAMES_PGI       pgf95 pgfortran pgf90 pgf77)
      set(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
      set(_Fortran_COMPILER_NAMES_XL        xlf)
      set(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf)
91
    endif()
92

93
    _cmake_find_compiler(Fortran)
94

95
  else()
96
    _cmake_find_compiler_path(Fortran)
97
  endif()
98
  mark_as_advanced(CMAKE_Fortran_COMPILER)
99

100 101 102
  # Each entry in this list is a set of extra flags to try
  # adding to the compile line to see if it helps produce
  # a valid identification executable.
103 104 105 106
  set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS_FIRST
    # Get verbose output to help distinguish compilers.
    "-v"
    )
107
  set(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS
108 109 110
    # Try compiling to an object file only.
    "-c"

111 112 113
    # Intel on windows does not preprocess by default.
    "-fpp"
    )
114 115 116 117 118
endif()

# Build a small source file to identify the compiler.
if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
  set(CMAKE_Fortran_COMPILER_ID_RUN 1)
119

120 121 122 123
  # Table of per-vendor compiler output regular expressions.
  list(APPEND CMAKE_Fortran_COMPILER_ID_MATCH_VENDORS CCur)
  set(CMAKE_Fortran_COMPILER_ID_MATCH_VENDOR_REGEX_CCur "Concurrent Fortran [0-9]+ Compiler")

124
  # Table of per-vendor compiler id flags with expected output.
125 126 127 128 129 130
  list(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS Compaq)
  set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_Compaq "-what")
  set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_Compaq "Compaq Visual Fortran")
  list(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS NAG) # Numerical Algorithms Group
  set(CMAKE_Fortran_COMPILER_ID_VENDOR_FLAGS_NAG "-V")
  set(CMAKE_Fortran_COMPILER_ID_VENDOR_REGEX_NAG "NAG Fortran Compiler")
131

132 133 134 135 136 137 138 139
  # Match the link line from xcodebuild output of the form
  #  Ld ...
  #      ...
  #      /path/to/cc ...CompilerIdFortran/...
  # to extract the compiler front-end for the language.
  set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_REGEX "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerIdFortran/(\\./)?(CompilerIdFortran.xctest/)?CompilerIdFortran[ \t\n\\\"]")
  set(CMAKE_Fortran_COMPILER_ID_TOOL_MATCH_INDEX 2)

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
  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)

181
  # Try to identify the compiler.
182 183
  set(CMAKE_Fortran_COMPILER_ID)
  include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
184
  CMAKE_DETERMINE_COMPILER_ID(Fortran FFLAGS CMakeFortranCompilerId.F)
185 186

  # Fall back to old is-GNU test.
187 188
  if(NOT CMAKE_Fortran_COMPILER_ID)
    exec_program(${CMAKE_Fortran_COMPILER}
189 190
      ARGS ${CMAKE_Fortran_COMPILER_ID_FLAGS_LIST} -E "\"${CMAKE_ROOT}/Modules/CMakeTestGNU.c\""
      OUTPUT_VARIABLE CMAKE_COMPILER_OUTPUT RETURN_VALUE CMAKE_COMPILER_RETURN)
191
    if(NOT CMAKE_COMPILER_RETURN)
192
      if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_GNU")
193 194
        set(CMAKE_Fortran_COMPILER_ID "GNU")
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
195 196
          "Determining if the Fortran compiler is GNU succeeded with "
          "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n")
197
      else()
198
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
199 200
          "Determining if the Fortran compiler is GNU failed with "
          "the following output:\n${CMAKE_COMPILER_OUTPUT}\n\n")
201
      endif()
202
      if(NOT CMAKE_Fortran_PLATFORM_ID)
203
        if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_MINGW")
204
          set(CMAKE_Fortran_PLATFORM_ID "MinGW")
205
        endif()
206
        if("${CMAKE_COMPILER_OUTPUT}" MATCHES "THIS_IS_CYGWIN")
207
          set(CMAKE_Fortran_PLATFORM_ID "Cygwin")
208 209 210 211
        endif()
      endif()
    endif()
  endif()
Bill Hoffman's avatar
Bill Hoffman committed
212

213
  # Set old compiler and platform id variables.
214
  if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
215
    set(CMAKE_COMPILER_IS_GNUG77 1)
216
  endif()
217
  if(CMAKE_Fortran_PLATFORM_ID MATCHES "MinGW")
218
    set(CMAKE_COMPILER_IS_MINGW 1)
219
  elseif(CMAKE_Fortran_PLATFORM_ID MATCHES "Cygwin")
220
    set(CMAKE_COMPILER_IS_CYGWIN 1)
221 222
  endif()
endif()
223

224 225 226 227 228 229 230 231
if (NOT _CMAKE_TOOLCHAIN_LOCATION)
  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_Fortran_COMPILER}" PATH)
endif ()

# if we have a fortran cross compiler, they have usually some prefix, like
# e.g. powerpc-linux-gfortran, arm-elf-gfortran or i586-mingw32msvc-gfortran , optionally
# with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).
# The other tools of the toolchain usually have the same prefix
232
# NAME_WE cannot be used since then this test will fail for names like
233 234
# "arm-unknown-nto-qnx6.3.0-gcc.exe", where BASENAME would be
# "arm-unknown-nto-qnx6" instead of the correct "arm-unknown-nto-qnx6.3.0-"
235 236
if (CMAKE_CROSSCOMPILING  AND NOT _CMAKE_TOOLCHAIN_PREFIX)

237
  if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
238 239 240 241 242 243 244 245 246 247
    get_filename_component(COMPILER_BASENAME "${CMAKE_Fortran_COMPILER}" NAME)
    if (COMPILER_BASENAME MATCHES "^(.+-)g?fortran(-[0-9]+\\.[0-9]+\\.[0-9]+)?(\\.exe)?$")
      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
    endif ()

    # if "llvm-" is part of the prefix, remove it, since llvm doesn't have its own binutils
    # but uses the regular ar, objcopy, etc. (instead of llvm-objcopy etc.)
    if ("${_CMAKE_TOOLCHAIN_PREFIX}" MATCHES "(.+-)?llvm-$")
      set(_CMAKE_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
    endif ()
248 249
  endif()

250 251
endif ()

252 253 254 255 256 257
include(CMakeFindBinUtils)

if(MSVC_Fortran_ARCHITECTURE_ID)
  set(SET_MSVC_Fortran_ARCHITECTURE_ID
    "set(MSVC_Fortran_ARCHITECTURE_ID ${MSVC_Fortran_ARCHITECTURE_ID})")
endif()
Bill Hoffman's avatar
Bill Hoffman committed
258
# configure variables set in this file for fast reload later on
259
configure_file(${CMAKE_ROOT}/Modules/CMakeFortranCompiler.cmake.in
260
  ${CMAKE_PLATFORM_INFO_DIR}/CMakeFortranCompiler.cmake
261
  @ONLY
262
  )
263
set(CMAKE_Fortran_COMPILER_ENV_VAR "FC")