1# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2# file Copyright.txt or https://cmake.org/licensing for details.
3
4
5function(_readFile file)
6  include(${file})
7  get_filename_component(name ${file} NAME_WE)
8  string(REGEX REPLACE "-.*" "" CompilerId ${name})
9  set(_compiler_id_version_compute_${CompilerId} ${_compiler_id_version_compute} PARENT_SCOPE)
10  set(_compiler_id_simulate_${CompilerId} ${_compiler_id_simulate} PARENT_SCOPE)
11  set(_compiler_id_pp_test_${CompilerId} ${_compiler_id_pp_test} PARENT_SCOPE)
12endfunction()
13
14function(compiler_id_detection outvar lang)
15
16  if (NOT "x${lang}" STREQUAL "xFortran" AND NOT "x${lang}" STREQUAL "xCSharp"
17      AND NOT "x${lang}" STREQUAL "xISPC")
18    file(GLOB lang_files
19      "${CMAKE_ROOT}/Modules/Compiler/*-DetermineCompiler.cmake")
20    set(nonlang CXX)
21    if ("x${lang}" STREQUAL "xCXX")
22      set(nonlang C)
23    endif()
24
25    file(GLOB nonlang_files
26      "${CMAKE_ROOT}/Modules/Compiler/*-${nonlang}-DetermineCompiler.cmake")
27    list(REMOVE_ITEM lang_files ${nonlang_files})
28  endif()
29
30  set(files ${lang_files})
31  if (files)
32    foreach(file ${files})
33      _readFile(${file})
34    endforeach()
35
36    set(options ID_STRING VERSION_STRINGS ID_DEFINE PLATFORM_DEFAULT_COMPILER)
37    set(oneValueArgs PREFIX)
38    cmake_parse_arguments(CID "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${ARGN})
39    if (CID_UNPARSED_ARGUMENTS)
40      message(FATAL_ERROR "Unrecognized arguments: \"${CID_UNPARSED_ARGUMENTS}\"")
41    endif()
42
43    # Order is relevant here. For example, compilers which pretend to be
44    # GCC must appear before the actual GCC.
45    if ("x${lang}" STREQUAL "xCXX")
46      list(APPEND ordered_compilers
47        Comeau
48      )
49    endif()
50    list(APPEND ordered_compilers
51      Intel
52      IntelLLVM
53      PathScale
54      Embarcadero
55      Borland
56      Watcom
57      OpenWatcom
58      SunPro
59      HP
60      Compaq
61      zOS
62      XLClang
63      XL
64      VisualAge
65      NVHPC
66      PGI
67      Cray
68      TI
69      FujitsuClang
70      Fujitsu
71      GHS
72    )
73    if ("x${lang}" STREQUAL "xC")
74      list(APPEND ordered_compilers
75        TinyCC
76        Bruce
77      )
78    endif()
79    list(APPEND ordered_compilers
80      SCO
81      ARMCC
82      AppleClang
83      ARMClang
84    )
85    list(APPEND ordered_compilers
86      Clang
87      GNU
88      MSVC
89      ADSP
90      IAR
91    )
92    if ("x${lang}" STREQUAL "xC")
93      list(APPEND ordered_compilers
94        SDCC
95      )
96    endif()
97
98    if("x${lang}" STREQUAL "xCUDA")
99      set(ordered_compilers NVIDIA Clang)
100    endif()
101
102    if(CID_ID_DEFINE)
103      foreach(Id ${ordered_compilers})
104        string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "# define ${CID_PREFIX}COMPILER_IS_${Id} 0\n")
105      endforeach()
106      # Hard-code definitions for compilers that are no longer supported.
107      string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "# define ${CID_PREFIX}COMPILER_IS_MIPSpro 0\n")
108    endif()
109
110    set(pp_if "#if")
111    if (CID_VERSION_STRINGS)
112      string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n/* Version number components: V=Version, R=Revision, P=Patch
113   Version date components:   YYYY=Year, MM=Month,   DD=Day  */\n")
114    endif()
115
116    foreach(Id ${ordered_compilers})
117      if (NOT _compiler_id_pp_test_${Id})
118        message(FATAL_ERROR "No preprocessor test for \"${Id}\"")
119      endif()
120      set(id_content "${pp_if} ${_compiler_id_pp_test_${Id}}\n")
121      if (CID_ID_STRING)
122        set(PREFIX ${CID_PREFIX})
123        string(CONFIGURE "${_compiler_id_simulate_${Id}}" SIMULATE_BLOCK @ONLY)
124        string(APPEND id_content "# define ${CID_PREFIX}COMPILER_ID \"${Id}\"${SIMULATE_BLOCK}")
125      endif()
126      if (CID_ID_DEFINE)
127        string(APPEND id_content "# undef ${CID_PREFIX}COMPILER_IS_${Id}\n")
128        string(APPEND id_content "# define ${CID_PREFIX}COMPILER_IS_${Id} 1\n")
129      endif()
130      if (CID_VERSION_STRINGS)
131        set(PREFIX ${CID_PREFIX})
132        set(MACRO_DEC DEC)
133        set(MACRO_HEX HEX)
134        string(CONFIGURE "${_compiler_id_version_compute_${Id}}" VERSION_BLOCK @ONLY)
135        string(APPEND id_content "${VERSION_BLOCK}\n")
136      endif()
137      string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n${id_content}")
138      set(pp_if "#elif")
139    endforeach()
140
141    if (CID_PLATFORM_DEFAULT_COMPILER)
142      set(platform_compiler_detection "
143/* These compilers are either not known or too old to define an
144  identification macro.  Try to identify the platform and guess that
145  it is the native compiler.  */
146#elif defined(__hpux) || defined(__hpua)
147# define ${CID_PREFIX}COMPILER_ID \"HP\"
148
149#else /* unknown compiler */
150# define ${CID_PREFIX}COMPILER_ID \"\"")
151    endif()
152
153    string(APPEND CMAKE_${lang}_COMPILER_ID_CONTENT "\n${platform_compiler_detection}\n#endif")
154  endif()
155
156  set(${outvar} ${CMAKE_${lang}_COMPILER_ID_CONTENT} PARENT_SCOPE)
157endfunction()
158