Browse Source

Add alternate per-vendor compiler id detection

At least one Fortran compiler does not provide a preprocessor symbol to
identify itself.  Instead we try running unknown compilers with version
query flags known for each vendor and look for known output.  Future
commits will add vendor-specific flags/output table entries.
Brad King 15 years ago
parent
commit
3c2ecbe74e

+ 40 - 0
Modules/CMakeDetermineCompilerId.cmake

@@ -42,6 +42,11 @@ FUNCTION(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
     ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
   ENDFOREACH(flags)
 
+  # If the compiler is still unknown, try to query its vendor.
+  IF(NOT CMAKE_${lang}_COMPILER_ID)
+    CMAKE_DETERMINE_COMPILER_ID_VENDOR(${lang})
+  ENDIF()
+
   # if the format is unknown after all files have been checked, put "Unknown" in the cache
   IF(NOT CMAKE_EXECUTABLE_FORMAT)
     SET(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
@@ -245,3 +250,38 @@ FUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
     PARENT_SCOPE)
   SET(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
 ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang)
+
+#-----------------------------------------------------------------------------
+# 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.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_VENDOR lang)
+  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(
+      COMMAND ${CMAKE_${lang}_COMPILER}
+      ${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
+      )
+    IF("${output}" MATCHES "${regex}")
+      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+        "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
+        "matched \"${regex}\":\n${output}")
+      SET(CMAKE_${lang}_COMPILER_ID "${vendor}" PARENT_SCOPE)
+      BREAK()
+    ELSE()
+      FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+        "Checking whether the ${lang} compiler is ${vendor} using \"${flags}\" "
+        "did not match \"${regex}\":\n${output}")
+    ENDIF()
+  ENDFOREACH()
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_VENDOR)

+ 1 - 0
Tests/CMakeTests/CMakeLists.txt

@@ -26,6 +26,7 @@ AddCMakeTest(If "")
 AddCMakeTest(String "")
 AddCMakeTest(Math "")
 AddCMakeTest(CMakeMinimumRequired "")
+AddCMakeTest(CompilerIdVendor "")
 
 if(HAVE_ELF_H)
   AddCMakeTest(ELF "")

+ 31 - 0
Tests/CMakeTests/CompilerIdVendorTest.cmake.in

@@ -0,0 +1,31 @@
+# This is not supposed to be included by user code, but we need to
+# test it.
+include(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
+
+set(MY_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/CompilerIdVendor")
+file(REMOVE_RECURSE ${MY_BINARY_DIR})
+file(MAKE_DIRECTORY ${MY_BINARY_DIR})
+
+set(CMAKE_MyLang_COMPILER ${CMAKE_COMMAND})
+set(CMAKE_MyLang_COMPILER_ID_ARG1)
+set(CMAKE_MyLang_COMPILER_ID_FLAGS_LIST)
+set(CMAKE_MyLang_COMPILER_ID_DIR ${MY_BINARY_DIR})
+
+file(WRITE "${MY_BINARY_DIR}/BogusVendor.cmake" "message(\"This is a BogusVendor compiler\")")
+list(APPEND CMAKE_MyLang_COMPILER_ID_VENDORS BogusVendor)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_FLAGS_BogusVendor -P BogusVendor.cmake)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_REGEX_BogusVendor ThisDoesNotMatch_BogusVendor)
+
+file(WRITE "${MY_BINARY_DIR}/MyVendor.cmake" "message(\"This is a MyVendor compiler\")")
+list(APPEND CMAKE_MyLang_COMPILER_ID_VENDORS MyVendor)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_FLAGS_MyVendor -P MyVendor.cmake)
+set(CMAKE_MyLang_COMPILER_ID_VENDOR_REGEX_MyVendor MyVendor)
+
+set(CMAKE_BINARY_DIR ${MY_BINARY_DIR})
+cmake_determine_compiler_id_vendor(MyLang)
+
+if("${CMAKE_MyLang_COMPILER_ID}" STREQUAL "MyVendor")
+  message(STATUS "Found MyVendor compiler id!")
+else()
+  message(FATAL_ERROR "Did not find MyVendor compiler id: [${CMAKE_MyLang_COMPILER_ID}]")
+endif()