2 # Function to compile a source file to identify the compiler. This is
3 # used internally by CMake and should not be included by user code.
4 # If successful, sets CMAKE_<lang>_COMPILER_ID and CMAKE_<lang>_PLATFORM_ID
6 FUNCTION(CMAKE_DETERMINE_COMPILER_ID lang flagvar src)
7 # Make sure the compiler arguments are clean.
8 STRING(STRIP "${CMAKE_${lang}_COMPILER_ARG1}" CMAKE_${lang}_COMPILER_ID_ARG1)
10 # Make sure user-specified compiler flags are used.
11 IF(CMAKE_${lang}_FLAGS)
12 SET(CMAKE_${lang}_COMPILER_ID_FLAGS ${CMAKE_${lang}_FLAGS})
13 ELSE(CMAKE_${lang}_FLAGS)
14 SET(CMAKE_${lang}_COMPILER_ID_FLAGS $ENV{${flagvar}})
15 ENDIF(CMAKE_${lang}_FLAGS)
16 STRING(REGEX REPLACE " " ";" CMAKE_${lang}_COMPILER_ID_FLAGS_LIST "${CMAKE_${lang}_COMPILER_ID_FLAGS}")
18 # Compute the directory in which to run the test.
19 SET(CMAKE_${lang}_COMPILER_ID_DIR ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CompilerId${lang})
21 # Try building with no extra flags and then try each set
22 # of helper flags. Stop when the compiler is identified.
23 FOREACH(flags "" ${CMAKE_${lang}_COMPILER_ID_TEST_FLAGS})
24 IF(NOT CMAKE_${lang}_COMPILER_ID)
25 CMAKE_DETERMINE_COMPILER_ID_BUILD("${lang}" "${flags}" "${src}")
26 FOREACH(file ${COMPILER_${lang}_PRODUCED_FILES})
27 CMAKE_DETERMINE_COMPILER_ID_CHECK("${lang}" "${CMAKE_${lang}_COMPILER_ID_DIR}/${file}" "${src}")
29 ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
32 # if the format is unknown after all files have been checked, put "Unknown" in the cache
33 IF(NOT CMAKE_EXECUTABLE_FORMAT)
34 SET(CMAKE_EXECUTABLE_FORMAT "Unknown" CACHE INTERNAL "Executable file format")
35 ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
37 # Display the final identification result.
38 IF(CMAKE_${lang}_COMPILER_ID)
39 MESSAGE(STATUS "The ${lang} compiler identification is "
40 "${CMAKE_${lang}_COMPILER_ID}")
41 ELSE(CMAKE_${lang}_COMPILER_ID)
42 MESSAGE(STATUS "The ${lang} compiler identification is unknown")
43 ENDIF(CMAKE_${lang}_COMPILER_ID)
45 SET(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
46 SET(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
47 ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID)
49 #-----------------------------------------------------------------------------
50 # Function to write the compiler id source file.
51 FUNCTION(CMAKE_DETERMINE_COMPILER_ID_WRITE lang src)
52 FILE(READ ${CMAKE_ROOT}/Modules/${src}.in ID_CONTENT_IN)
53 STRING(CONFIGURE "${ID_CONTENT_IN}" ID_CONTENT_OUT @ONLY)
54 FILE(WRITE ${CMAKE_${lang}_COMPILER_ID_DIR}/${src} "${ID_CONTENT_OUT}")
55 ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_WRITE)
57 #-----------------------------------------------------------------------------
58 # Function to build the compiler id source file and look for output
60 FUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
61 # Create a clean working directory.
62 FILE(REMOVE_RECURSE ${CMAKE_${lang}_COMPILER_ID_DIR})
63 FILE(MAKE_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR})
64 CMAKE_DETERMINE_COMPILER_ID_WRITE("${lang}" "${src}")
66 # Construct a description of this test case.
67 SET(COMPILER_DESCRIPTION
68 "Compiler: ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_ARG1}
69 Build flags: ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
70 Id flags: ${testflags}
73 # Compile the compiler identification source.
74 IF(COMMAND EXECUTE_PROCESS)
76 COMMAND ${CMAKE_${lang}_COMPILER}
77 ${CMAKE_${lang}_COMPILER_ID_ARG1}
78 ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
81 WORKING_DIRECTORY ${CMAKE_${lang}_COMPILER_ID_DIR}
82 OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
83 ERROR_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
84 RESULT_VARIABLE CMAKE_${lang}_COMPILER_ID_RESULT
86 ELSE(COMMAND EXECUTE_PROCESS)
88 ${CMAKE_${lang}_COMPILER} ${CMAKE_${lang}_COMPILER_ID_DIR}
89 ARGS ${CMAKE_${lang}_COMPILER_ID_ARG1}
90 ${CMAKE_${lang}_COMPILER_ID_FLAGS_LIST}
93 OUTPUT_VARIABLE CMAKE_${lang}_COMPILER_ID_OUTPUT
94 RETURN_VALUE CMAKE_${lang}_COMPILER_ID_RESULT
96 ENDIF(COMMAND EXECUTE_PROCESS)
98 # Check the result of compilation.
99 IF(CMAKE_${lang}_COMPILER_ID_RESULT)
100 # Compilation failed.
102 "Compiling the ${lang} compiler identification source file \"${src}\" failed.
103 ${COMPILER_DESCRIPTION}
105 ${CMAKE_${lang}_COMPILER_ID_RESULT}
106 ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
109 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log "${MSG}")
110 #IF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
111 # MESSAGE(FATAL_ERROR "${MSG}")
112 #ENDIF(NOT CMAKE_${lang}_COMPILER_ID_ALLOW_FAIL)
114 # No output files should be inspected.
115 SET(COMPILER_${lang}_PRODUCED_FILES)
116 ELSE(CMAKE_${lang}_COMPILER_ID_RESULT)
117 # Compilation succeeded.
118 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
119 "Compiling the ${lang} compiler identification source file \"${src}\" succeeded.
120 ${COMPILER_DESCRIPTION}
122 ${CMAKE_${lang}_COMPILER_ID_RESULT}
123 ${CMAKE_${lang}_COMPILER_ID_OUTPUT}
127 # Find the executable produced by the compiler, try all files in the
129 FILE(GLOB COMPILER_${lang}_PRODUCED_FILES
130 RELATIVE ${CMAKE_${lang}_COMPILER_ID_DIR}
131 ${CMAKE_${lang}_COMPILER_ID_DIR}/*)
132 LIST(REMOVE_ITEM COMPILER_${lang}_PRODUCED_FILES "${src}")
133 FOREACH(file ${COMPILER_${lang}_PRODUCED_FILES})
134 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
135 "Compilation of the ${lang} compiler identification source \""
136 "${src}\" produced \"${file}\"\n\n")
139 IF(NOT COMPILER_${lang}_PRODUCED_FILES)
140 # No executable was found.
141 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
142 "Compilation of the ${lang} compiler identification source \""
143 "${src}\" did not produce an executable in \""
144 "${CMAKE_${lang}_COMPILER_ID_DIR}\".\n\n")
145 ENDIF(NOT COMPILER_${lang}_PRODUCED_FILES)
146 ENDIF(CMAKE_${lang}_COMPILER_ID_RESULT)
148 # Return the files produced by the compilation.
149 SET(COMPILER_${lang}_PRODUCED_FILES "${COMPILER_${lang}_PRODUCED_FILES}" PARENT_SCOPE)
150 ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_BUILD lang testflags src)
152 #-----------------------------------------------------------------------------
153 # Function to extract the compiler id from an executable.
154 FUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang file)
155 # Look for a compiler id if not yet known.
156 IF(NOT CMAKE_${lang}_COMPILER_ID)
157 # Read the compiler identification string from the executable file.
161 CMAKE_${lang}_COMPILER_ID_STRINGS LIMIT_COUNT 2 REGEX "INFO:")
162 SET(HAVE_COMPILER_TWICE 0)
163 FOREACH(info ${CMAKE_${lang}_COMPILER_ID_STRINGS})
164 IF("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
166 SET(COMPILER_ID_TWICE 1)
168 STRING(REGEX REPLACE ".*INFO:compiler\\[([^]]*)\\].*" "\\1"
169 COMPILER_ID "${info}")
170 ENDIF("${info}" MATCHES ".*INFO:compiler\\[([^]\"]*)\\].*")
171 IF("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
172 STRING(REGEX REPLACE ".*INFO:platform\\[([^]]*)\\].*" "\\1"
173 PLATFORM_ID "${info}")
174 ENDIF("${info}" MATCHES ".*INFO:platform\\[([^]\"]*)\\].*")
177 # Check if a valid compiler and platform were found.
178 IF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
179 SET(CMAKE_${lang}_COMPILER_ID "${COMPILER_ID}")
180 SET(CMAKE_${lang}_PLATFORM_ID "${PLATFORM_ID}")
181 ENDIF(COMPILER_ID AND NOT COMPILER_ID_TWICE)
183 # Check the compiler identification string.
184 IF(CMAKE_${lang}_COMPILER_ID)
185 # The compiler identification was found.
186 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
187 "The ${lang} compiler identification is ${CMAKE_${lang}_COMPILER_ID}, found in \""
189 ELSE(CMAKE_${lang}_COMPILER_ID)
190 # The compiler identification could not be found.
191 FILE(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
192 "The ${lang} compiler identification could not be found in \""
194 ENDIF(CMAKE_${lang}_COMPILER_ID)
195 ENDIF(NOT CMAKE_${lang}_COMPILER_ID)
197 # try to figure out the executable format: ELF, COFF, Mach-O
198 IF(NOT CMAKE_EXECUTABLE_FORMAT)
199 FILE(READ ${file} CMAKE_EXECUTABLE_MAGIC LIMIT 4 HEX)
201 # ELF files start with 0x7f"ELF"
202 IF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
203 SET(CMAKE_EXECUTABLE_FORMAT "ELF" CACHE INTERNAL "Executable file format")
204 ENDIF("${CMAKE_EXECUTABLE_MAGIC}" STREQUAL "7f454c46")
206 # # COFF (.exe) files start with "MZ"
207 # IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
208 # SET(CMAKE_EXECUTABLE_FORMAT "COFF" CACHE STRING "Executable file format")
209 # ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "4d5a....")
211 # # Mach-O files start with CAFEBABE or FEEDFACE, according to http://radio.weblogs.com/0100490/2003/01/28.html
212 # IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
213 # SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
214 # ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "cafebabe")
215 # IF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
216 # SET(CMAKE_EXECUTABLE_FORMAT "MACHO" CACHE STRING "Executable file format")
217 # ENDIF("${CMAKE_EXECUTABLE_MAGIC}" MATCHES "feedface")
219 ENDIF(NOT CMAKE_EXECUTABLE_FORMAT)
221 # Return the information extracted.
222 SET(CMAKE_${lang}_COMPILER_ID "${CMAKE_${lang}_COMPILER_ID}" PARENT_SCOPE)
223 SET(CMAKE_${lang}_PLATFORM_ID "${CMAKE_${lang}_PLATFORM_ID}" PARENT_SCOPE)
224 SET(CMAKE_EXECUTABLE_FORMAT "${CMAKE_EXECUTABLE_FORMAT}" PARENT_SCOPE)
225 ENDFUNCTION(CMAKE_DETERMINE_COMPILER_ID_CHECK lang)