CMakeDetermineCompilerId.cmake 20.6 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.
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 88 89 90
function(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
  file(READ ${CMAKE_ROOT}/Modules/${src}.in ID_CONTENT_IN)
  string(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
  file(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
91
endfunction()
92

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

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

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

    # 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()
230
  else()
231 232
    if(COMMAND EXECUTE_PROCESS)
      execute_process(
233
        COMMAND "${CMAKE_${lang}_COMPILER}"
234 235 236 237 238 239 240 241 242 243 244
                ${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(
245
        "${CMAKE_${lang}_COMPILER}" ${CMAKE_${lang}_COMPILER_ID_DIR}
246 247 248 249 250 251 252 253
        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()
254
  endif()
255 256

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

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

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

")
287

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

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

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

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

363 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
    # 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()

392
    # Check if a valid compiler and platform were found.
393 394 395 396 397
    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}")
398 399
      set(CMAKE_${lang}_SIMULATE_ID "${SIMULATE_ID}")
      set(CMAKE_${lang}_SIMULATE_VERSION "${SIMULATE_VERSION}")
400
    endif()
401 402

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

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

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

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

438
  endif()
439 440 441
  if(NOT DEFINED CMAKE_EXECUTABLE_FORMAT)
    set(CMAKE_EXECUTABLE_FORMAT)
  endif()
442
  # Return the information extracted.
443 444 445
  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}"
446
    PARENT_SCOPE)
447
  set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_${lang}_COMPILER_VERSION}" PARENT_SCOPE)
448 449
  set(CMAKE_${lang}_SIMULATE_ID "${CMAKE_${lang}_SIMULATE_ID}" PARENT_SCOPE)
  set(CMAKE_${lang}_SIMULATE_VERSION "${CMAKE_${lang}_SIMULATE_VERSION}" PARENT_SCOPE)
450
  set(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
451
endfunction()
452 453 454 455 456 457 458 459 460

#-----------------------------------------------------------------------------
# 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.
461
function(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
462

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


473 474 475 476
  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(
477
      COMMAND "${CMAKE_${lang}_COMPILER}"
478 479 480 481 482 483
      ${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
484
      TIMEOUT 10
485
      )
486

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