CMakeDetermineCompilerId.cmake 20.7 KB
Newer Older
1

2
3
4
5
6
7
8
9
10
11
#=============================================================================
# Copyright 2007-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
# Function to compile a source file to identify the compiler.  This is
16
# used internally by CMake and should not be included by user code.
Alexander Neundorf's avatar
   
Alexander Neundorf committed
17
18
# If successful, sets CMAKE_<lang>_COMPILER_ID and CMAKE_<lang>_PLATFORM_ID

19
function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
20
  # Make sure the compiler arguments are clean.
21
22
  string(STRIP "${CMAKE_${lang}_COMPILER_ARG1}" CMAKE_${lang}_COMPILER_ID_ARG1)
  string(REGEX REPLACE " +" ";" CMAKE_${lang}_COMPILER_ID_ARG1 "${CMAKE_${lang}_COMPILER_ID_ARG1}")
23

24
  # Make sure user-specified compiler flags are used.
25
26
  if(CMAKE_${lang}_FLAGS)
    set(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
27
  else()
28
    set(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
29
  endif()
30
  string(REGEX REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
31

32
  # Compute the directory in which to run the test.
33
  set(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang})
34
35
36

  # Try building with no extra flags and then try each set
  # of helper flags.  Stop when the compiler is identified.
37
38
  foreach(flags "" ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
    if(NOT CMAKE_${lang}_COMPILER_ID)
39
      CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
40
      foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
41
        CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
42
43
44
      endforeach()
    endif()
  endforeach()
45

46
  # If the compiler is still unknown, try to query its vendor.
47
  if(CMAKE_${lang}_COMPILER AND NOT CMAKE_${lang}_COMPILER_ID)
48
    CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang})
49
  endif()
50

51
  # if the format is unknown after all files have been checked, put "Unknown" in the cache
52
53
  if(NOT CMAKE_EXECUTABLE_FORMAT)
    set(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
54
  endif()
55
56

  # Display the final identification result.
57
58
59
60
61
62
63
  if(CMAKE_${lang}_COMPILER_ID)
    if(CMAKE_${lang}_COMPILER_VERSION)
      set(_version " ${CMAKE_${lang}_COMPILER_VERSION}")
    else()
      set(_version "")
    endif()
    message(STATUS "The ${lang} compiler identification is "
64
      "${CMAKE_${lang}_COMPILER_ID}${_version}")
65
  else()
66
    message(STATUS "The ${lang} compiler identification is unknown")
67
  endif()
68

69
  # Check if compiler id detection gave us the compiler tool.
70
71
72
73
  if(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)
74
75
  endif()

76
77
78
  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
  set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
79
    PARENT_SCOPE)
80
  set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
81
82
  set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
83
endfunction()
84

85
86
#-----------------------------------------------------------------------------
# Function to write the compiler id source file.
87
function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
88
89
90
  find_file(src_in ${src}.in PATHS ${CMAKE_ROOT}/Modules ${CMAKE_MODULE_PATH} NO_DEFAULT_PATH)
  file(READ ${src_in} ID_CONTENT_IN)
  unset(src_in CACHE)
91
92
  string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
  file(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
93
endfunction()
94

95
96
97
#-----------------------------------------------------------------------------
# Function to build the compiler id source file and look for output
# files.
98
function(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
99
  # Create a clean working directory.
100
101
  file(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
  file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
102
  CMAKE_DETERMINE_COMPILER_ID_WRITE("${lang}" "${src}")
103

104
  # Construct a description of this test case.
105
  set(COMPILER_DESCRIPTION
106
107
108
109
    "Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}
Build flags: ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
Id flags: ${testflags}
")
110

111
  # Compile the compiler identification source.
112
113
114
115
116
  if(CMAKE_GENERATOR STREQUAL "Visual Studio 6" AND
      lang STREQUAL "Fortran")
    set(CMAKE_${lang}_COMPILER_ID_RESULT 1)
    set(CMAKE_${lang}_COMPILER_ID_OUTPUT "No Intel Fortran in VS 6")
  elseif("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)")
117
    set(vs_version ${CMAKE_MATCH_1})
118
    set(id_platform ${CMAKE_VS_PLATFORM_NAME})
119
120
    set(id_lang "${lang}")
    set(id_cl cl.exe)
121
122
123
124
125
    if(lang STREQUAL Fortran)
      set(v Intel)
      set(ext vfproj)
      set(id_cl ifort.exe)
    elseif(NOT "${vs_version}" VERSION_LESS 10)
126
127
128
129
130
131
132
133
134
135
      set(v 10)
      set(ext vcxproj)
    elseif(NOT "${vs_version}" VERSION_LESS 7)
      set(id_version ${vs_version}.00)
      set(v 7)
      set(ext vcproj)
    else()
      set(v 6)
      set(ext dsp)
    endif()
136
137
    if("${id_platform}" STREQUAL "Itanium")
      set(id_platform ia64)
138
139
140
    endif()
    if(CMAKE_VS_PLATFORM_TOOLSET)
      set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
141
142
143
      if(CMAKE_VS_PLATFORM_TOOLSET MATCHES "Intel")
        set(id_cl icl.exe)
      endif()
144
145
146
    else()
      set(id_toolset "")
    endif()
147
    if(CMAKE_VS_WINCE_VERSION)
148
      set(id_entrypoint "mainACRTStartup")
149
150
151
152
153
      if("${vs_version}" VERSION_LESS 9)
        set(id_subsystem 9)
      else()
        set(id_subsystem 8)
      endif()
154
155
    else()
      set(id_subsystem 1)
156
    endif()
157
    if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]")
158
      set(build /p:Configuration=Debug /p:Platform=@id_platform@ /p:VisualStudioVersion=${vs_version}.0)
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    elseif("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Dd][Ee][Vv]")
      set(build /make)
    else()
      set(build /build Debug)
    endif()
    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
    get_filename_component(id_src "${src}" NAME)
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/VS-${v}.${ext}.in
      ${id_dir}/CompilerId${lang}.${ext} @ONLY IMMEDIATE)
    execute_process(
      COMMAND ${CMAKE_MAKE_PROGRAM} CompilerId${lang}.${ext} ${build}
      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
      )
    # Match the compiler location line printed out.
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "CMAKE_${lang}_COMPILER=([^%\r\n]+)[\r\n]")
177
178
      # Strip VS diagnostic output from the end of the line.
      string(REGEX REPLACE " \\(TaskId:[0-9]*\\)$" "" _comp "${CMAKE_MATCH_1}")
179
180
181
182
183
184
      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")
185
186
187
188
    set(id_lang "${lang}")
    set(id_type ${CMAKE_${lang}_COMPILER_XCODE_TYPE})
    set(id_dir ${CMAKE_${lang}_COMPILER_ID_DIR})
    get_filename_component(id_src "${src}" NAME)
189
190
191
192
193
    if(CMAKE_XCODE_PLATFORM_TOOLSET)
      set(id_toolset "GCC_VERSION = ${CMAKE_XCODE_PLATFORM_TOOLSET};")
    else()
      set(id_toolset "")
    endif()
194
195
196
197
198
199
200
201
202
203
204
205
    if(NOT ${XCODE_VERSION} VERSION_LESS 3)
      set(v 3)
      set(ext xcodeproj)
    elseif(NOT ${XCODE_VERSION} VERSION_LESS 2)
      set(v 2)
      set(ext xcodeproj)
    else()
      set(v 1)
      set(ext xcode)
    endif()
    configure_file(${CMAKE_ROOT}/Modules/CompilerId/Xcode-${v}.pbxproj.in
      ${id_dir}/CompilerId${lang}.${ext}/project.pbxproj @ONLY IMMEDIATE)
206
207
208
209
210
    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()
211
212
213
214
215
216
    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
      )
217
218
219
    if(DEFINED _ENV_MACOSX_DEPLOYMENT_TARGET)
      set(ENV{MACOSX_DEPLOYMENT_TARGET} "${_ENV_MACOSX_DEPLOYMENT_TARGET}")
    endif()
220
221
222
223
224
225
226
227
228
229
230
231

    # Match the link line from xcodebuild output of the form
    #  Ld ...
    #      ...
    #      /path/to/cc ...CompilerId${lang}/...
    # to extract the compiler front-end for the language.
    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "\nLd[^\n]*(\n[ \t]+[^\n]*)*\n[ \t]+([^ \t\r\n]+)[^\r\n]*-o[^\r\n]*CompilerId${lang}/\\./CompilerId${lang}[ \t\n\\\"]")
      set(_comp "${CMAKE_MATCH_2}")
      if(EXISTS "${_comp}")
        set(CMAKE_${lang}_COMPILER_ID_TOOL "${_comp}" PARENT_SCOPE)
      endif()
    endif()
232
  else()
233
234
    if(COMMAND EXECUTE_PROCESS)
      execute_process(
235
        COMMAND "${CMAKE_${lang}_COMPILER}"
236
237
238
239
240
241
242
243
244
245
246
                ${CMAKE_${lang}_COMPILER_ID_ARG1}
                ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
                ${testflags}
                "${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
        )
    else()
      exec_program(
247
        "${CMAKE_${lang}_COMPILER}" ${CMAKE_${lang}_COMPILER_ID_DIR}
248
249
250
251
252
253
254
255
        ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
             ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
             ${testflags}
             \"${src}\"
        OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
        RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
        )
    endif()
256
  endif()
257
258

  # Check the result of compilation.
259
260
261
262
  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"
     )
263
    # Compilation failed.
264
    set(MSG
265
266
267
268
269
270
271
      "Compiling the ${lang} compiler identification source file \"${src}\" failed.
${COMPILER_DESCRIPTION}
The output was:
${CMAKE_${lang}_COMPILER_ID_RESULT}
${CMAKE_${lang}_COMPILER_ID_OUTPUT}

")
272
273
274
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
    #if(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
    #  message(FATAL_ERROR "${MSG}")
275
    #endif()
276
277

    # No output files should be inspected.
278
    set(COMPILER_${lang}_PRODUCED_FILES)
279
  else()
280
    # Compilation succeeded.
281
    file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
282
283
284
285
286
287
288
      "Compiling the ${lang} compiler identification source file \"${src}\" succeeded.
${COMPILER_DESCRIPTION}
The output was:
${CMAKE_${lang}_COMPILER_ID_RESULT}
${CMAKE_${lang}_COMPILER_ID_OUTPUT}

")
289

290
291
    # Find the executable produced by the compiler, try all files in the
    # binary dir.
292
    file(GLOB files
293
294
      RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
      ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
295
296
297
298
299
300
301
302
303
    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()
304
    endforeach()
305

306
    if(NOT COMPILER_${lang}_PRODUCED_FILES)
Alexander Neundorf's avatar
   
Alexander Neundorf committed
307
      # No executable was found.
308
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
309
        "Compilation of the ${lang} compiler identification source \""
310
        "${src}\" did not produce an executable in \""
311
        "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
312
313
    endif()
  endif()
314

315
  # Return the files produced by the compilation.
316
  set(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
317
endfunction()
318
319
320

#-----------------------------------------------------------------------------
# Function to extract the compiler id from an executable.
321
function(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
322
  # Look for a compiler id if not yet known.
323
  if(NOT CMAKE_${lang}_COMPILER_ID)
324
    # Read the compiler identification string from the executable file.
325
326
327
    set(COMPILER_ID)
    set(COMPILER_VERSION)
    set(PLATFORM_ID)
328
    set(ARCHITECTURE_ID)
329
330
    set(SIMULATE_ID)
    set(SIMULATE_VERSION)
331
    file(STRINGS ${file}
332
      CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 6 REGEX "INFO:")
333
    set(COMPILER_ID_TWICE)
334
335
336
337
    foreach(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
      if("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
        if(COMPILER_ID)
          set(COMPILER_ID_TWICE 1)
338
        endif()
339
        string(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
340
          COMPILER_ID "${info}")
341
      endif()
342
343
      if("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
        string(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
344
          PLATFORM_ID "${info}")
345
      endif()
346
347
      if("${info}" MATCHES ".*INFO:arch\\[([^]\"]*)\\].*")
        string(REGEX REPLACE ".*INFO:arch\\[([^]]*)\\].*" "\\1"
348
          ARCHITECTURE_ID "${info}")
349
      endif()
350
351
352
353
      if("${info}" MATCHES ".*INFO:compiler_version\\[([^]\"]*)\\].*")
        string(REGEX REPLACE ".*INFO:compiler_version\\[([^]]*)\\].*" "\\1" COMPILER_VERSION "${info}")
        string(REGEX REPLACE "^0+([0-9])" "\\1" COMPILER_VERSION "${COMPILER_VERSION}")
        string(REGEX REPLACE "\\.0+([0-9])" ".\\1" COMPILER_VERSION "${COMPILER_VERSION}")
354
      endif()
355
356
357
358
359
360
361
362
      if("${info}" MATCHES ".*INFO:simulate\\[([^]\"]*)\\].*")
        set(SIMULATE_ID "${CMAKE_MATCH_1}")
      endif()
      if("${info}" MATCHES ".*INFO:simulate_version\\[([^]\"]*)\\].*")
        set(SIMULATE_VERSION "${CMAKE_MATCH_1}")
        string(REGEX REPLACE "^0+([0-9])" "\\1" SIMULATE_VERSION "${SIMULATE_VERSION}")
        string(REGEX REPLACE "\\.0+([0-9])" ".\\1" SIMULATE_VERSION "${SIMULATE_VERSION}")
      endif()
363
    endforeach()
364

365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
    # 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)
      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")
      elseif(peheader STREQUAL "50450000c201")
        set(ARCHITECTURE_ID "THUMB")
      endif()
    endif()

394
    # Check if a valid compiler and platform were found.
395
396
397
398
399
    if(COMPILER_ID AND NOT COMPILER_ID_TWICE)
      set(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
      set(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
      set(MSVC_${lang}_ARCHITECTURE_ID "${ARCHITECTURE_ID}")
      set(CMAKE_${lang}_COMPILER_VERSION "${COMPILER_VERSION}")
400
401
      set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}")
      set(CMAKE_${lang}_SIMULATE_VERSION "${SIMULATE_VERSION}")
402
    endif()
403
404

    # Check the compiler identification string.
405
    if(CMAKE_${lang}_COMPILER_ID)
406
      # The compiler identification was found.
407
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
408
409
        "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
        "${file}\"\n\n")
410
    else()
411
      # The compiler identification could not be found.
412
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
413
414
        "The ${lang} compiler identification could not be found in \""
        "${file}\"\n\n")
415
416
    endif()
  endif()
417
418

  # try to figure out the executable format: ELF, COFF, Mach-O
419
420
  if(NOT CMAKE_EXECUTABLE_FORMAT)
    file(READ ${file} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
421
422

    # ELF files start with 0x7f"ELF"
423
424
    if("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
      set(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE INTERNAL "Executable file format")
425
    endif()
426
427

#    # COFF (.exe) files start with "MZ"
428
429
#    if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
#      set(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
430
#    endif()
431
432
#
#    # Mach-O files start with CAFEBABE or FEEDFACE, according to http://radio.weblogs.com/0100490/2003/01/28.html
433
434
#    if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
#      set(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
435
#    endif()
436
437
#    if("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
#      set(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
438
#    endif()
439

440
  endif()
441
442
443
  if(NOT DEFINED CMAKE_EXECUTABLE_FORMAT)
    set(CMAKE_EXECUTABLE_FORMAT)
  endif()
444
  # Return the information extracted.
445
446
447
  set(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
  set(MSVC_${lang}_ARCHITECTURE_ID "${MSVC_${lang}_ARCHITECTURE_ID}"
448
    PARENT_SCOPE)
449
  set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
450
451
  set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
452
  set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
453
endfunction()
454
455
456
457
458
459
460
461
462

#-----------------------------------------------------------------------------
# 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.
463
function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
464

465
  if(NOT CMAKE_${lang}_COMPILER_ID_DIR)
466
467
468
    # 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.
469
    set(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_PLATFORM_INFO_DIR}/CompilerId${lang})
470
471
    file(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
    file(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
472
  endif()
473
474


475
476
477
478
  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(
479
      COMMAND "${CMAKE_${lang}_COMPILER}"
480
481
482
483
484
485
      ${CMAKE_${lang}_COMPILER_ID_ARG1}
      ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
      ${flags}
      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
      OUTPUT_VARIABLE output ERROR_VARIABLE output
      RESULT_VARIABLE result
486
      TIMEOUT 10
487
      )
488

489
490
    if("${output}" MATCHES "${regex}")
      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
491
492
        "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
        "matched \"${regex}\":\n${output}")
493
494
495
496
497
      set(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
      break()
    else()
      if("${result}" MATCHES  "timeout")
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
498
499
          "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
          "terminated after 10 s due to timeout.")
500
501
      else()
        file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
502
503
          "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
          "did not match \"${regex}\":\n${output}")
504
505
506
       endif()
    endif()
  endforeach()
507
endfunction()