瀏覽代碼

Merge topic 'ide-compiler-id'

403ead6 Document CMAKE_<LANG>_COMPILER_(ID|VERSION) values
8be51f6 Test variables CMAKE_(C|CXX|Fortran)_COMPILER(|_ID|_VERSION)
ec22a9b Cleanly enable a language in multiple subdirectories
66cb335 VS: Detect the compiler id and tool location
89595d6 VS10: Define CMAKE_VS_PLATFORM_TOOLSET variable
965a69d Xcode: Detect the compiler id and tool location
9a9e1ee CMakeDetermineCompilerId: Prepare to detect IDE compiler id
b8b5c83 Re-order C/C++/Fortran compiler determination logic
David Cole 13 年之前
父節點
當前提交
34a0284603

+ 57 - 58
Modules/CMakeDetermineCCompiler.cmake

@@ -39,76 +39,66 @@ if(NOT CMAKE_C_COMPILER_NAMES)
   set(CMAKE_C_COMPILER_NAMES cc)
 endif()
 
-if(NOT CMAKE_C_COMPILER)
-  set(CMAKE_C_COMPILER_INIT NOTFOUND)
-
-  # prefer the environment variable CC
-  if($ENV{CC} MATCHES ".+")
-    get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT)
-    if(CMAKE_C_FLAGS_ENV_INIT)
-      set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "First argument to C compiler")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+  set(CMAKE_C_COMPILER_XCODE_TYPE sourcecode.c.c)
+else()
+  if(NOT CMAKE_C_COMPILER)
+    set(CMAKE_C_COMPILER_INIT NOTFOUND)
+
+    # prefer the environment variable CC
+    if($ENV{CC} MATCHES ".+")
+      get_filename_component(CMAKE_C_COMPILER_INIT $ENV{CC} PROGRAM PROGRAM_ARGS CMAKE_C_FLAGS_ENV_INIT)
+      if(CMAKE_C_FLAGS_ENV_INIT)
+        set(CMAKE_C_COMPILER_ARG1 "${CMAKE_C_FLAGS_ENV_INIT}" CACHE STRING "First argument to C compiler")
+      endif()
+      if(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
+        message(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.")
+      endif()
     endif()
-    if(NOT EXISTS ${CMAKE_C_COMPILER_INIT})
-      message(FATAL_ERROR "Could not find compiler set in environment variable CC:\n$ENV{CC}.")
+
+    # next try prefer the compiler specified by the generator
+    if(CMAKE_GENERATOR_CC)
+      if(NOT CMAKE_C_COMPILER_INIT)
+        set(CMAKE_C_COMPILER_INIT ${CMAKE_GENERATOR_CC})
+      endif()
     endif()
-  endif()
 
-  # next try prefer the compiler specified by the generator
-  if(CMAKE_GENERATOR_CC)
+    # finally list compilers to try
     if(NOT CMAKE_C_COMPILER_INIT)
-      set(CMAKE_C_COMPILER_INIT ${CMAKE_GENERATOR_CC})
+      set(CMAKE_C_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc cl bcc xlc clang)
     endif()
-  endif()
-
-  # finally list compilers to try
-  if(NOT CMAKE_C_COMPILER_INIT)
-    set(CMAKE_C_COMPILER_LIST ${_CMAKE_TOOLCHAIN_PREFIX}cc ${_CMAKE_TOOLCHAIN_PREFIX}gcc cl bcc xlc clang)
-  endif()
 
-  _cmake_find_compiler(C)
+    _cmake_find_compiler(C)
 
-else()
+  else()
 
-  # we only get here if CMAKE_C_COMPILER was specified using -D or a pre-made CMakeCache.txt
-  # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-  # if CMAKE_C_COMPILER is a list of length 2, use the first item as
-  # CMAKE_C_COMPILER and the 2nd one as CMAKE_C_COMPILER_ARG1
+    # we only get here if CMAKE_C_COMPILER was specified using -D or a pre-made CMakeCache.txt
+    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+    # if CMAKE_C_COMPILER is a list of length 2, use the first item as
+    # CMAKE_C_COMPILER and the 2nd one as CMAKE_C_COMPILER_ARG1
 
-  list(LENGTH CMAKE_C_COMPILER _CMAKE_C_COMPILER_LIST_LENGTH)
-  if("${_CMAKE_C_COMPILER_LIST_LENGTH}" EQUAL 2)
-    list(GET CMAKE_C_COMPILER 1 CMAKE_C_COMPILER_ARG1)
-    list(GET CMAKE_C_COMPILER 0 CMAKE_C_COMPILER)
-  endif()
+    list(LENGTH CMAKE_C_COMPILER _CMAKE_C_COMPILER_LIST_LENGTH)
+    if("${_CMAKE_C_COMPILER_LIST_LENGTH}" EQUAL 2)
+      list(GET CMAKE_C_COMPILER 1 CMAKE_C_COMPILER_ARG1)
+      list(GET CMAKE_C_COMPILER 0 CMAKE_C_COMPILER)
+    endif()
 
-  # if a compiler was specified by the user but without path,
-  # now try to find it with the full path
-  # if it is found, force it into the cache,
-  # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
-  # if the C compiler already had a path, reuse it for searching the CXX compiler
-  get_filename_component(_CMAKE_USER_C_COMPILER_PATH "${CMAKE_C_COMPILER}" PATH)
-  if(NOT _CMAKE_USER_C_COMPILER_PATH)
-    find_program(CMAKE_C_COMPILER_WITH_PATH NAMES ${CMAKE_C_COMPILER})
-    mark_as_advanced(CMAKE_C_COMPILER_WITH_PATH)
-    if(CMAKE_C_COMPILER_WITH_PATH)
-      set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER_WITH_PATH} CACHE STRING "C compiler" FORCE)
+    # if a compiler was specified by the user but without path,
+    # now try to find it with the full path
+    # if it is found, force it into the cache,
+    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
+    # if the C compiler already had a path, reuse it for searching the CXX compiler
+    get_filename_component(_CMAKE_USER_C_COMPILER_PATH "${CMAKE_C_COMPILER}" PATH)
+    if(NOT _CMAKE_USER_C_COMPILER_PATH)
+      find_program(CMAKE_C_COMPILER_WITH_PATH NAMES ${CMAKE_C_COMPILER})
+      mark_as_advanced(CMAKE_C_COMPILER_WITH_PATH)
+      if(CMAKE_C_COMPILER_WITH_PATH)
+        set(CMAKE_C_COMPILER ${CMAKE_C_COMPILER_WITH_PATH} CACHE STRING "C compiler" FORCE)
+      endif()
     endif()
   endif()
-endif()
-mark_as_advanced(CMAKE_C_COMPILER)
-
-if (NOT _CMAKE_TOOLCHAIN_LOCATION)
-  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
-endif ()
-
-# Build a small source file to identify the compiler.
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
-  set(CMAKE_C_COMPILER_ID_RUN 1)
-  set(CMAKE_C_PLATFORM_ID "Windows")
-  set(CMAKE_C_COMPILER_ID "MSVC")
-endif()
-
-if(NOT CMAKE_C_COMPILER_ID_RUN)
-  set(CMAKE_C_COMPILER_ID_RUN 1)
+  mark_as_advanced(CMAKE_C_COMPILER)
 
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
@@ -120,6 +110,11 @@ if(NOT CMAKE_C_COMPILER_ID_RUN)
     # Try enabling ANSI mode on HP.
     "-Aa"
     )
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_C_COMPILER_ID_RUN)
+  set(CMAKE_C_COMPILER_ID_RUN 1)
 
   # Try to identify the compiler.
   set(CMAKE_C_COMPILER_ID)
@@ -139,6 +134,10 @@ if(NOT CMAKE_C_COMPILER_ID_RUN)
   endif()
 endif()
 
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_C_COMPILER}" PATH)
+endif ()
+
 # If we have a gcc cross compiler, they have usually some prefix, like
 # e.g. powerpc-linux-gcc, arm-elf-gcc or i586-mingw32msvc-gcc, optionally
 # with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).

+ 58 - 70
Modules/CMakeDetermineCXXCompiler.cmake

@@ -38,87 +38,66 @@ if(NOT CMAKE_CXX_COMPILER_NAMES)
   set(CMAKE_CXX_COMPILER_NAMES CC)
 endif()
 
-if(NOT CMAKE_CXX_COMPILER)
-  set(CMAKE_CXX_COMPILER_INIT NOTFOUND)
-
-  # prefer the environment variable CXX
-  if($ENV{CXX} MATCHES ".+")
-    get_filename_component(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
-    if(CMAKE_CXX_FLAGS_ENV_INIT)
-      set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+  set(CMAKE_CXX_COMPILER_XCODE_TYPE sourcecode.cpp.cpp)
+else()
+  if(NOT CMAKE_CXX_COMPILER)
+    set(CMAKE_CXX_COMPILER_INIT NOTFOUND)
+
+    # prefer the environment variable CXX
+    if($ENV{CXX} MATCHES ".+")
+      get_filename_component(CMAKE_CXX_COMPILER_INIT $ENV{CXX} PROGRAM PROGRAM_ARGS CMAKE_CXX_FLAGS_ENV_INIT)
+      if(CMAKE_CXX_FLAGS_ENV_INIT)
+        set(CMAKE_CXX_COMPILER_ARG1 "${CMAKE_CXX_FLAGS_ENV_INIT}" CACHE STRING "First argument to CXX compiler")
+      endif()
+      if(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
+        message(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
+      endif()
     endif()
-    if(NOT EXISTS ${CMAKE_CXX_COMPILER_INIT})
-      message(FATAL_ERROR "Could not find compiler set in environment variable CXX:\n$ENV{CXX}.\n${CMAKE_CXX_COMPILER_INIT}")
+
+    # next prefer the generator specified compiler
+    if(CMAKE_GENERATOR_CXX)
+      if(NOT CMAKE_CXX_COMPILER_INIT)
+        set(CMAKE_CXX_COMPILER_INIT ${CMAKE_GENERATOR_CXX})
+      endif()
     endif()
-  endif()
 
-  # next prefer the generator specified compiler
-  if(CMAKE_GENERATOR_CXX)
+    # finally list compilers to try
     if(NOT CMAKE_CXX_COMPILER_INIT)
-      set(CMAKE_CXX_COMPILER_INIT ${CMAKE_GENERATOR_CXX})
+      set(CMAKE_CXX_COMPILER_LIST CC ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ aCC cl bcc xlC clang++)
     endif()
-  endif()
 
-  # finally list compilers to try
-  if(NOT CMAKE_CXX_COMPILER_INIT)
-    set(CMAKE_CXX_COMPILER_LIST CC ${_CMAKE_TOOLCHAIN_PREFIX}c++ ${_CMAKE_TOOLCHAIN_PREFIX}g++ aCC cl bcc xlC clang++)
-  endif()
-
-  _cmake_find_compiler(CXX)
-else()
+    _cmake_find_compiler(CXX)
+  else()
 
-# we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
-# (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-#
-# if CMAKE_CXX_COMPILER is a list of length 2, use the first item as
-# CMAKE_CXX_COMPILER and the 2nd one as CMAKE_CXX_COMPILER_ARG1
+    # we only get here if CMAKE_CXX_COMPILER was specified using -D or a pre-made CMakeCache.txt
+    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+    #
+    # if CMAKE_CXX_COMPILER is a list of length 2, use the first item as
+    # CMAKE_CXX_COMPILER and the 2nd one as CMAKE_CXX_COMPILER_ARG1
 
-  list(LENGTH CMAKE_CXX_COMPILER _CMAKE_CXX_COMPILER_LIST_LENGTH)
-  if("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)
-    list(GET CMAKE_CXX_COMPILER 1 CMAKE_CXX_COMPILER_ARG1)
-    list(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER)
-  endif()
+    list(LENGTH CMAKE_CXX_COMPILER _CMAKE_CXX_COMPILER_LIST_LENGTH)
+    if("${_CMAKE_CXX_COMPILER_LIST_LENGTH}" EQUAL 2)
+      list(GET CMAKE_CXX_COMPILER 1 CMAKE_CXX_COMPILER_ARG1)
+      list(GET CMAKE_CXX_COMPILER 0 CMAKE_CXX_COMPILER)
+    endif()
 
-# if a compiler was specified by the user but without path,
-# now try to find it with the full path
-# if it is found, force it into the cache,
-# if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
-# if the CXX compiler already had a path, reuse it for searching the C compiler
-  get_filename_component(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
-  if(NOT _CMAKE_USER_CXX_COMPILER_PATH)
-    find_program(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER})
-    mark_as_advanced(CMAKE_CXX_COMPILER_WITH_PATH)
-    if(CMAKE_CXX_COMPILER_WITH_PATH)
-      set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE STRING "CXX compiler" FORCE)
+    # if a compiler was specified by the user but without path,
+    # now try to find it with the full path
+    # if it is found, force it into the cache,
+    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
+    # if the CXX compiler already had a path, reuse it for searching the C compiler
+    get_filename_component(_CMAKE_USER_CXX_COMPILER_PATH "${CMAKE_CXX_COMPILER}" PATH)
+    if(NOT _CMAKE_USER_CXX_COMPILER_PATH)
+      find_program(CMAKE_CXX_COMPILER_WITH_PATH NAMES ${CMAKE_CXX_COMPILER})
+      mark_as_advanced(CMAKE_CXX_COMPILER_WITH_PATH)
+      if(CMAKE_CXX_COMPILER_WITH_PATH)
+        set(CMAKE_CXX_COMPILER ${CMAKE_CXX_COMPILER_WITH_PATH} CACHE STRING "CXX compiler" FORCE)
+      endif()
     endif()
   endif()
-endif()
-mark_as_advanced(CMAKE_CXX_COMPILER)
-
-if (NOT _CMAKE_TOOLCHAIN_LOCATION)
-  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
-endif ()
-
-# This block was used before the compiler was identified by building a
-# source file.  Unless g++ crashes when building a small C++
-# executable this should no longer be needed.
-#
-# The g++ that comes with BeOS 5 segfaults if you run "g++ -E"
-#  ("gcc -E" is fine), which throws up a system dialog box that hangs cmake
-#  until the user clicks "OK"...so for now, we just assume it's g++.
-# if(BEOS)
-#   set(CMAKE_COMPILER_IS_GNUCXX 1)
-#   set(CMAKE_COMPILER_IS_GNUCXX_RUN 1)
-# endif()
-
-# Build a small source file to identify the compiler.
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
-  set(CMAKE_CXX_COMPILER_ID_RUN 1)
-  set(CMAKE_CXX_PLATFORM_ID "Windows")
-  set(CMAKE_CXX_COMPILER_ID "MSVC")
-endif()
-if(NOT CMAKE_CXX_COMPILER_ID_RUN)
-  set(CMAKE_CXX_COMPILER_ID_RUN 1)
+  mark_as_advanced(CMAKE_CXX_COMPILER)
 
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
@@ -127,6 +106,11 @@ if(NOT CMAKE_CXX_COMPILER_ID_RUN)
     # Try compiling to an object file only.
     "-c"
     )
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_CXX_COMPILER_ID_RUN)
+  set(CMAKE_CXX_COMPILER_ID_RUN 1)
 
   # Try to identify the compiler.
   set(CMAKE_CXX_COMPILER_ID)
@@ -146,6 +130,10 @@ if(NOT CMAKE_CXX_COMPILER_ID_RUN)
   endif()
 endif()
 
+if (NOT _CMAKE_TOOLCHAIN_LOCATION)
+  get_filename_component(_CMAKE_TOOLCHAIN_LOCATION "${CMAKE_CXX_COMPILER}" PATH)
+endif ()
+
 # if we have a g++ cross compiler, they have usually some prefix, like
 # e.g. powerpc-linux-g++, arm-elf-g++ or i586-mingw32msvc-g++ , optionally
 # with a 3-component version number at the end (e.g. arm-eabi-gcc-4.5.2).

+ 131 - 20
Modules/CMakeDetermineCompilerId.cmake

@@ -66,6 +66,15 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     message(STATUS "The ${lang} compiler identification is unknown")
   endif()
 
+  # Check if compiler id detection gave us the compiler tool.
+  if(NOT CMAKE_${lang}_COMPILER)
+    if(CMAKE_${lang}_COMPILER_ID_TOOL)
+      set(CMAKE_${lang}_COMPILER "${CMAKE_${lang}_COMPILER_ID_TOOL}" PARENT_SCOPE)
+    else()
+      set(CMAKE_${lang}_COMPILER "CMAKE_${lang}_COMPILER-NOTFOUND" PARENT_SCOPE)
+    endif()
+  endif()
+
   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}"
@@ -98,28 +107,126 @@ Id flags: ${testflags}
 ")
 
   # Compile the compiler identification source.
-  if(COMMAND EXECUTE_PROCESS)
+  if("${CMAKE_GENERATOR}" MATCHES "Visual Studio ([0-9]+)( .NET)?( 200[358])? *((Win64|IA64|ARM))?")
+    set(vs_version ${CMAKE_MATCH_1})
+    set(vs_arch ${CMAKE_MATCH_4})
+    set(id_lang "${lang}")
+    set(id_cl cl.exe)
+    if(NOT "${vs_version}" VERSION_LESS 10)
+      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()
+    if("${vs_arch}" STREQUAL "Win64")
+      set(id_machine_7 17)
+      set(id_machine_10 MachineX64)
+      set(id_arch x64)
+    elseif("${vs_arch}" STREQUAL "IA64")
+      set(id_machine_7 5)
+      set(id_machine_10 MachineIA64)
+      set(id_arch ia64)
+    else()
+      set(id_machine_6 x86)
+      set(id_machine_7 1)
+      set(id_machine_10 MachineX86)
+      set(id_arch Win32)
+    endif()
+    if(CMAKE_VS_PLATFORM_TOOLSET)
+      set(id_toolset "<PlatformToolset>${CMAKE_VS_PLATFORM_TOOLSET}</PlatformToolset>")
+    else()
+      set(id_toolset "")
+    endif()
+    if("${CMAKE_MAKE_PROGRAM}" MATCHES "[Mm][Ss][Bb][Uu][Ii][Ll][Dd]")
+      set(build /p:Configuration=Debug /p:Platform=@id_arch@)
+    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_${lang}_COMPILER}
-              ${CMAKE_${lang}_COMPILER_ID_ARG1}
-              ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
-              ${testflags}
-              "${src}"
+      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
       )
-  else()
-    exec_program(
-      ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_DIR}
-      ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
-           ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
-           ${testflags}
-           \"${src}\"
+    # Match the compiler location line printed out.
+    if("${CMAKE_${lang}_COMPILER_ID_OUTPUT}" MATCHES "CMAKE_${lang}_COMPILER=([^%\r\n]+)[\r\n]")
+      set(_comp "${CMAKE_MATCH_1}")
+      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")
+    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)
+    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)
+    execute_process(COMMAND xcodebuild
+      WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
       OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
-      RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
+      ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
+      RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
       )
+
+    # 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()
+  else()
+    if(COMMAND EXECUTE_PROCESS)
+      execute_process(
+        COMMAND ${CMAKE_${lang}_COMPILER}
+                ${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(
+        ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_DIR}
+        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()
   endif()
 
   # Check the result of compilation.
@@ -153,14 +260,18 @@ ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
 
     # Find the executable produced by the compiler, try all files in the
     # binary dir.
-    file(GLOB COMPILER_${lang}_PRODUCED_FILES
+    file(GLOB files
       RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
       ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
-    list(REMOVE_ITEM COMPILER_${lang}_PRODUCED_FILES "${src}")
-    foreach(file ${COMPILER_${lang}_PRODUCED_FILES})
-      file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
-        "Compilation of the ${lang} compiler identification source \""
-        "${src}\" produced \"${file}\"\n\n")
+    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()
     endforeach()
 
     if(NOT COMPILER_${lang}_PRODUCED_FILES)

+ 90 - 88
Modules/CMakeDetermineFortranCompiler.cmake

@@ -25,105 +25,102 @@ if(NOT CMAKE_Fortran_COMPILER_NAMES)
   set(CMAKE_Fortran_COMPILER_NAMES f95)
 endif()
 
-if(NOT CMAKE_Fortran_COMPILER)
-  # prefer the environment variable CC
-  if($ENV{FC} MATCHES ".+")
-    get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
-    if(CMAKE_Fortran_FLAGS_ENV_INIT)
-      set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
+if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
+  set(CMAKE_Fortran_COMPILER_ID_RUN 1)
+  set(CMAKE_Fortran_PLATFORM_ID "Windows")
+  set(CMAKE_Fortran_COMPILER_ID "Intel")
+  set(CMAKE_Fortran_COMPILER "${CMAKE_GENERATOR_FC}")
+elseif("${CMAKE_GENERATOR}" MATCHES "Xcode")
+  set(CMAKE_Fortran_COMPILER_XCODE_TYPE sourcecode.fortran.f90)
+else()
+  if(NOT CMAKE_Fortran_COMPILER)
+    # prefer the environment variable CC
+    if($ENV{FC} MATCHES ".+")
+      get_filename_component(CMAKE_Fortran_COMPILER_INIT $ENV{FC} PROGRAM PROGRAM_ARGS CMAKE_Fortran_FLAGS_ENV_INIT)
+      if(CMAKE_Fortran_FLAGS_ENV_INIT)
+        set(CMAKE_Fortran_COMPILER_ARG1 "${CMAKE_Fortran_FLAGS_ENV_INIT}" CACHE STRING "First argument to Fortran compiler")
+      endif()
+      if(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
+      else()
+        message(FATAL_ERROR "Could not find compiler set in environment variable FC:\n$ENV{FC}.")
+      endif()
     endif()
-    if(EXISTS ${CMAKE_Fortran_COMPILER_INIT})
-    else()
-      message(FATAL_ERROR "Could not find compiler set in environment variable FC:\n$ENV{FC}.")
+
+    # next try prefer the compiler specified by the generator
+    if(CMAKE_GENERATOR_FC)
+      if(NOT CMAKE_Fortran_COMPILER_INIT)
+        set(CMAKE_Fortran_COMPILER_INIT ${CMAKE_GENERATOR_FC})
+      endif()
     endif()
-  endif()
 
-  # next try prefer the compiler specified by the generator
-  if(CMAKE_GENERATOR_FC)
+    # finally list compilers to try
     if(NOT CMAKE_Fortran_COMPILER_INIT)
-      set(CMAKE_Fortran_COMPILER_INIT ${CMAKE_GENERATOR_FC})
+      # Known compilers:
+      #  f77/f90/f95: generic compiler names
+      #  g77: GNU Fortran 77 compiler
+      #  gfortran: putative GNU Fortran 95+ compiler (in progress)
+      #  fort77: native F77 compiler under HP-UX (and some older Crays)
+      #  frt: Fujitsu F77 compiler
+      #  pathf90/pathf95/pathf2003: PathScale Fortran compiler
+      #  pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers
+      #  xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers
+      #  lf95: Lahey-Fujitsu F95 compiler
+      #  fl32: Microsoft Fortran 77 "PowerStation" compiler
+      #  af77: Apogee F77 compiler for Intergraph hardware running CLIX
+      #  epcf90: "Edinburgh Portable Compiler" F90
+      #  fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha
+      #  ifc: Intel Fortran 95 compiler for Linux/x86
+      #  efc: Intel Fortran 95 compiler for IA64
+      #
+      #  The order is 95 or newer compilers first, then 90,
+      #  then 77 or older compilers, gnu is always last in the group,
+      #  so if you paid for a compiler it is picked by default.
+      set(CMAKE_Fortran_COMPILER_LIST
+        ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95
+        fort gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77
+        frt pgf77 xlf fl32 af77 g77 f77
+        )
+
+      # Vendor-specific compiler names.
+      set(_Fortran_COMPILER_NAMES_GNU       gfortran gfortran-4 g95 g77)
+      set(_Fortran_COMPILER_NAMES_Intel     ifort ifc efc)
+      set(_Fortran_COMPILER_NAMES_Absoft    af95 af90 af77)
+      set(_Fortran_COMPILER_NAMES_PGI       pgf95 pgfortran pgf90 pgf77)
+      set(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
+      set(_Fortran_COMPILER_NAMES_XL        xlf)
+      set(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf)
     endif()
-  endif()
 
-  # finally list compilers to try
-  if(NOT CMAKE_Fortran_COMPILER_INIT)
-    # Known compilers:
-    #  f77/f90/f95: generic compiler names
-    #  g77: GNU Fortran 77 compiler
-    #  gfortran: putative GNU Fortran 95+ compiler (in progress)
-    #  fort77: native F77 compiler under HP-UX (and some older Crays)
-    #  frt: Fujitsu F77 compiler
-    #  pathf90/pathf95/pathf2003: PathScale Fortran compiler
-    #  pgf77/pgf90/pgf95/pgfortran: Portland Group F77/F90/F95 compilers
-    #  xlf/xlf90/xlf95: IBM (AIX) F77/F90/F95 compilers
-    #  lf95: Lahey-Fujitsu F95 compiler
-    #  fl32: Microsoft Fortran 77 "PowerStation" compiler
-    #  af77: Apogee F77 compiler for Intergraph hardware running CLIX
-    #  epcf90: "Edinburgh Portable Compiler" F90
-    #  fort: Compaq (now HP) Fortran 90/95 compiler for Tru64 and Linux/Alpha
-    #  ifc: Intel Fortran 95 compiler for Linux/x86
-    #  efc: Intel Fortran 95 compiler for IA64
-    #
-    #  The order is 95 or newer compilers first, then 90,
-    #  then 77 or older compilers, gnu is always last in the group,
-    #  so if you paid for a compiler it is picked by default.
-    set(CMAKE_Fortran_COMPILER_LIST
-      ifort ifc af95 af90 efc f95 pathf2003 pathf95 pgf95 pgfortran lf95 xlf95
-      fort gfortran gfortran-4 g95 f90 pathf90 pgf90 xlf90 epcf90 fort77
-      frt pgf77 xlf fl32 af77 g77 f77
-      )
-
-    # Vendor-specific compiler names.
-    set(_Fortran_COMPILER_NAMES_GNU       gfortran gfortran-4 g95 g77)
-    set(_Fortran_COMPILER_NAMES_Intel     ifort ifc efc)
-    set(_Fortran_COMPILER_NAMES_Absoft    af95 af90 af77)
-    set(_Fortran_COMPILER_NAMES_PGI       pgf95 pgfortran pgf90 pgf77)
-    set(_Fortran_COMPILER_NAMES_PathScale pathf2003 pathf95 pathf90)
-    set(_Fortran_COMPILER_NAMES_XL        xlf)
-    set(_Fortran_COMPILER_NAMES_VisualAge xlf95 xlf90 xlf)
-  endif()
+    _cmake_find_compiler(Fortran)
 
-  _cmake_find_compiler(Fortran)
+  else()
+     # we only get here if CMAKE_Fortran_COMPILER was specified using -D or a pre-made CMakeCache.txt
+    # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
+    # if CMAKE_Fortran_COMPILER is a list of length 2, use the first item as
+    # CMAKE_Fortran_COMPILER and the 2nd one as CMAKE_Fortran_COMPILER_ARG1
 
-else()
-   # we only get here if CMAKE_Fortran_COMPILER was specified using -D or a pre-made CMakeCache.txt
-  # (e.g. via ctest) or set in CMAKE_TOOLCHAIN_FILE
-  # if CMAKE_Fortran_COMPILER is a list of length 2, use the first item as
-  # CMAKE_Fortran_COMPILER and the 2nd one as CMAKE_Fortran_COMPILER_ARG1
-
-  list(LENGTH CMAKE_Fortran_COMPILER _CMAKE_Fortran_COMPILER_LIST_LENGTH)
-  if("${_CMAKE_Fortran_COMPILER_LIST_LENGTH}" EQUAL 2)
-    list(GET CMAKE_Fortran_COMPILER 1 CMAKE_Fortran_COMPILER_ARG1)
-    list(GET CMAKE_Fortran_COMPILER 0 CMAKE_Fortran_COMPILER)
-  endif()
+    list(LENGTH CMAKE_Fortran_COMPILER _CMAKE_Fortran_COMPILER_LIST_LENGTH)
+    if("${_CMAKE_Fortran_COMPILER_LIST_LENGTH}" EQUAL 2)
+      list(GET CMAKE_Fortran_COMPILER 1 CMAKE_Fortran_COMPILER_ARG1)
+      list(GET CMAKE_Fortran_COMPILER 0 CMAKE_Fortran_COMPILER)
+    endif()
 
-  # if a compiler was specified by the user but without path,
-  # now try to find it with the full path
-  # if it is found, force it into the cache,
-  # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
-  # if the C compiler already had a path, reuse it for searching the CXX compiler
-  get_filename_component(_CMAKE_USER_Fortran_COMPILER_PATH "${CMAKE_Fortran_COMPILER}" PATH)
-  if(NOT _CMAKE_USER_Fortran_COMPILER_PATH)
-    find_program(CMAKE_Fortran_COMPILER_WITH_PATH NAMES ${CMAKE_Fortran_COMPILER})
-    mark_as_advanced(CMAKE_Fortran_COMPILER_WITH_PATH)
-    if(CMAKE_Fortran_COMPILER_WITH_PATH)
-      set(CMAKE_Fortran_COMPILER ${CMAKE_Fortran_COMPILER_WITH_PATH}
-        CACHE STRING "Fortran compiler" FORCE)
+    # if a compiler was specified by the user but without path,
+    # now try to find it with the full path
+    # if it is found, force it into the cache,
+    # if not, don't overwrite the setting (which was given by the user) with "NOTFOUND"
+    # if the C compiler already had a path, reuse it for searching the CXX compiler
+    get_filename_component(_CMAKE_USER_Fortran_COMPILER_PATH "${CMAKE_Fortran_COMPILER}" PATH)
+    if(NOT _CMAKE_USER_Fortran_COMPILER_PATH)
+      find_program(CMAKE_Fortran_COMPILER_WITH_PATH NAMES ${CMAKE_Fortran_COMPILER})
+      mark_as_advanced(CMAKE_Fortran_COMPILER_WITH_PATH)
+      if(CMAKE_Fortran_COMPILER_WITH_PATH)
+        set(CMAKE_Fortran_COMPILER ${CMAKE_Fortran_COMPILER_WITH_PATH}
+          CACHE STRING "Fortran compiler" FORCE)
+      endif()
     endif()
   endif()
-endif()
-
-mark_as_advanced(CMAKE_Fortran_COMPILER)
-
-# Build a small source file to identify the compiler.
-if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
-  set(CMAKE_Fortran_COMPILER_ID_RUN 1)
-  set(CMAKE_Fortran_PLATFORM_ID "Windows")
-  set(CMAKE_Fortran_COMPILER_ID "Intel")
-endif()
-
-if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
-  set(CMAKE_Fortran_COMPILER_ID_RUN 1)
+  mark_as_advanced(CMAKE_Fortran_COMPILER)
 
   # Each entry in this list is a set of extra flags to try
   # adding to the compile line to see if it helps produce
@@ -135,6 +132,11 @@ if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
     # Intel on windows does not preprocess by default.
     "-fpp"
     )
+endif()
+
+# Build a small source file to identify the compiler.
+if(NOT CMAKE_Fortran_COMPILER_ID_RUN)
+  set(CMAKE_Fortran_COMPILER_ID_RUN 1)
 
   # Table of per-vendor compiler id flags with expected output.
   list(APPEND CMAKE_Fortran_COMPILER_ID_VENDORS Compaq)

+ 53 - 0
Modules/CompilerId/VS-10.vcxproj.in

@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|@id_arch@">
+      <Configuration>Debug</Configuration>
+      <Platform>@id_arch@</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{CAE07175-D007-4FC3-BFE8-47B392814159}</ProjectGuid>
+    <RootNamespace>CompilerId@id_lang@</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_arch@'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    @id_toolset@
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|@id_arch@'">.\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|@id_arch@'">$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|@id_arch@'">false</LinkIncremental>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|@id_arch@'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>false</MinimalRebuild>
+      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <WarningLevel>TurnOffAllWarnings</WarningLevel>
+      <DebugInformationFormat>
+      </DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <GenerateDebugInformation>false</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>@id_machine_10@</TargetMachine>
+    </Link>
+    <PostBuildEvent>
+      <Command>for %%i in (@id_cl@) do %40echo CMAKE_@id_lang@_COMPILER=%%~$PATH:i</Command>
+    </PostBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="@id_src@" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+</Project>

+ 48 - 0
Modules/CompilerId/VS-6.dsp.in

@@ -0,0 +1,48 @@
+# Microsoft Developer Studio Project File - Name="CompilerId@id_lang@" - Package Owner=<4>
+# Microsoft Developer Studio Generated Build File, Format Version 6.00
+
+# TARGTYPE "Win32 (@id_machine_6@) Application" 0x0101
+
+CFG=CompilerId@id_lang@ - Win32 Debug
+!MESSAGE This is not a valid makefile. To build this project using NMAKE,
+!MESSAGE use the Export Makefile command and run
+!MESSAGE
+!MESSAGE NMAKE /f "CompilerId@[email protected]".
+!MESSAGE
+!MESSAGE You can specify a configuration when running NMAKE
+!MESSAGE by defining the macro CFG on the command line. For example:
+!MESSAGE
+!MESSAGE NMAKE /f "CompilerId@[email protected]" CFG="CompilerId@id_lang@ - Win32 Debug"
+!MESSAGE
+!MESSAGE Possible choices for configuration are:
+!MESSAGE
+!MESSAGE "CompilerId@id_lang@ - Win32 Debug" (based on "Win32 (@id_machine_6@) Application")
+!MESSAGE
+
+# Begin Project
+# PROP AllowPerConfigDependencies 0
+CPP=cl.exe
+# PROP Use_MFC 0
+# PROP Use_Debug_Libraries 1
+# PROP Output_Dir "."
+# PROP Intermediate_Dir "Debug"
+# PROP Target_Dir ""
+# ADD CPP /nologo /MDd /c
+LINK32=link.exe
+# ADD LINK32 /nologo /version:0.0 /subsystem:console /machine:@id_machine_6@ /out:"CompilerId@[email protected]" /IGNORE:4089
+# Begin Special Build Tool
+SOURCE="$(InputPath)"
+PostBuild_Cmds=for %%i in (@id_cl@) do @echo CMAKE_@id_lang@_COMPILER=%%~$PATH:i
+# End Special Build Tool
+# Begin Target
+
+# Name "CompilerId@id_lang@ - Win32 Debug"
+# Begin Group "Source Files"
+
+# Begin Source File
+
+SOURCE="@id_src@"
+# End Source File
+# End Group
+# End Target
+# End Project

+ 60 - 0
Modules/CompilerId/VS-7.vcproj.in

@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="@id_version@"
+	Name="CompilerId@id_lang@"
+	ProjectGUID="{CAE07175-D007-4FC3-BFE8-47B392814159}"
+	RootNamespace="CompilerId@id_lang@"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="196613"
+	>
+	<Platforms>
+		<Platform
+			Name="@id_arch@"
+		/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|@id_arch@"
+			OutputDirectory="."
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="1"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				PreprocessorDefinitions=""
+				MinimalRebuild="false"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="0"
+				DebugInformationFormat="0"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="false"
+				SubSystem="1"
+				TargetMachine="@id_machine_7@"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+				CommandLine="for %%i in (@id_cl@) do @echo CMAKE_@id_lang@_COMPILER=%%~$PATH:i"
+			/>
+		</Configuration>
+	</Configurations>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath="@id_src@"
+				>
+			</File>
+		</Filter>
+	</Files>
+</VisualStudioProject>

+ 120 - 0
Modules/CompilerId/Xcode-1.pbxproj.in

@@ -0,0 +1,120 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 39;
+	objects = {
+		014CEA460018CE2711CA2923 = {
+			buildSettings = {
+			};
+			isa = PBXBuildStyle;
+			name = Development;
+		};
+		08FB7793FE84155DC02AAC07 = {
+			buildSettings = {
+			};
+			buildStyles = (
+				014CEA460018CE2711CA2923,
+			);
+			hasScannedForEncodings = 1;
+			isa = PBXProject;
+			mainGroup = 08FB7794FE84155DC02AAC07;
+			projectDirPath = "";
+			targets = (
+				8DD76FA90486AB0100D96B5E,
+			);
+		};
+		08FB7794FE84155DC02AAC07 = {
+			children = (
+				08FB7795FE84155DC02AAC07,
+				1AB674ADFE9D54B511CA2CBB,
+			);
+			isa = PBXGroup;
+			name = CompilerId@id_lang@;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		08FB7795FE84155DC02AAC07 = {
+			children = (
+				2C18F0B415DC1DC700593670,
+			);
+			isa = PBXGroup;
+			name = Source;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		1AB674ADFE9D54B511CA2CBB = {
+			children = (
+				8DD76F6C0486A84900D96B5E,
+			);
+			isa = PBXGroup;
+			name = Products;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		2C18F0B415DC1DC700593670 = {
+			fileEncoding = 30;
+			isa = PBXFileReference;
+			lastKnownFileType = @id_type@;
+			path = @id_src@;
+			refType = 4;
+			sourceTree = "<group>";
+		};
+		2C18F0B615DC1E0300593670 = {
+			fileRef = 2C18F0B415DC1DC700593670;
+			isa = PBXBuildFile;
+			settings = {
+			};
+		};
+		2C8FEB8E15DC1A1A00E56A5D = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "echo \"GCC_VERSION=$GCC_VERSION\"";
+		};
+		8DD76FA90486AB0100D96B5E = {
+			buildPhases = (
+				2C18F0B515DC1DCE00593670,
+				2C8FEB8E15DC1A1A00E56A5D,
+			);
+			buildRules = (
+			);
+			buildSettings = {
+				PRODUCT_NAME = CompilerId@id_lang@;
+				SYMROOT = .;
+			};
+			dependencies = (
+			);
+			isa = PBXNativeTarget;
+			name = CompilerId@id_lang@;
+			productName = CompilerId@id_lang@;
+			productReference = 8DD76F6C0486A84900D96B5E;
+			productType = "com.apple.product-type.tool";
+		};
+		2C18F0B515DC1DCE00593670 = {
+			buildActionMask = 2147483647;
+			files = (
+				2C18F0B615DC1E0300593670,
+			);
+			isa = PBXSourcesBuildPhase;
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		8DD76F6C0486A84900D96B5E = {
+			explicitFileType = "compiled.mach-o.executable";
+			includeInIndex = 0;
+			isa = PBXFileReference;
+			path = CompilerId@id_lang@;
+			refType = 3;
+			sourceTree = BUILT_PRODUCTS_DIR;
+		};
+	};
+	rootObject = 08FB7793FE84155DC02AAC07;
+}

+ 119 - 0
Modules/CompilerId/Xcode-2.pbxproj.in

@@ -0,0 +1,119 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 42;
+	objects = {
+
+		2C18F0B615DC1E0300593670 = {isa = PBXBuildFile; fileRef = 2C18F0B415DC1DC700593670; };
+		2C18F0B415DC1DC700593670 = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = @id_type@; path = @id_src@; sourceTree = "<group>"; };
+		8DD76F6C0486A84900D96B5E = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = CompilerId@id_lang@; sourceTree = BUILT_PRODUCTS_DIR; };
+
+		08FB7794FE84155DC02AAC07 = {
+			isa = PBXGroup;
+			children = (
+				08FB7795FE84155DC02AAC07,
+				1AB674ADFE9D54B511CA2CBB,
+			);
+			name = CompilerId@id_lang@;
+			sourceTree = "<group>";
+		};
+		08FB7795FE84155DC02AAC07 = {
+			isa = PBXGroup;
+			children = (
+				2C18F0B415DC1DC700593670,
+			);
+			name = Source;
+			sourceTree = "<group>";
+		};
+		1AB674ADFE9D54B511CA2CBB = {
+			isa = PBXGroup;
+			children = (
+				8DD76F6C0486A84900D96B5E,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+
+		8DD76FA90486AB0100D96B5E = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 1DEB928508733DD80010E9CD;
+			buildPhases = (
+				2C18F0B515DC1DCE00593670,
+				2C8FEB8E15DC1A1A00E56A5D,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = CompilerId@id_lang@;
+			productName = CompilerId@id_lang@;
+			productReference = 8DD76F6C0486A84900D96B5E;
+			productType = "com.apple.product-type.tool";
+		};
+		08FB7793FE84155DC02AAC07 = {
+			isa = PBXProject;
+			buildConfigurationList = 1DEB928908733DD80010E9CD;
+			hasScannedForEncodings = 1;
+			mainGroup = 08FB7794FE84155DC02AAC07;
+			projectDirPath = "";
+			targets = (
+				8DD76FA90486AB0100D96B5E,
+			);
+		};
+		2C8FEB8E15DC1A1A00E56A5D = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "echo \"GCC_VERSION=$GCC_VERSION\"";
+		};
+		2C18F0B515DC1DCE00593670 = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				2C18F0B615DC1E0300593670,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		1DEB928608733DD80010E9CD = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = CompilerId@id_lang@;
+			};
+			name = Debug;
+		};
+		1DEB928A08733DD80010E9CD = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				SYMROOT = .;
+			};
+			name = Debug;
+		};
+		1DEB928508733DD80010E9CD = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928608733DD80010E9CD,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		1DEB928908733DD80010E9CD = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928A08733DD80010E9CD,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+	};
+	rootObject = 08FB7793FE84155DC02AAC07;
+}

+ 107 - 0
Modules/CompilerId/Xcode-3.pbxproj.in

@@ -0,0 +1,107 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+		2C18F0B615DC1E0300593670 = {isa = PBXBuildFile; fileRef = 2C18F0B415DC1DC700593670; };
+		2C18F0B415DC1DC700593670 = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = @id_type@; path = @id_src@; sourceTree = "<group>"; };
+		08FB7794FE84155DC02AAC07 = {
+			isa = PBXGroup;
+			children = (
+				2C18F0B415DC1DC700593670,
+			);
+			name = CompilerId@id_lang@;
+			sourceTree = "<group>";
+		};
+		8DD76FA90486AB0100D96B5E = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = 1DEB928508733DD80010E9CD;
+			buildPhases = (
+				2C18F0B515DC1DCE00593670,
+				2C8FEB8E15DC1A1A00E56A5D,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = CompilerId@id_lang@;
+			productName = CompilerId@id_lang@;
+			productType = "com.apple.product-type.tool";
+		};
+		08FB7793FE84155DC02AAC07 = {
+			isa = PBXProject;
+			buildConfigurationList = 1DEB928908733DD80010E9CD;
+			compatibilityVersion = "Xcode 3.1";
+			developmentRegion = English;
+			hasScannedForEncodings = 1;
+			knownRegions = (
+				en,
+			);
+			mainGroup = 08FB7794FE84155DC02AAC07;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				8DD76FA90486AB0100D96B5E,
+			);
+		};
+		2C8FEB8E15DC1A1A00E56A5D = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/sh;
+			shellScript = "echo \"GCC_VERSION=$GCC_VERSION\"";
+			showEnvVarsInLog = 0;
+		};
+		2C18F0B515DC1DCE00593670 = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				2C18F0B615DC1E0300593670,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+		1DEB928608733DD80010E9CD = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = CompilerId@id_lang@;
+			};
+			name = Debug;
+		};
+		1DEB928A08733DD80010E9CD = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_BIT)";
+				ONLY_ACTIVE_ARCH = YES;
+				CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)";
+				SYMROOT = .;
+			};
+			name = Debug;
+		};
+		1DEB928508733DD80010E9CD = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928608733DD80010E9CD,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		1DEB928908733DD80010E9CD = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				1DEB928A08733DD80010E9CD,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+	};
+	rootObject = 08FB7793FE84155DC02AAC07;
+}

+ 37 - 5
Source/cmDocumentVariables.cxx

@@ -282,6 +282,16 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
      "This variable is around for backwards compatibility, "
      "see CMAKE_BUILD_TOOL.",false,
      "Variables that Provide Information");
+  cm->DefineProperty
+    ("CMAKE_VS_PLATFORM_TOOLSET", cmProperty::VARIABLE,
+     "Visual Studio Platform Toolset name.",
+     "VS 10 and above use MSBuild under the hood and support multiple "
+     "compiler toolchains.  "
+     "CMake may specify a toolset explicitly, such as \"v110\" for "
+     "VS 11 or \"Windows7.1SDK\" for 64-bit support in VS 10 Express.  "
+     "CMake provides the name of the chosen toolset in this variable."
+     ,false,
+     "Variables that Provide Information");
   cm->DefineProperty
     ("CMAKE_MINOR_VERSION", cmProperty::VARIABLE,
      "The Minor version of cmake (i.e. the 4 in X.4.X).",
@@ -1395,8 +1405,30 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
 
   cm->DefineProperty
     ("CMAKE_<LANG>_COMPILER_ID", cmProperty::VARIABLE,
-     "An internal variable subject to change.",
-     "This is used in determining the compiler and is subject to change.",
+     "Compiler identification string.",
+     "A short string unique to the compiler vendor.  "
+     "Possible values include:\n"
+     "  Absoft = Absoft Fortran (absoft.com)\n"
+     "  ADSP = Analog VisualDSP++ (analog.com)\n"
+     "  Clang = LLVM Clang (clang.llvm.org)\n"
+     "  Cray = Cray Compiler (cray.com)\n"
+     "  Embarcadero, Borland = Embarcadero (embarcadero.com)\n"
+     "  G95 = G95 Fortran (g95.org)\n"
+     "  GNU = GNU Compiler Collection (gcc.gnu.org)\n"
+     "  HP = Hewlett-Packard Compiler (hp.com)\n"
+     "  Intel = Intel Compiler (intel.com)\n"
+     "  MIPSpro = SGI MIPSpro (sgi.com)\n"
+     "  MSVC = Microsoft Visual Studio (microsoft.com)\n"
+     "  PGI = The Portland Group (pgroup.com)\n"
+     "  PathScale = PathScale (pathscale.com)\n"
+     "  SDCC = Small Device C Compiler (sdcc.sourceforge.net)\n"
+     "  SunPro = Oracle Solaris Studio (oracle.com)\n"
+     "  TI_DSP = Texas Instruments (ti.com)\n"
+     "  TinyCC = Tiny C Compiler (tinycc.org)\n"
+     "  Watcom = Open Watcom (openwatcom.org)\n"
+     "  XL, VisualAge, zOS = IBM XL (ibm.com)\n"
+     "This variable is not guaranteed to be defined for all "
+     "compilers or languages.",
      false,
      "Variables for Languages");
 
@@ -1416,10 +1448,10 @@ void cmDocumentVariables::DefineVariables(cmake* cm)
 
   cm->DefineProperty
     ("CMAKE_<LANG>_COMPILER_VERSION", cmProperty::VARIABLE,
-     "An internal variable subject to change.",
+     "Compiler version string.",
      "Compiler version in major[.minor[.patch[.tweak]]] format.  "
-     "This variable is reserved for internal use by CMake and is not "
-     "guaranteed to be set.",
+     "This variable is not guaranteed to be defined for all "
+     "compilers or languages.",
      false,
      "Variables for Languages");
 

+ 13 - 11
Source/cmGlobalGenerator.cxx

@@ -376,22 +376,24 @@ cmGlobalGenerator::EnableLanguage(std::vector<std::string>const& languages,
     std::string loadedLang = "CMAKE_";
     loadedLang +=  lang;
     loadedLang += "_COMPILER_LOADED";
-    // If the existing build tree was already configured with this
-    // version of CMake then try to load the configured file first
-    // to avoid duplicate compiler tests.
-    unsigned int cacheMajor = mf->GetCacheMajorVersion();
-    unsigned int cacheMinor = mf->GetCacheMinorVersion();
-    unsigned int selfMajor = cmVersion::GetMajorVersion();
-    unsigned int selfMinor = cmVersion::GetMinorVersion();
-    if((this->CMakeInstance->GetIsInTryCompile() ||
-        (selfMajor == cacheMajor && selfMinor == cacheMinor))
-       && !mf->GetDefinition(loadedLang.c_str()))
+    if(!mf->GetDefinition(loadedLang.c_str()))
       {
       fpath = rootBin;
       fpath += "/CMake";
       fpath += lang;
       fpath += "Compiler.cmake";
-      if(cmSystemTools::FileExists(fpath.c_str()))
+
+      // If the existing build tree was already configured with this
+      // version of CMake then try to load the configured file first
+      // to avoid duplicate compiler tests.
+      unsigned int cacheMajor = mf->GetCacheMajorVersion();
+      unsigned int cacheMinor = mf->GetCacheMinorVersion();
+      unsigned int selfMajor = cmVersion::GetMajorVersion();
+      unsigned int selfMinor = cmVersion::GetMinorVersion();
+      if((this->CMakeInstance->GetIsInTryCompile() ||
+          (cacheMajor == 0 && cacheMinor == 0) ||
+          (selfMajor == cacheMajor && selfMinor == cacheMinor)) &&
+         cmSystemTools::FileExists(fpath.c_str()))
         {
         if(!mf->ReadListFile(0,fpath.c_str()))
           {

+ 11 - 0
Source/cmGlobalVisualStudio10Generator.cxx

@@ -27,6 +27,17 @@ cmGlobalVisualStudio10Generator::cmGlobalVisualStudio10Generator()
     "ProductDir", vc10Express, cmSystemTools::KeyWOW64_32);
 }
 
+//----------------------------------------------------------------------------
+void cmGlobalVisualStudio10Generator::AddPlatformDefinitions(cmMakefile* mf)
+{
+  cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf);
+  if(!this->PlatformToolset.empty())
+    {
+    mf->AddDefinition("CMAKE_VS_PLATFORM_TOOLSET",
+                      this->PlatformToolset.c_str());
+    }
+}
+
 //----------------------------------------------------------------------------
 void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout)
 {

+ 1 - 0
Source/cmGlobalVisualStudio10Generator.h

@@ -38,6 +38,7 @@ public:
   virtual const char* GetName() const {
     return cmGlobalVisualStudio10Generator::GetActualName();}
   static const char* GetActualName() {return "Visual Studio 10";}
+  virtual void AddPlatformDefinitions(cmMakefile* mf);
 
   /** Get the documentation entry for this generator.  */
   virtual void GetDocumentation(cmDocumentationEntry& entry) const;

+ 6 - 0
Tests/CMakeOnly/CMakeLists.txt

@@ -19,6 +19,12 @@ add_CMakeOnly_test(CheckCXXCompilerFlag)
 
 add_CMakeOnly_test(CheckLanguage)
 
+add_CMakeOnly_test(CompilerIdC)
+add_CMakeOnly_test(CompilerIdCXX)
+if(CMAKE_Fortran_COMPILER)
+  add_CMakeOnly_test(CompilerIdFortran)
+endif()
+
 add_CMakeOnly_test(AllFindModules)
 
 add_CMakeOnly_test(TargetScope)

+ 14 - 0
Tests/CMakeOnly/CompilerIdC/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(CompilerIdC C)
+
+foreach(v
+    CMAKE_C_COMPILER
+    CMAKE_C_COMPILER_ID
+    CMAKE_C_COMPILER_VERSION
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(SEND_ERROR "${v} not set!")
+  endif()
+endforeach()

+ 14 - 0
Tests/CMakeOnly/CompilerIdCXX/CMakeLists.txt

@@ -0,0 +1,14 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(CompilerIdCXX CXX)
+
+foreach(v
+    CMAKE_CXX_COMPILER
+    CMAKE_CXX_COMPILER_ID
+    CMAKE_CXX_COMPILER_VERSION
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(SEND_ERROR "${v} not set!")
+  endif()
+endforeach()

+ 22 - 0
Tests/CMakeOnly/CompilerIdFortran/CMakeLists.txt

@@ -0,0 +1,22 @@
+cmake_minimum_required(VERSION 2.8.9)
+project(CompilerIdFortran Fortran)
+
+foreach(v
+    CMAKE_Fortran_COMPILER
+    CMAKE_Fortran_COMPILER_ID
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(SEND_ERROR "${v} not set!")
+  endif()
+endforeach()
+foreach(v
+    CMAKE_Fortran_COMPILER_VERSION
+    )
+  if(${v})
+    message(STATUS "${v}=[${${v}}]")
+  else()
+    message(WARNING "${v} not set!")
+  endif()
+endforeach()