summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2010-02-01 09:02:39 -0500
committerBrad King <brad.king@kitware.com>2010-02-01 09:02:39 -0500
commit107872976fbc5f063de2e28a08f546a51bbad3af (patch)
tree6c0a9d0fee5e11d65de85fac6c066bf97bdfa07e
parentdc1d2189ae922be9d6e7f5fde698532db47e46aa (diff)
downloadcmake-107872976fbc5f063de2e28a08f546a51bbad3af.tar.gz
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.
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake40
-rw-r--r--Tests/CMakeTests/CMakeLists.txt1
-rw-r--r--Tests/CMakeTests/CompilerIdVendorTest.cmake.in31
3 files changed, 72 insertions, 0 deletions
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index a70c6ab923..bddd6a1e8b 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/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)
diff --git a/Tests/CMakeTests/CMakeLists.txt b/Tests/CMakeTests/CMakeLists.txt
index 161ca44994..6df026e0bb 100644
--- a/Tests/CMakeTests/CMakeLists.txt
+++ b/Tests/CMakeTests/CMakeLists.txt
@@ -26,6 +26,7 @@ AddCMakeTest(If "")
AddCMakeTest(String "")
AddCMakeTest(Math "")
AddCMakeTest(CMakeMinimumRequired "")
+AddCMakeTest(CompilerIdVendor "")
if(HAVE_ELF_H)
AddCMakeTest(ELF "")
diff --git a/Tests/CMakeTests/CompilerIdVendorTest.cmake.in b/Tests/CMakeTests/CompilerIdVendorTest.cmake.in
new file mode 100644
index 0000000000..68f646212b
--- /dev/null
+++ b/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()