summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Modules/CMakeDetermineCompilerId.cmake249
-rw-r--r--Modules/CMakeDetermineFortranCompiler.cmake9
2 files changed, 166 insertions, 92 deletions
diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake
index f8dab51..eea8291 100644
--- a/Modules/CMakeDetermineCompilerId.cmake
+++ b/Modules/CMakeDetermineCompilerId.cmake
@@ -1,9 +1,9 @@
-# Macro to compile a source file to identify the compiler. This is
+# Function to compile a source file to identify the compiler. This is
# used internally by CMake and should not be included by user code.
# If successful, sets CMAKE_<lang>_COMPILER_ID and CMAKE_<lang>_PLATFORM_ID
-MACRO(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
# Store the compiler identification source file.
SET(CMAKE_${lang}_COMPILER_ID_SRC "${src}")
IF(CMAKE_HOST_WIN32 AND NOT CMAKE_HOST_UNIX)
@@ -23,17 +23,64 @@ MACRO(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
ELSE(CMAKE_${lang}_FLAGS)
SET(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
ENDIF(CMAKE_${lang}_FLAGS)
+ STRING(REGEX REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
- # Create an empty directory in which to run the test.
+ # Compute the directory in which to run the test.
SET(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CompilerId${lang})
+
+ # Try building with no extra flags and then try each set
+ # of helper flags. Stop when the compiler is identified.
+ FOREACH(flags "" ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
+ IF(NOT CMAKE_${lang}_COMPILER_ID)
+ CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}")
+ FOREACH(file ${COMPILER_${lang}_PRODUCED_FILES})
+ CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${file}")
+ ENDFOREACH(file)
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
+ ENDFOREACH(flags)
+
+ # 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 STRING "Executable file format")
+ ELSE(NOT CMAKE_EXECUTABLE_FORMAT)
+ MESSAGE(STATUS "The executable file format is ${CMAKE_EXECUTABLE_FORMAT}")
+ ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
+
+ # Display the final identification result.
+ IF(CMAKE_${lang}_COMPILER_ID)
+ MESSAGE(STATUS "The ${lang} compiler identification is "
+ "${CMAKE_${lang}_COMPILER_ID}")
+ ELSE(CMAKE_${lang}_COMPILER_ID)
+ MESSAGE(STATUS "The ${lang} compiler identification is unknown")
+ ENDIF(CMAKE_${lang}_COMPILER_ID)
+
+ RAISE_SCOPE(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}")
+ RAISE_SCOPE(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}")
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID)
+
+#-----------------------------------------------------------------------------
+# Function to build the compiler id source file and look for output
+# files.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags)
+ # Create a clean working directory.
FILE(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
FILE(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
+ # Construct a description of this test case.
+ SET(COMPILER_DESCRIPTION
+ "Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}\n"
+ "Build flags: ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}\n"
+ "Id flags: ${testflags}\n"
+ )
+
# Compile the compiler identification source.
- STRING(REGEX REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
IF(COMMAND EXECUTE_PROCESS)
EXECUTE_PROCESS(
- COMMAND ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1} ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST} ${CMAKE_${lang}_COMPILER_ID_SRC}
+ COMMAND ${CMAKE_${lang}_COMPILER}
+ ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+ ${testflags}
+ ${CMAKE_${lang}_COMPILER_ID_SRC}
WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
@@ -42,7 +89,10 @@ MACRO(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
ELSE(COMMAND EXECUTE_PROCESS)
EXEC_PROGRAM(
${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_DIR}
- ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1} ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST} \"${CMAKE_${lang}_COMPILER_ID_SRC}\"
+ ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
+ ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
+ ${testflags}
+ \"${CMAKE_${lang}_COMPILER_ID_SRC}\"
OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
)
@@ -51,108 +101,125 @@ MACRO(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
# Check the result of compilation.
IF(CMAKE_${lang}_COMPILER_ID_RESULT)
# Compilation failed.
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ SET(MSG
"Compiling the ${lang} compiler identification source file \""
- "${CMAKE_${lang}_COMPILER_ID_SRC}\" failed with the following output:\n"
+ "${CMAKE_${lang}_COMPILER_ID_SRC}\" failed.\n"
+ ${COMPILER_DESCRIPTION}
+ "The output was:\n"
"${CMAKE_${lang}_COMPILER_ID_RESULT}\n"
- "${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n")
- IF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
- MESSAGE(FATAL_ERROR "Compiling the ${lang} compiler identification source file \""
- "${CMAKE_${lang}_COMPILER_ID_SRC}\" failed with the following output:\n"
- "${CMAKE_${lang}_COMPILER_ID_RESULT}\n"
- "${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n")
- ENDIF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
+ "${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n"
+ )
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
+ #IF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
+ # MESSAGE(FATAL_ERROR "${MSG}")
+ #ENDIF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
+
+ # No output files should be inspected.
+ SET(COMPILER_${lang}_PRODUCED_FILES)
ELSE(CMAKE_${lang}_COMPILER_ID_RESULT)
# Compilation succeeded.
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Compiling the ${lang} compiler identification source file \""
- "${CMAKE_${lang}_COMPILER_ID_SRC}\" succeeded with the following output:\n"
- "${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n")
+ "${CMAKE_${lang}_COMPILER_ID_SRC}\" succeeded.\n"
+ ${COMPILER_DESCRIPTION}
+ "The output was:\n"
+ "${CMAKE_${lang}_COMPILER_ID_RESULT}\n"
+ "${CMAKE_${lang}_COMPILER_ID_OUTPUT}\n\n"
+ )
- # Find the executable produced by the compiler, try all files in the binary dir
- SET(CMAKE_${lang}_COMPILER_ID)
+ # Find the executable produced by the compiler, try all files in the
+ # binary dir.
FILE(GLOB COMPILER_${lang}_PRODUCED_FILES ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
- FOREACH(CMAKE_${lang}_COMPILER_ID_EXE ${COMPILER_${lang}_PRODUCED_FILES})
+ FOREACH(file ${COMPILER_${lang}_PRODUCED_FILES})
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
"Compilation of the ${lang} compiler identification source \""
- "${CMAKE_${lang}_COMPILER_ID_SRC}\" produced \""
- "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
-
- # try to figure out the executable format: ELF, COFF, Mach-O
- IF(NOT CMAKE_EXECUTABLE_FORMAT)
- FILE(READ ${CMAKE_${lang}_COMPILER_ID_EXE} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
-
- # ELF files start with 0x7f"ELF"
- IF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
- SET(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE STRING "Executable file format")
- ENDIF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
-
-# # COFF (.exe) files start with "MZ"
-# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
-# SET(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
-# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
-#
-# # Mach-O files start with CAFEBABE or FEEDFACE, according to http://radio.weblogs.com/0100490/2003/01/28.html
-# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
-# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
-# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
-# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
-# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
-# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
-
- ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
-
- # only check if we don't have it yet
- IF(NOT CMAKE_${lang}_COMPILER_ID)
- # Read the compiler identification string from the executable file.
- FILE(STRINGS ${CMAKE_${lang}_COMPILER_ID_EXE}
- CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 2 REGEX "INFO:")
- FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
- IF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
- STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
- CMAKE_${lang}_COMPILER_ID "${info}")
- ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
- IF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
- STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
- CMAKE_${lang}_PLATFORM_ID "${info}")
- ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
- ENDFOREACH(info)
-
- # Check the compiler identification string.
- IF(CMAKE_${lang}_COMPILER_ID)
- # The compiler identification was found.
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
- "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
- "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
- ELSE(CMAKE_${lang}_COMPILER_ID)
- # The compiler identification could not be found.
- FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
- "The ${lang} compiler identification could not be found in \""
- "${CMAKE_${lang}_COMPILER_ID_EXE}\"\n\n")
- ENDIF(CMAKE_${lang}_COMPILER_ID)
- ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
- ENDFOREACH(CMAKE_${lang}_COMPILER_ID_EXE)
-
- # 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 STRING "Executable file format")
- ELSE(NOT CMAKE_EXECUTABLE_FORMAT)
- MESSAGE(STATUS "The executable file format is ${CMAKE_EXECUTABLE_FORMAT}")
- ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
+ "${CMAKE_${lang}_COMPILER_ID_SRC}\" produced \"${file}\"\n\n")
+ ENDFOREACH(file)
IF(NOT COMPILER_${lang}_PRODUCED_FILES)
# No executable was found.
FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
"Compilation of the ${lang} compiler identification source \""
- "${CMAKE_${lang}_COMPILER_ID_SRC}\" did not produce an executable in "
- "${CMAKE_${lang}_COMPILER_ID_DIR} .\n\n")
+ "${CMAKE_${lang}_COMPILER_ID_SRC}\" did not produce an executable in \""
+ "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
ENDIF(NOT COMPILER_${lang}_PRODUCED_FILES)
+ ENDIF(CMAKE_${lang}_COMPILER_ID_RESULT)
+ # Return the files produced by the compilation.
+ RAISE_SCOPE(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}")
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags)
+
+#-----------------------------------------------------------------------------
+# Function to extract the compiler id from an executable.
+FUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
+ # Look for a compiler id if not yet known.
+ IF(NOT CMAKE_${lang}_COMPILER_ID)
+ # Read the compiler identification string from the executable file.
+ SET(COMPILER_ID)
+ SET(PLATFORM_ID)
+ FILE(STRINGS ${file}
+ CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 2 REGEX "INFO:")
+ SET(HAVE_COMPILER_TWICE 0)
+ FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
+ IF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
+ IF(COMPILER_ID)
+ SET(COMPILER_ID_TWICE 1)
+ ENDIF(COMPILER_ID)
+ STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
+ COMPILER_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]]*)\\].*")
+ IF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
+ STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
+ PLATFORM_ID "${info}")
+ ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]]*)\\].*")
+ ENDFOREACH(info)
+
+ # Check if a valid compiler and platform were found.
+ IF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
+ SET(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
+ SET(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
+ ENDIF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
+
+ # Check the compiler identification string.
IF(CMAKE_${lang}_COMPILER_ID)
- MESSAGE(STATUS "The ${lang} compiler identification is "
- "${CMAKE_${lang}_COMPILER_ID}")
+ # The compiler identification was found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
+ "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
+ "${file}\"\n\n")
ELSE(CMAKE_${lang}_COMPILER_ID)
- MESSAGE(STATUS "The ${lang} compiler identification is unknown")
+ # The compiler identification could not be found.
+ FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
+ "The ${lang} compiler identification could not be found in \""
+ "${file}\"\n\n")
ENDIF(CMAKE_${lang}_COMPILER_ID)
- ENDIF(CMAKE_${lang}_COMPILER_ID_RESULT)
-ENDMACRO(CMAKE_DETERMINE_COMPILER_ID)
+ ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
+
+ # try to figure out the executable format: ELF, COFF, Mach-O
+ IF(NOT CMAKE_EXECUTABLE_FORMAT)
+ FILE(READ ${file} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
+
+ # ELF files start with 0x7f"ELF"
+ IF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
+ SET(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE STRING "Executable file format")
+ ENDIF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
+
+# # COFF (.exe) files start with "MZ"
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
+# SET(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
+#
+# # Mach-O files start with CAFEBABE or FEEDFACE, according to http://radio.weblogs.com/0100490/2003/01/28.html
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
+# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
+# IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
+# SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
+# ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
+
+ ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
+
+ # Return the information extracted.
+ RAISE_SCOPE(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}")
+ RAISE_SCOPE(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}")
+ RAISE_SCOPE(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}")
+ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang)
diff --git a/Modules/CMakeDetermineFortranCompiler.cmake b/Modules/CMakeDetermineFortranCompiler.cmake
index 3776f16..52d041f 100644
--- a/Modules/CMakeDetermineFortranCompiler.cmake
+++ b/Modules/CMakeDetermineFortranCompiler.cmake
@@ -80,9 +80,16 @@ ENDIF(${CMAKE_GENERATOR} MATCHES "Visual Studio")
IF(NOT CMAKE_Fortran_COMPILER_ID_RUN)
SET(CMAKE_Fortran_COMPILER_ID_RUN 1)
+ # Each entry in this list is a set of extra flags to try
+ # adding to the compile line to see if it helps produce
+ # a valid identification executable.
+ SET(CMAKE_Fortran_COMPILER_ID_TEST_FLAGS
+ # Intel on windows does not preprocess by default.
+ "-fpp"
+ )
+
# Try to identify the compiler.
SET(CMAKE_Fortran_COMPILER_ID)
- SET(CMAKE_Fortran_COMPILER_ID_ALLOW_FAIL 1)
INCLUDE(${CMAKE_ROOT}/Modules/CMakeDetermineCompilerId.cmake)
CMAKE_DETERMINE_COMPILER_ID(Fortran FFLAGS ${CMAKE_ROOT}/Modules/CMakeFortranCompilerId.F90)