CMakeDetermineCompilerId.cmake 43.6 KB
Newer Older
1
2
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.
3

4

5
# Function to compile a source file to identify the compiler.  This is
6
# used internally by CMake and should not be included by user code.
Alexander Neundorf's avatar
   
Alexander Neundorf committed
7
8
# If successful, sets CMAKE_<lang>_COMPILER_ID and CMAKE_<lang>_PLATFORM_ID

9
function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
10
  # Make sure the compiler arguments are clean.
11
12
  string(STRIP "${CMAKE_${lang}_COMPILER_ARG1}" CMAKE_${lang}_COMPILER_ID_ARG1)
  string(REGEX REPLACE " +" ";" CMAKE_${lang}_COMPILER_ID_ARG1 "${CMAKE_${lang}_COMPILER_ID_ARG1}")
13

14
  # Make sure user-specified compiler flags are used.
15
16
  if(CMAKE_${lang}_FLAGS)
    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
17
  elseif(DEFINED ENV{${flagvar}})
18
    set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
19
20
  else(CMAKE_${lang}_FLAGS_INIT)
    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS_INIT})
21
  endif()
22
  string(REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
23

24
  # Compute the directory in which to run the test.
25
  set(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang})
26
27
28

  # Try building with no extra flags and then try each set
  # of helper flags.  Stop when the compiler is identified.
29
30
31
32
  foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
    foreach(testflags ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS_FIRST}
                      ""
                      ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
33
      separate_arguments(testflags UNIX_COMMAND "${testflags}")
34
35
36
37
38
39
40
41
42
43
44
      CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${testflags}" "${userflags}" "${src}")
      CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR("${lang}" "${COMPILER_${lang}_PRODUCED_OUTPUT}")
      if(CMAKE_${lang}_COMPILER_ID)
        break()
      endif()
      foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
        CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
      endforeach()
      if(CMAKE_${lang}_COMPILER_ID)
        break()
      endif()
45
46
47
    endforeach()
    if(CMAKE_${lang}_COMPILER_ID)
      break()
48
49
    endif()
  endforeach()
50

51
52
53
54
55
56
57
58
  # Check if compiler id detection gave us the compiler tool.
  if(CMAKE_${lang}_COMPILER_ID_TOOL)
    set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}")
    set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
  elseif(NOT CMAKE_${lang}_COMPILER)
    set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
  endif()

59
  # If the compiler is still unknown, try to query its vendor.
60
  if(CMAKE_${lang}_COMPILER AND NOT CMAKE_${lang}_COMPILER_ID)
61
62
63
    foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
      CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang} "${userflags}")
    endforeach()
64
  endif()
65

Fred Baksik's avatar
Fred Baksik committed
66
67
68
69
70
71
72
  # If the compiler is still unknown, fallback to GHS
  if(NOT CMAKE_${lang}_COMPILER_ID  AND "${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
    set(CMAKE_${lang}_COMPILER_ID GHS)
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
        "The ${lang} compiler identification is falling back to GHS.\n\n")
  endif()

73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  # CUDA < 7.5 is missing version macros
  if(lang STREQUAL "CUDA"
     AND CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA"
     AND NOT CMAKE_${lang}_COMPILER_VERSION)
    execute_process(
      COMMAND "${CMAKE_${lang}_COMPILER}"
      --version
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
      TIMEOUT 10
    )
    if(output MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=])
      set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}")
    endif()
  endif()

Brad King's avatar
Brad King committed
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
  # For Swift we need to explicitly query the version.
  if(lang STREQUAL "Swift"
     AND CMAKE_${lang}_COMPILER
     AND NOT CMAKE_${lang}_COMPILER_VERSION)
    execute_process(
      COMMAND "${CMAKE_${lang}_COMPILER}"
      -version
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
      TIMEOUT 10
    )
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
      "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n"
      "${output}\n"
      )

    if(output MATCHES [[Swift version ([0-9]+\.[0-9]+(\.[0-9]+)?)]])
      set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}")
      if(NOT CMAKE_${lang}_COMPILER_ID)
        set(CMAKE_Swift_COMPILER_ID "Apple")
      endif()
    endif()
  endif()

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
  # For ISPC we need to explicitly query the version.
  if(lang STREQUAL "ISPC"
     AND CMAKE_${lang}_COMPILER
     AND NOT CMAKE_${lang}_COMPILER_VERSION)
    execute_process(
      COMMAND "${CMAKE_${lang}_COMPILER}"
      --version
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
      TIMEOUT 10
    )
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
      "Running the ${lang} compiler: \"${CMAKE_${lang}_COMPILER}\" -version\n"
      "${output}\n"
      )

    if(output MATCHES [[ISPC\), ([0-9]+\.[0-9]+(\.[0-9]+)?)]])
      set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}")
    endif()
  endif()


135
  if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU")
136
137
138
139
140
141
142
143
144
145
146
147
148
149
    execute_process(
      COMMAND "${CMAKE_${lang}_COMPILER}"
      -V
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
      TIMEOUT 10
      )
    if (output MATCHES "targets available")
      set(CMAKE_${lang}_COMPILER_ID QCC)
      # http://community.qnx.com/sf/discussion/do/listPosts/projects.community/discussion.qnx_momentics_community_support.topc3555?_pagenum=2
      # The qcc driver does not itself have a version.
    endif()
  endif()

150
  # if the format is unknown after all files have been checked, put "Unknown" in the cache
151
152
  if(NOT CMAKE_EXECUTABLE_FORMAT)
    set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
153
  endif()
154

155
156
157
158
  if((CMAKE_GENERATOR MATCHES "^Ninja"
        OR ((NOT DEFINED CMAKE_DEPENDS_USE_COMPILER OR CMAKE_DEPENDS_USE_COMPILER)
          AND CMAKE_GENERATOR MATCHES "Makefiles|WMake"))
      AND MSVC_${lang}_ARCHITECTURE_ID)
159
160
161
    foreach(userflags "${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}" "")
      CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX(${lang} "${userflags}")
    endforeach()
162
163
164
165
  else()
    set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "")
  endif()

166
167
  set(_variant "")
  if("x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xClang")
168
    if("x${CMAKE_${lang}_SIMULATE_ID}" STREQUAL "xMSVC")
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
      if(CMAKE_GENERATOR MATCHES "Visual Studio")
        set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC")
      else()
        # Test whether an MSVC-like command-line option works.
        execute_process(COMMAND "${CMAKE_${lang}_COMPILER}" -?
          RESULT_VARIABLE _clang_result
          OUTPUT_VARIABLE _clang_stdout
          ERROR_VARIABLE _clang_stderr)
        if(_clang_result EQUAL 0)
          set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "MSVC")
        else()
          set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU")
        endif()
      endif()
      set(_variant " with ${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}-like command-line")
    else()
      set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "GNU")
    endif()
  else()
    set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "")
  endif()

191
  # Display the final identification result.
192
193
194
195
196
197
  if(CMAKE_${lang}_COMPILER_ID)
    if(CMAKE_${lang}_COMPILER_VERSION)
      set(_version " ${CMAKE_${lang}_COMPILER_VERSION}")
    else()
      set(_version "")
    endif()
198
    if(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID AND "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xIAR")
199
200
201
202
      set(_archid " ${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}")
    else()
      set(_archid "")
    endif()
203
    message(STATUS "The ${lang} compiler identification is "
204
      "${CMAKE_${lang}_COMPILER_ID}${_archid}${_version}${_variant}")
205
206
    unset(_archid)
    unset(_version)
207
    unset(_variant)
208
  else()
209
    message(STATUS "The ${lang} compiler identification is unknown")
210
  endif()
211

212
213
214
215
  if(lang STREQUAL "Fortran" AND CMAKE_${lang}_COMPILER_ID STREQUAL "XL")
    set(CMAKE_${lang}_XL_CPP "${CMAKE_${lang}_COMPILER_ID_CPP}" PARENT_SCOPE)
  endif()

216
217
  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
218
  set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)
219
  set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
220
    PARENT_SCOPE)
221
  set(CMAKE_${lang}_XCODE_ARCHS "${CMAKE_${lang}_XCODE_ARCHS}" PARENT_SCOPE)
222
  set(CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX "${CMAKE_${lang}_CL_SHOWINCLUDES_PREFIX}" PARENT_SCOPE)
223
  set(CMAKE_${lang}_COMPILER_FRONTEND_VARIANT "${CMAKE_${lang}_COMPILER_FRONTEND_VARIANT}" PARENT_SCOPE)
224
  set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
225
  set(CMAKE_${lang}_COMPILER_VERSION_INTERNAL "${CMAKE_${lang}_COMPILER_VERSION_INTERNAL}" PARENT_SCOPE)
226
  set(CMAKE_${lang}_COMPILER_WRAPPER "${CMAKE_${lang}_COMPILER_WRAPPER}" PARENT_SCOPE)
227
228
  set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
229
  set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
230
231
  set(CMAKE_${lang}_COMPILER_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
  set(CMAKE_${lang}_COMPILER_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
232
endfunction()
233

234
include(CMakeCompilerIdDetection)
235

236
237
#-----------------------------------------------------------------------------
# Function to write the compiler id source file.
238
function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
239
  find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
240
  file(READ ${src_in} ID_CONTENT_IN)
241

242
243
244
  compiler_id_detection(CMAKE_${lang}_COMPILER_ID_CONTENT ${lang}
    ID_STRING
    VERSION_STRINGS
245
    PLATFORM_DEFAULT_COMPILER
246
  )
247

248
  unset(src_in CACHE)
249
250
  string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
  file(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
251
endfunction()
252

253
254
255
#-----------------------------------------------------------------------------
# Function to build the compiler id source file and look for output
# files.
256
function(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags userflags src)
257
  # Create a clean working directory.
258
259
  file(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
  file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
260
  file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}/tmp)
261
  CMAKE_DETERMINE_COMPILER_ID_WRITE("${lang}" "${src}")
262

263
  # Construct a description of this test case.
264
  set(COMPILER_DESCRIPTION
265
    "Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}
266
Build flags: ${userflags}
267
Id flags: ${testflags} ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
268
")
269

270
  # Compile the compiler identification source.
Brad King's avatar
Brad King committed
271
  if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)")
272
    set(vs_version ${CMAKE_MATCH_1})
273
    set(id_platform ${CMAKE_VS_PLATFORM_NAME})
274
    set(id_lang "${lang}")
275
    set(id_PostBuildEvent_Command "")
276
    if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Ll][Ll][Vv][Mm](_v[0-9]+(_xp)?)?$")
277
      set(id_cl_var "ClangClExecutable")
278
    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "^[Cc][Ll][Aa][Nn][Gg]([Cc][Ll]$|_[0-9])")
279
      set(id_cl "$(CLToolExe)")
280
    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "v[0-9]+_clang_.*")
281
      set(id_cl clang.exe)
282
283
284
285
286
287
288
289
290
291
    # Executable names have choosen according documentation
    # URL: (https://software.intel.com/content/www/us/en/develop/documentation/get-started-with-dpcpp-compiler/top.html#top_GUID-A9B4C91D-97AC-450D-9742-9D895BC8AEE1)
    elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "Intel")
      if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "DPC\\+\\+ Compiler")
        set(id_cl dpcpp.exe)
      elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler 2021")
        set(id_cl icx.exe)
      elseif(CMAKE_VS_PLATFORM_TOOLSET MATCHES "C\\+\\+ Compiler")
        set(id_cl icl.exe)
      endif()
292
293
294
    else()
      set(id_cl cl.exe)
    endif()
295
296
297
298
299
300
301
302
303
304
305
    if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
      set(v NsightTegra)
      set(ext vcxproj)
      if(lang STREQUAL CXX)
        set(id_gcc g++)
        set(id_clang clang++)
      else()
        set(id_gcc gcc)
        set(id_clang clang)
      endif()
    elseif(lang STREQUAL Fortran)
306
307
308
      set(v Intel)
      set(ext vfproj)
      set(id_cl ifort.exe)
309
310
311
312
    elseif(lang STREQUAL CSharp)
      set(v 10)
      set(ext csproj)
      set(id_cl csc.exe)
313
    elseif(NOT "${vs_version}" VERSION_LESS 10)
314
315
      set(v 10)
      set(ext vcxproj)
Brad King's avatar
Brad King committed
316
    else()
317
318
319
320
321
      set(id_version ${vs_version}.00)
      set(v 7)
      set(ext vcproj)
    endif()
    if(CMAKE_VS_PLATFORM_TOOLSET)
322
323
324
325
      if(CMAKE_VS_PLATFORM_NAME STREQUAL "Tegra-Android")
        set(id_toolset "<NdkToolchainVersion>${CMAKE_VS_PLATFORM_TOOLSET}</NdkToolchainVersion>")
      else()
        set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
326
        if(CMAKE_VS_PLATFORM_TOOLSET_VERSION)
327
          set(id_sep "\\")
328
          if(CMAKE_VS_PLATFORM_TOOLSET_VERSION VERSION_GREATER_EQUAL "14.20")
329
330
331
            if(EXISTS "${CMAKE_GENERATOR_INSTANCE}/VC/Auxiliary/Build.${CMAKE_VS_PLATFORM_TOOLSET_VERSION}/Microsoft.VCToolsVersion.${CMAKE_VS_PLATFORM_TOOLSET_VERSION}.props")
              set(id_sep ".")
            endif()
332
333
334
          endif()
          set(id_toolset_version_props "<Import Project=\"${CMAKE_GENERATOR_INSTANCE}\\VC\\Auxiliary\\Build${id_sep}${CMAKE_VS_PLATFORM_TOOLSET_VERSION}\\Microsoft.VCToolsVersion.${CMAKE_VS_PLATFORM_TOOLSET_VERSION}.props\" />")
          unset(id_sep)
335
        endif()
336
      endif()
337
338
    else()
      set(id_toolset "")
339
      set(id_toolset_version_props "")
340
    endif()
341
342
343
344
345
    if(CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE)
      set(id_PreferredToolArchitecture "<PreferredToolArchitecture>${CMAKE_VS_PLATFORM_TOOLSET_HOST_ARCHITECTURE}</PreferredToolArchitecture>")
    else()
      set(id_PreferredToolArchitecture "")
    endif()
346
    if(CMAKE_SYSTEM_NAME STREQUAL "WindowsPhone")
347
      set(id_keyword "Win32Proj")
348
349
      set(id_system "<ApplicationType>Windows Phone</ApplicationType>")
    elseif(CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
350
      set(id_keyword "Win32Proj")
351
      set(id_system "<ApplicationType>Windows Store</ApplicationType>")
352
353
354
    elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
      set(id_keyword "Android")
      set(id_system "<ApplicationType>Android</ApplicationType>")
355
    else()
356
      set(id_keyword "Win32Proj")
357
358
      set(id_system "")
    endif()
359
360
361
362
363
364
365
366
367
    if(id_keyword STREQUAL "Android")
      if(CMAKE_GENERATOR MATCHES "Visual Studio 14")
        set(id_system_version "<ApplicationTypeRevision>2.0</ApplicationTypeRevision>")
      elseif(CMAKE_GENERATOR MATCHES "Visual Studio 1[56]")
        set(id_system_version "<ApplicationTypeRevision>3.0</ApplicationTypeRevision>")
      else()
        set(id_system_version "")
      endif()
    elseif(id_system AND CMAKE_SYSTEM_VERSION MATCHES "^([0-9]+\\.[0-9]+)")
368
      set(id_system_version "<ApplicationTypeRevision>${CMAKE_MATCH_1}</ApplicationTypeRevision>")
369
370
371
    else()
      set(id_system_version "")
    endif()
372
373
374
375
376
    if(id_keyword STREQUAL "Android")
      set(id_config_type "DynamicLibrary")
    else()
      set(id_config_type "Application")
    endif()
377
378
379
    if(CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION)
      set(id_WindowsTargetPlatformVersion "<WindowsTargetPlatformVersion>${CMAKE_VS_WINDOWS_TARGET_PLATFORM_VERSION}</WindowsTargetPlatformVersion>")
    endif()
380
381
382
    if(CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR)
      set(id_ToolsetVCTargetsDir "<VCTargetsPath>${CMAKE_VS_PLATFORM_TOOLSET_VCTARGETS_CUSTOM_DIR}</VCTargetsPath>")
    endif()
383
384
385
386
387
388
    set(id_CustomGlobals "")
    foreach(pair IN LISTS CMAKE_VS_GLOBALS)
      if("${pair}" MATCHES "([^=]+)=(.*)$")
        string(APPEND id_CustomGlobals "<${CMAKE_MATCH_1}>${CMAKE_MATCH_2}</${CMAKE_MATCH_1}>\n    ")
      endif()
    endforeach()
389
390
391
    if(id_keyword STREQUAL "Android")
      set(id_WindowsSDKDesktopARMSupport "")
    elseif(id_platform STREQUAL "ARM64")
392
      set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARM64Support>true</WindowsSDKDesktopARM64Support>")
393
    elseif(id_platform STREQUAL "ARM")
394
395
396
397
      set(id_WindowsSDKDesktopARMSupport "<WindowsSDKDesktopARMSupport>true</WindowsSDKDesktopARMSupport>")
    else()
      set(id_WindowsSDKDesktopARMSupport "")
    endif()
398
    if(CMAKE_VS_WINCE_VERSION)
399
      set(id_entrypoint "mainACRTStartup")
400
401
402
403
404
      if("${vs_version}" VERSION_LESS 9)
        set(id_subsystem 9)
      else()
        set(id_subsystem 8)
      endif()
405
406
    else()
      set(id_subsystem 1)
407
    endif()
408
    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
409
    set(id_src "${src}")
410
    set(id_compile "ClCompile")
411
412
413
414
415
    if(id_cl_var)
      set(id_PostBuildEvent_Command "echo CMAKE_${lang}_COMPILER=$(${id_cl_var})")
    else()
      set(id_PostBuildEvent_Command "for %%i in (${id_cl}) do %40echo CMAKE_${lang}_COMPILER=%%~$PATH:i")
    endif()
416
417
418
419
    set(id_Import_props "")
    set(id_Import_targets "")
    set(id_ItemDefinitionGroup_entry "")
    set(id_Link_AdditionalDependencies "")
420
421
422
423
424
425
    if(lang STREQUAL CUDA)
      if(NOT CMAKE_VS_PLATFORM_TOOLSET_CUDA)
        message(FATAL_ERROR "No CUDA toolset found.")
      endif()
      set(cuda_tools "CUDA ${CMAKE_VS_PLATFORM_TOOLSET_CUDA}")
      set(id_compile "CudaCompile")
426
427
428
429
430
431
432
433
      if(CMAKE_VS_PLATFORM_NAME STREQUAL x64)
        set(cuda_target "<TargetMachinePlatform>64</TargetMachinePlatform>")
      endif()
      foreach(arch ${CMAKE_CUDA_ARCHITECTURES})
        string(REGEX MATCH "[0-9]+" arch_name "${arch}")
        string(APPEND cuda_codegen "compute_${arch_name},sm_${arch_name};")
      endforeach()
      set(id_ItemDefinitionGroup_entry "<CudaCompile>${cuda_target}<AdditionalOptions>%(AdditionalOptions)-v</AdditionalOptions><CodeGeneration>${cuda_codegen}</CodeGeneration></CudaCompile>")
434
      set(id_PostBuildEvent_Command [[echo CMAKE_CUDA_COMPILER=$(CudaToolkitBinDir)\nvcc.exe]])
435
436
437
438
439
440
441
442
      if(CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR)
        set(id_CudaToolkitCustomDir "<CudaToolkitCustomDir>${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}nvcc</CudaToolkitCustomDir>")
        string(CONCAT id_Import_props "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.props\" />")
        string(CONCAT id_Import_targets "<Import Project=\"${CMAKE_VS_PLATFORM_TOOLSET_CUDA_CUSTOM_DIR}\\CUDAVisualStudioIntegration\\extras\\visual_studio_integration\\MSBuildExtensions\\${cuda_tools}.targets\" />")
      else()
        string(CONCAT id_Import_props [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.props" />]])
        string(CONCAT id_Import_targets [[<Import Project="$(VCTargetsPath)\BuildCustomizations\]] "${cuda_tools}" [[.targets" />]])
      endif()
443
444
445
446
447
      if(CMAKE_CUDA_FLAGS MATCHES "(^| )-cudart +shared( |$)")
        set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart.lib</AdditionalDependencies>")
      else()
        set(id_Link_AdditionalDependencies "<AdditionalDependencies>cudart_static.lib</AdditionalDependencies>")
      endif()
448
    endif()
449
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
450
      ${id_dir}/CompilerId${lang}.${ext} @ONLY)
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
    if(CMAKE_VS_MSBUILD_COMMAND AND NOT lang STREQUAL "Fortran")
      set(command "${CMAKE_VS_MSBUILD_COMMAND}" "CompilerId${lang}.${ext}"
        "/p:Configuration=Debug" "/p:Platform=${id_platform}" "/p:VisualStudioVersion=${vs_version}.0"
        )
    elseif(CMAKE_VS_DEVENV_COMMAND)
      set(command "${CMAKE_VS_DEVENV_COMMAND}" "CompilerId${lang}.${ext}" "/build" "Debug")
    else()
      set(command "")
    endif()
    if(command)
      execute_process(
        COMMAND ${command}
        WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
        OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
        ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
        RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
        )
    else()
      set(CMAKE_${lang}_COMPILER_ID_RESULT 1)
      set(CMAKE_${lang}_COMPILER_ID_OUTPUT "VS environment not known to support ${lang}")
    endif()
472
473
    # Match the compiler location line printed out.
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "CMAKE_${lang}_COMPILER=([^%\r\n]+)[\r\n]")
474
475
      # Strip VS diagnostic output from the end of the line.
      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _comp "${CMAKE_MATCH_1}")
476
477
478
479
480
481
      if(EXISTS "${_comp}")
        file(TO_CMAKE_PATH "${_comp}" _comp)
        set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
      endif()
    endif()
  elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
482
483
484
    set(id_lang "${lang}")
    set(id_type ${CMAKE_${lang}_COMPILER_XCODE_TYPE})
    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
485
    set(id_src "${src}")
486
487
488
489
490
    if(CMAKE_XCODE_PLATFORM_TOOLSET)
      set(id_toolset "GCC_VERSION = ${CMAKE_XCODE_PLATFORM_TOOLSET};")
    else()
      set(id_toolset "")
    endif()
491
    if("${lang}" STREQUAL "Swift")
492
493
      if(CMAKE_Swift_LANGUAGE_VERSION)
        set(id_lang_version "SWIFT_VERSION = ${CMAKE_Swift_LANGUAGE_VERSION};")
494
495
      elseif(XCODE_VERSION VERSION_GREATER_EQUAL 10.2)
        set(id_lang_version "SWIFT_VERSION = 4.0;")
496
497
498
499
500
      elseif(XCODE_VERSION VERSION_GREATER_EQUAL 8.3)
        set(id_lang_version "SWIFT_VERSION = 3.0;")
      else()
        set(id_lang_version "SWIFT_VERSION = 2.3;")
      endif()
501
502
503
    else()
      set(id_lang_version "")
    endif()
504
505
506
507
508
509
    if(CMAKE_OSX_DEPLOYMENT_TARGET)
      set(id_deployment_target
        "MACOSX_DEPLOYMENT_TARGET = \"${CMAKE_OSX_DEPLOYMENT_TARGET}\";")
    else()
      set(id_deployment_target "")
    endif()
510
    set(id_product_type "com.apple.product-type.tool")
511
512
    if(CMAKE_OSX_SYSROOT)
      set(id_sdkroot "SDKROOT = \"${CMAKE_OSX_SYSROOT}\";")
513
514
      if(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ii][Pp][Hh][Oo][Nn][Ee]" OR
        CMAKE_OSX_SYSROOT MATCHES "(^|/)[Aa][Pp][Pp][Ll][Ee][Tt][Vv]")
515
        set(id_product_type "com.apple.product-type.bundle.unit-test")
516
517
      elseif(CMAKE_OSX_SYSROOT MATCHES "(^|/)[Ww][Aa][Tt][Cc][Hh]")
        set(id_product_type "com.apple.product-type.framework")
518
      endif()
519
520
521
    else()
      set(id_sdkroot "")
    endif()
522
523
524
525
526
527
528
529
530
    set(id_clang_cxx_library "")
    set(stdlib_regex "(^| )(-stdlib=)([^ ]+)( |$)")
    string(REGEX MATCHALL "${stdlib_regex}" all_stdlib_matches "${CMAKE_CXX_FLAGS}")
    if(all_stdlib_matches)
      list(GET all_stdlib_matches "-1" last_stdlib_match)
      if(last_stdlib_match MATCHES "${stdlib_regex}")
        set(id_clang_cxx_library "CLANG_CXX_LIBRARY = \"${CMAKE_MATCH_3}\";")
      endif()
    endif()
531
532
    if(CMAKE_SYSTEM_NAME STREQUAL "Darwin" AND CMAKE_OSX_SYSROOT MATCHES "^$|[Mm][Aa][Cc][Oo][Ss]")
      # When targeting macOS, use only the host architecture.
533
534
535
536
537
538
539
      if (_CMAKE_APPLE_ARCHS_DEFAULT)
        set(id_archs "ARCHS = \"${_CMAKE_APPLE_ARCHS_DEFAULT}\";")
        set(id_arch_active "ONLY_ACTIVE_ARCH = NO;")
      else()
        set(id_archs [[ARCHS = "$(NATIVE_ARCH_ACTUAL)";]])
        set(id_arch_active "ONLY_ACTIVE_ARCH = YES;")
      endif()
540
541
    else()
      set(id_archs "")
542
      set(id_arch_active "ONLY_ACTIVE_ARCH = YES;")
543
    endif()
544
545
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-3.pbxproj.in
      ${id_dir}/CompilerId${lang}.xcodeproj/project.pbxproj @ONLY)
546
547
548
549
550
    unset(_ENV_MACOSX_DEPLOYMENT_TARGET)
    if(DEFINED ENV{MACOSX_DEPLOYMENT_TARGET})
      set(_ENV_MACOSX_DEPLOYMENT_TARGET "$ENV{MACOSX_DEPLOYMENT_TARGET}")
      set(ENV{MACOSX_DEPLOYMENT_TARGET} "")
    endif()
551
552
553
554
555
556
    execute_process(COMMAND xcodebuild
      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
      OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
      )
557
558
559
    if(DEFINED _ENV_MACOSX_DEPLOYMENT_TARGET)
      set(ENV{MACOSX_DEPLOYMENT_TARGET} "${_ENV_MACOSX_DEPLOYMENT_TARGET}")
    endif()
560

561
562
563
564
565
566
    if(DEFINED CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX)
      if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_REGEX}")
        set(_comp "${CMAKE_MATCH_${CMAKE_${lang}_COMPILER_ID_TOOL_MATCH_INDEX}}")
        if(EXISTS "${_comp}")
          set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
        endif()
567
568
      endif()
    endif()
569
570
571
572
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "ARCHS=([^%\r\n]+)[\r\n]")
      set(CMAKE_${lang}_XCODE_ARCHS "${CMAKE_MATCH_1}")
      separate_arguments(CMAKE_${lang}_XCODE_ARCHS)
      set(CMAKE_${lang}_XCODE_ARCHS "${CMAKE_${lang}_XCODE_ARCHS}" PARENT_SCOPE)
573
    endif()
Fred Baksik's avatar
Fred Baksik committed
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
  elseif("${CMAKE_GENERATOR}" MATCHES "Green Hills MULTI")
    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
    set(id_src "${src}")
    if (GHS_PRIMARY_TARGET)
      set(ghs_primary_target "${GHS_PRIMARY_TARGET}")
    else()
      set(ghs_primary_target "${CMAKE_GENERATOR_PLATFORM}_${GHS_TARGET_PLATFORM}.tgt")
    endif()
    if ("${GHS_TARGET_PLATFORM}" MATCHES "integrity")
        set(bsp_name "macro GHS_BSP=${GHS_BSP_NAME}")
        set(os_dir "macro GHS_OS=${GHS_OS_DIR}")
    endif()
    set(command "${CMAKE_MAKE_PROGRAM}" "-commands" "-top" "GHS_default.gpj")
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/GHS_default.gpj.in
      ${id_dir}/GHS_default.gpj @ONLY)
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/GHS_lib.gpj.in
      ${id_dir}/GHS_lib.gpj @ONLY)
    execute_process(COMMAND ${command}
      WORKING_DIRECTORY ${id_dir}
      OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
      )
    # Match the compiler location line printed out.
    set(ghs_toolpath "${CMAKE_MAKE_PROGRAM}")
599
600
601
602
603
604
    if(CMAKE_HOST_UNIX)
      string(REPLACE "/gbuild" "/" ghs_toolpath ${ghs_toolpath})
    else()
      string(REPLACE "/gbuild.exe" "/" ghs_toolpath ${ghs_toolpath})
      string(REPLACE / "\\\\" ghs_toolpath ${ghs_toolpath})
    endif()
Fred Baksik's avatar
Fred Baksik committed
605
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "(${ghs_toolpath}[^ ]*)")
606
607
608
609
610
      if(CMAKE_HOST_UNIX)
        set(_comp "${CMAKE_MATCH_1}")
      else()
        set(_comp "${CMAKE_MATCH_1}.exe")
      endif()
Fred Baksik's avatar
Fred Baksik committed
611
612
613
614
615
      if(EXISTS "${_comp}")
        file(TO_CMAKE_PATH "${_comp}" _comp)
        set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
      endif()
    endif()
616
  else()
617
618
619
    execute_process(
      COMMAND "${CMAKE_${lang}_COMPILER}"
              ${CMAKE_${lang}_COMPILER_ID_ARG1}
620
              ${userflags}
621
              ${testflags}
622
              ${CMAKE_${lang}_COMPILER_ID_FLAGS_ALWAYS}
623
624
625
626
627
628
              "${src}"
      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
      OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
      )
629
630
631
632
633
634
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "exec: [^\n]*\\((/[^,\n]*/cpp),CMakeFortranCompilerId.F")
      set(_cpp "${CMAKE_MATCH_1}")
      if(EXISTS "${_cpp}")
        set(CMAKE_${lang}_COMPILER_ID_CPP "${_cpp}" PARENT_SCOPE)
      endif()
    endif()
635
  endif()
636
637

  # Check the result of compilation.
638
639
640
641
  if(CMAKE_${lang}_COMPILER_ID_RESULT
     # Intel Fortran warns and ignores preprocessor lines without /fpp
     OR CMAKE_${lang}_COMPILER_ID_OUTPUT MATCHES "Bad # preprocessor line"
     )
642
    # Compilation failed.
643
    set(MSG
644
645
646
647
648
649
650
      "Compiling the ${lang} compiler identification source file \"${src}\" failed.
${COMPILER_DESCRIPTION}
The output was:
${CMAKE_${lang}_COMPILER_ID_RESULT}
${CMAKE_${lang}_COMPILER_ID_OUTPUT}

")
651
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
652
653
654
655
656
657

    # Some languages may know the correct/desired set of flags and want to fail right away if they don't work.
    # This is currently only used by CUDA.
    if(CMAKE_${lang}_COMPILER_ID_REQUIRE_SUCCESS)
      message(FATAL_ERROR "${MSG}")
    endif()
658
659

    # No output files should be inspected.
660
    set(COMPILER_${lang}_PRODUCED_FILES)
661
    set(COMPILER_${lang}_PRODUCED_OUTPUT)
662
  else()
663
    # Compilation succeeded.
664
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
665
666
667
668
669
670
671
      "Compiling the ${lang} compiler identification source file \"${src}\" succeeded.
${COMPILER_DESCRIPTION}
The output was:
${CMAKE_${lang}_COMPILER_ID_RESULT}
${CMAKE_${lang}_COMPILER_ID_OUTPUT}

")
672

673
674
    # Find the executable produced by the compiler, try all files in the
    # binary dir.
675
    string(REGEX REPLACE "([][])" "[\\1]" _glob_id_dir "${CMAKE_${lang}_COMPILER_ID_DIR}")
676
    file(GLOB files
677
      RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
678
679

      # normal case
680
      ${_glob_id_dir}/*
681
682

      # com.apple.package-type.bundle.unit-test
683
      ${_glob_id_dir}/*.xctest/*
684
685
686

      # com.apple.product-type.framework
      ${_glob_id_dir}/*.framework/*
687
      )
688
689
690
691
692
693
694
695
696
    list(REMOVE_ITEM files "${src}")
    set(COMPILER_${lang}_PRODUCED_FILES "")
    foreach(file ${files})
      if(NOT IS_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}/${file})
        list(APPEND COMPILER_${lang}_PRODUCED_FILES ${file})
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
          "Compilation of the ${lang} compiler identification source \""
          "${src}\" produced \"${file}\"\n\n")
      endif()
697
    endforeach()
698

699
    if(NOT COMPILER_${lang}_PRODUCED_FILES)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
700
      # No executable was found.
701
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
702
        "Compilation of the ${lang} compiler identification source \""
703
        "${src}\" did not produce an executable in \""
704
        "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
705
    endif()
706
707

    set(COMPILER_${lang}_PRODUCED_OUTPUT "${CMAKE_${lang}_COMPILER_ID_OUTPUT}")
708
  endif()
709

710
  # Return the files produced by the compilation.
711
  set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
712
  set(COMPILER_${lang}_PRODUCED_OUTPUT "${COMPILER_${lang}_PRODUCED_OUTPUT}" PARENT_SCOPE)
713

714
715
716
717
718
719
720
721
722
723
724
endfunction()

#-----------------------------------------------------------------------------
# Function to extract the compiler id from compiler output.
function(CMAKE_DETERMINE_COMPILER_ID_MATCH_VENDOR lang output)
  foreach(vendor ${CMAKE_${lang}_COMPILER_ID_MATCH_VENDORS})
    if(output MATCHES "${CMAKE_${lang}_COMPILER_ID_MATCH_VENDOR_REGEX_${vendor}}")
      set(CMAKE_${lang}_COMPILER_ID "${vendor}")
    endif()
  endforeach()
  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
725
endfunction()
726
727
728

#-----------------------------------------------------------------------------
# Function to extract the compiler id from an executable.
729
function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
730
  # Look for a compiler id if not yet known.
731
  if(NOT CMAKE_${lang}_COMPILER_ID)
732
    # Read the compiler identification string from the executable file.
733
734
    set(COMPILER_ID)
    set(COMPILER_VERSION)
735
736
737
738
    set(COMPILER_VERSION_MAJOR 0)
    set(COMPILER_VERSION_MINOR 0)
    set(COMPILER_VERSION_PATCH 0)
    set(COMPILER_VERSION_TWEAK 0)
739
    set(COMPILER_VERSION_INTERNAL "")
740
741
742
743
    set(HAVE_COMPILER_VERSION_MAJOR 0)
    set(HAVE_COMPILER_VERSION_MINOR 0)
    set(HAVE_COMPILER_VERSION_PATCH 0)
    set(HAVE_COMPILER_VERSION_TWEAK 0)
744
    set(COMPILER_WRAPPER)
745
746
747
748
749
750
751
752
    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)
753
    set(PLATFORM_ID)
754
    set(ARCHITECTURE_ID)
755
756
    set(SIMULATE_ID)
    set(SIMULATE_VERSION)
757
758
759
760
761
762
763
764
    foreach(encoding "" "ENCODING;UTF-16LE" "ENCODING;UTF-16BE")
      file(STRINGS "${file}" CMAKE_${lang}_COMPILER_ID_STRINGS
        LIMIT_COUNT 38 ${encoding}
        REGEX ".?I.?N.?F.?O.?:.?[A-Za-z0-9_]+\\[[^]]*\\]")
      if(NOT CMAKE_${lang}_COMPILER_ID_STRINGS STREQUAL "")
        break()
      endif()
    endforeach()
765

766
767
768
    # With the IAR Compiler, some strings are found twice, first time as incomplete
    # list like "?<Constant "INFO:compiler[IAR]">".  Remove the incomplete copies.
    list(FILTER CMAKE_${lang}_COMPILER_ID_STRINGS EXCLUDE REGEX "\\?<Constant \\\"")
769

770
771
772
773
774
775
776
    # The IAR-AVR compiler uses a binary format that places a '6'
    # character (0x34) before each character in the string.  Strip
    # out these characters without removing any legitimate characters.
    if(CMAKE_${lang}_COMPILER_ID_STRINGS MATCHES "(.)I.N.F.O.:.")
      string(REGEX REPLACE "${CMAKE_MATCH_1}([^;])" "\\1"
        CMAKE_${lang}_COMPILER_ID_STRINGS "${CMAKE_${lang}_COMPILER_ID_STRINGS}")
    endif()
777

778
779
780
781
    # Remove arbitrary text that may appear before or after each INFO string.
    string(REGEX MATCHALL "INFO:[A-Za-z0-9_]+\\[([^]\"]*)\\]"
      CMAKE_${lang}_COMPILER_ID_STRINGS "${CMAKE_${lang}_COMPILER_ID_STRINGS}")

782
783
    # In C# binaries, some strings are found more than once.
    list(REMOVE_DUPLICATES CMAKE_${lang}_COMPILER_ID_STRINGS)
784
785

    set(COMPILER_ID_TWICE)
786
    foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
787
      if("${info}" MATCHES "INFO:compiler\\[([^]\"]*)\\]")
788
789
        if(COMPILER_ID)
          set(COMPILER_ID_TWICE 1)
790
        endif()
791
        set(COMPILER_ID "${CMAKE_MATCH_1}")
792
      endif()
793
      if("${info}" MATCHES "INFO:platform\\[([^]\"]*)\\]")
794
        set(PLATFORM_ID "${CMAKE_MATCH_1}")
795
      endif()
796
      if("${info}" MATCHES "INFO:arch\\[([^]\"]*)\\]")
797
        set(ARCHITECTURE_ID "${CMAKE_MATCH_1}")
798
      endif()
799
      if("${info}" MATCHES "INFO:compiler_version\\[([^]\"]*)\\]")
Fred Baksik's avatar
Fred Baksik committed
800
        string(REGEX REPLACE "^0+([0-9]+)" "\\1" COMPILER_VERSION "${CMAKE_MATCH_1}")
801
        string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}")
802
      endif()
803
804
805
806
      if("${info}" MATCHES "INFO:compiler_version_internal\\[([^]\"]*)\\]")
        string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION_INTERNAL "${CMAKE_MATCH_1}")
        string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION_INTERNAL "${COMPILER_VERSION_INTERNAL}")
      endif()
807
808
809
810
811
812
813
814
815
      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()
816
817
818
      if("${info}" MATCHES "INFO:compiler_wrapper\\[([^]\"]*)\\]")
        set(COMPILER_WRAPPER "${CMAKE_MATCH_1}")
      endif()
819
      if("${info}" MATCHES "INFO:simulate\\[([^]\"]*)\\]")
820
821
        set(SIMULATE_ID "${CMAKE_MATCH_1}")
      endif()
822
      if("${info}" MATCHES "INFO:simulate_version\\[([^]\"]*)\\]")
823
        string(REGEX REPLACE "^0+([0-9])" "\\1" SIMULATE_VERSION "${CMAKE_MATCH_1}")
824
825
        string(REGEX REPLACE "\\.0+([0-9])" ".\\1" SIMULATE_VERSION "${SIMULATE_VERSION}")
      endif()
826
      if("${info}" MATCHES "INFO:qnxnto\\[\\]")
827
828
        set(COMPILER_QNXNTO 1)
      endif()
829
830
831
      if("${info}" MATCHES "INFO:dialect_default\\[([^]\"]*)\\]")
        set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_MATCH_1}")
      endif()
832
    endforeach()
833

834
835
836
837
    # 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)
Daniel Pfeifer's avatar
Daniel Pfeifer committed
838
        string(APPEND COMPILER_VERSION ".${COMPILER_VERSION_MINOR}")
839
        if(HAVE_COMPILER_VERSION_PATCH)
Daniel Pfeifer's avatar
Daniel Pfeifer committed
840
          string(APPEND COMPILER_VERSION ".${COMPILER_VERSION_PATCH}")
841
          if(HAVE_COMPILER_VERSION_TWEAK)
Daniel Pfeifer's avatar
Daniel Pfeifer committed
842
            string(APPEND COMPILER_VERSION ".${COMPILER_VERSION_TWEAK}")
843
844
845
846
847
          endif()
        endif()
      endif()
    endif()

848
849
850
851
    # Detect the exact architecture from the PE header.
    if(WIN32)
      # The offset to the PE signature is stored at 0x3c.
      file(READ ${file} peoffsethex LIMIT 1 OFFSET 60 HEX)
Fred Baksik's avatar
Fred Baksik committed
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
      if(NOT peoffsethex STREQUAL "")
        string(SUBSTRING "${peoffsethex}" 0 1 peoffsethex1)
        string(SUBSTRING "${peoffsethex}" 1 1 peoffsethex2)
        set(peoffsetexpression "${peoffsethex1} * 16 + ${peoffsethex2}")
        string(REPLACE "a" "10" peoffsetexpression "${peoffsetexpression}")
        string(REPLACE "b" "11" peoffsetexpression "${peoffsetexpression}")
        string(REPLACE "c" "12" peoffsetexpression "${peoffsetexpression}")
        string(REPLACE "d" "13" peoffsetexpression "${peoffsetexpression}")
        string(REPLACE "e" "14" peoffsetexpression "${peoffsetexpression}")
        string(REPLACE "f" "15" peoffsetexpression "${peoffsetexpression}")
        math(EXPR peoffset "${peoffsetexpression}")

        file(READ ${file} peheader LIMIT 6 OFFSET ${peoffset} HEX)
        if(peheader STREQUAL "50450000a201")
          set(ARCHITECTURE_ID "SH3")
        elseif(peheader STREQUAL "50450000a301")
          set(ARCHITECTURE_ID "SH3DSP")
        elseif(peheader STREQUAL "50450000a601")
          set(ARCHITECTURE_ID "SH4")
        elseif(peheader STREQUAL "50450000a801")
          set(ARCHITECTURE_ID "SH5")
        endif()
874
875
876
      endif()
    endif()

877
    # Check if a valid compiler and platform were found.
878
879
880
    if(COMPILER_ID AND NOT COMPILER_ID_TWICE)
      set(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
      set(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
881
      set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${ARCHITECTURE_ID}")
882
883
      set(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}")
      set(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}")
884
      set(CMAKE_${lang}_COMPILER_VERSION_INTERNAL "${COMPILER_VERSION_INTERNAL}")
885
886
      set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}")
      set(CMAKE_${lang}_SIMULATE_VERSION "${SIMULATE_VERSION}")
887
    endif()
888
889

    # Check the compiler identification string.
890
    if(CMAKE_${lang}_COMPILER_ID)
891
      # The compiler identification was found.
892
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
893
894
        "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
        "${file}\"\n\n")
895
    else()
896
      # The compiler identification could not be found.
897
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
898
899
        "The ${lang} compiler identification could not be found in \""
        "${file}\"\n\n")
900
901
    endif()
  endif()
902
903

  # try to figure out the executable format: ELF, COFF, Mach-O
904
905
  if(NOT CMAKE_EXECUTABLE_FORMAT)
    file(READ ${file} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
906
907

    # ELF files start with 0x7f"ELF"
908
909
    if("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
      set(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE INTERNAL "Executable file format")
910
    endif()
911
912

#    # COFF (.exe) files start with "MZ"
913
914
#    if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
#      set(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
915
#    endif()
916
#
917
918
919
920
    # Mach-O files start with MH_MAGIC or MH_CIGAM
    if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface|cefaedfe|feedfacf|cffaedfe")
      set(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
    endif()
921

922
  endif()
923
924
925
  if(NOT DEFINED CMAKE_EXECUTABLE_FORMAT)
    set(CMAKE_EXECUTABLE_FORMAT)
  endif()
926
  # Return the information extracted.
927
928
  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
929
  set(CMAKE_${lang}_COMPILER_ARCHITECTURE_ID "${CMAKE_${lang}_COMPILER_ARCHITECTURE_ID}" PARENT_SCOPE)
930
  set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
931
    PARENT_SCOPE)
932
  set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
933
  set(CMAKE_${lang}_COMPILER_VERSION_INTERNAL "${CMAKE_${lang}_COMPILER_VERSION_INTERNAL}" PARENT_SCOPE)
934
  set(CMAKE_${lang}_COMPILER_WRAPPER "${COMPILER_WRAPPER}" PARENT_SCOPE)
935
936
  set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
937
  set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
938
  set(COMPILER_QNXNTO "${COMPILER_QNXNTO}" PARENT_SCOPE)
939
  set(CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT "${CMAKE_${lang}_STANDARD_COMPUTED_DEFAULT}" PARENT_SCOPE)
940
endfunction()
941
942
943
944
945
946
947
948
949

#-----------------------------------------------------------------------------
# Function to query the compiler vendor.
# This uses a table with entries of the form
#   list(APPEND CMAKE_${lang}_COMPILER_ID_VENDORS ${vendor})
#   set(CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor} -some-vendor-flag)
#   set(CMAKE_${lang}_COMPILER_ID_VENDOR_REGEX_${vendor} "Some Vendor Output")
# We try running the compiler with the flag for each vendor and
# matching its regular expression in the output.
950
function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang userflags)
951

952
  if(NOT CMAKE_${lang}_COMPILER_ID_DIR)
953
954
955
    # We get here when this function is called not from within CMAKE_DETERMINE_COMPILER_ID()
    # This is done e.g. for detecting the compiler ID for assemblers.
    # Compute the directory in which to run the test and Create a clean working directory.
956
    set(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang})
957
958
    file(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
    file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
959
  endif()
960

961
962
963
964
965
966
967
968
  # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
  # and set them to "C" so we get the expected output to match.
  set(_orig_lc_all      $ENV{LC_ALL})
  set(_orig_lc_messages $ENV{LC_MESSAGES})
  set(_orig_lang        $ENV{LANG})
  set(ENV{LC_ALL}      C)
  set(ENV{LC_MESSAGES} C)
  set(ENV{LANG}        C)
969

970
971
972
973
  foreach(vendor ${CMAKE_${lang}_COMPILER_ID_VENDORS})
    set(flags ${CMAKE_${lang}_COMPILER_ID_VENDOR_FLAGS_${vendor}})
    set(regex ${CMAKE_${lang}_COMPILER_ID_VENDOR_REGEX_${vendor}})
    execute_process(
974
      COMMAND "${CMAKE_${lang}_COMPILER}"
975
      ${CMAKE_${lang}_COMPILER_ID_ARG1}
976
      ${userflags}
977
978
979
980
      ${flags}
      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
981
      TIMEOUT 10
982
      )
983

984
985
    if("${output}" MATCHES "${regex}")
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
986
987
        "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
        "matched \"${regex}\":\n${output}")
988
      set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
989
      set(CMAKE_${lang}_COMPILER_ID_OUTPUT "${output}" PARENT_SCOPE)
990
      set(CMAKE_${lang}_COMPILER_ID_VENDOR_MATCH "${CMAKE_MATCH_1}" PARENT_SCOPE)
991
992
993
994
      break()
    else()
      if("${result}" MATCHES  "timeout")
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
995
996
          "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
          "terminated after 10 s due to timeout.")
997
998
      else()
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
999
1000
          "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
          "did not match \"${regex}\":\n${output}")
1001
1002
1003
       endif()
    endif()
  endforeach()
1004
1005
1006
1007
1008

  # Restore original LC_ALL, LC_MESSAGES, and LANG
  set(ENV{LC_ALL}      ${_orig_lc_all})
  set(ENV{LC_MESSAGES} ${_orig_lc_messages})
  set(ENV{LANG}        ${_orig_lang})
1009
endfunction()
1010

1011
function(CMAKE_DETERMINE_MSVC_SHOWINCLUDES_PREFIX lang userflags)
1012
1013
1014
1015
1016
1017
1018
1019
1020
  # Run this MSVC-compatible compiler to detect what the /showIncludes
  # option displays.  We can use a C source even with the C++ compiler
  # because MSVC-compatible compilers handle both and show the same output.
  set(showdir ${CMAKE_BINARY_DIR}/CMakeFiles/ShowIncludes)
  file(WRITE ${showdir}/foo.h "\n")
  file(WRITE ${showdir}/main.c "#include \"foo.h\" \nint main(){}\n")
  execute_process(
    COMMAND "${CMAKE_${lang}_COMPILER}"
            ${CMAKE_${lang}_COMPILER_ID_ARG1}
1021
            ${userflags}
1022
1023
1024
1025
1026
            /nologo /showIncludes /c main.c
    WORKING_DIRECTORY ${showdir}
    OUTPUT_VARIABLE out
    ERROR_VARIABLE err