CMakeCompilerIdDetection.cmake 4.97 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

#=============================================================================
# Copyright 2014 Stephen Kelly <steveire@gmail.com>
#
# 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.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
#  License text for the above reference.)

function(_readFile file)
  include(${file})
  get_filename_component(name ${file} NAME_WE)
  string(REGEX REPLACE "-.*" "" CompilerId ${name})
  set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE)
20
  set(_compiler_id_simulate_${CompilerId} ${_compiler_id_simulate} PARENT_SCOPE)
21 22 23
  set(_compiler_id_pp_test_${CompilerId} ${_compiler_id_pp_test} PARENT_SCOPE)
endfunction()

24 25
include(${CMAKE_CURRENT_LIST_DIR}/CMakeParseArguments.cmake)

26 27 28
function(compiler_id_detection outvar lang)

  if (NOT lang STREQUAL Fortran)
29
    file(GLOB lang_files
30
      "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake")
31 32 33 34 35 36 37 38
    set(nonlang CXX)
    if (lang STREQUAL CXX)
      set(nonlang C)
    endif()

    file(GLOB nonlang_files
      "${CMAKE_ROOT}/Modules/Compiler/*-${nonlang}-DetermineCompiler.cmake")
    list(REMOVE_ITEM lang_files ${nonlang_files})
39 40
  endif()

41
  set(files ${lang_files})
42 43 44 45 46
  if (files)
    foreach(file ${files})
      _readFile(${file})
    endforeach()

47
    set(options ID_STRING VERSION_STRINGS ID_DEFINE PLATFORM_DEFAULT_COMPILER)
48
    set(oneValueArgs PREFIX)
49 50 51 52 53
    cmake_parse_arguments(CID "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${ARGN})
    if (CID_UNPARSED_ARGUMENTS)
      message(FATAL_ERROR "Unrecognized arguments: \"${CID_UNPARSED_ARGUMENTS}\"")
    endif()

54 55 56 57 58 59 60 61
    # Order is relevant here. For example, compilers which pretend to be
    # GCC must appear before the actual GCC.
    if (lang STREQUAL CXX)
      list(APPEND ordered_compilers
        Comeau
      )
    endif()
    list(APPEND ordered_compilers
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
      Intel
      PathScale
      Embarcadero
      Borland
      Watcom
      OpenWatcom
      SunPro
      HP
      Compaq
      zOS
      XL
      VisualAge
      PGI
      Cray
      TI
77
      Fujitsu
78 79 80 81
    )
    if (lang STREQUAL C)
      list(APPEND ordered_compilers
        TinyCC
82
        Bruce
83 84 85
      )
    endif()
    list(APPEND ordered_compilers
86
      SCO
87 88
      AppleClang
      Clang
89 90 91 92
      GNU
      MSVC
      ADSP
      IAR
93
      ARMCC
94 95 96 97 98 99 100
    )
    if (lang STREQUAL C)
      list(APPEND ordered_compilers
        SDCC
      )
    endif()
    list(APPEND ordered_compilers
101 102
      MIPSpro)

103 104
    if(CID_ID_DEFINE)
      foreach(Id ${ordered_compilers})
105
        set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n")
106 107 108
      endforeach()
    endif()

109
    set(pp_if "#if")
110
    if (CID_VERSION_STRINGS)
111
      set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n/* Version number components: V=Version, R=Revision, P=Patch
112
   Version date components:   YYYY=Year, MM=Month,   DD=Day  */\n")
113
    endif()
114 115 116 117 118

    foreach(Id ${ordered_compilers})
      if (NOT _compiler_id_pp_test_${Id})
        message(FATAL_ERROR "No preprocessor test for \"${Id}\"")
      endif()
119 120
      set(id_content "${pp_if} ${_compiler_id_pp_test_${Id}}\n")
      if (CID_ID_STRING)
121 122 123
        set(PREFIX ${CID_PREFIX})
        string(CONFIGURE "${_compiler_id_simulate_${Id}}" SIMULATE_BLOCK @ONLY)
        set(id_content "${id_content}# define ${CID_PREFIX}COMPILER_ID \"${Id}\"${SIMULATE_BLOCK}")
124
      endif()
125
      if (CID_ID_DEFINE)
126 127
        set(id_content "${id_content}# undef ${CID_PREFIX}COMPILER_IS_${Id}\n")
        set(id_content "${id_content}# define ${CID_PREFIX}COMPILER_IS_${Id} 1\n")
128
      endif()
129
      if (CID_VERSION_STRINGS)
130
        set(PREFIX ${CID_PREFIX})
131 132
        set(MACRO_DEC DEC)
        set(MACRO_HEX HEX)
133 134
        string(CONFIGURE "${_compiler_id_version_compute_${Id}}" VERSION_BLOCK @ONLY)
        set(id_content "${id_content}${VERSION_BLOCK}\n")
135
      endif()
136 137 138 139
      set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${id_content}")
      set(pp_if "#elif")
    endforeach()

140 141
    if (CID_PLATFORM_DEFAULT_COMPILER)
      set(platform_compiler_detection "
142 143 144 145
/* These compilers are either not known or too old to define an
  identification macro.  Try to identify the platform and guess that
  it is the native compiler.  */
#elif defined(__sgi)
146
# define ${CID_PREFIX}COMPILER_ID \"MIPSpro\"
147 148

#elif defined(__hpux) || defined(__hpua)
149
# define ${CID_PREFIX}COMPILER_ID \"HP\"
150 151

#else /* unknown compiler */
152
# define ${CID_PREFIX}COMPILER_ID \"\"")
153
    endif()
154

155
    set(CMAKE_${lang}_COMPILER_ID_CONTENT "${CMAKE_${lang}_COMPILER_ID_CONTENT}\n${platform_compiler_detection}\n#endif")
156 157 158 159
  endif()

  set(${outvar} ${CMAKE_${lang}_COMPILER_ID_CONTENT} PARENT_SCOPE)
endfunction()