1 # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
5 # Function to compile a source file to identify the compiler ABI.
6 # This is used internally by CMake and should not be included by user
9 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitIncludeInfo.cmake)
10 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
11 include(${CMAKE_ROOT}/Modules/CMakeParseLibraryArchitecture.cmake)
12 include(CMakeTestCompilerCommon)
14 function(CMAKE_DETERMINE_COMPILER_ABI lang src)
15 if(NOT DEFINED CMAKE_${lang}_ABI_COMPILED)
16 message(CHECK_START "Detecting ${lang} compiler ABI info")
18 # Compile the ABI identification source.
19 set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
21 set(COMPILE_DEFINITIONS )
22 if(DEFINED CMAKE_${lang}_VERBOSE_FLAG)
23 set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
24 set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_FLAG}")
26 if(DEFINED CMAKE_${lang}_VERBOSE_COMPILE_FLAG)
27 set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_COMPILE_FLAG}")
29 if(lang STREQUAL "CUDA")
30 if(CMAKE_CUDA_ARCHITECTURES STREQUAL "native")
31 # We are about to detect the native architectures, so we do
32 # not yet know them. Use all architectures during detection.
33 set(CMAKE_CUDA_ARCHITECTURES "all")
35 set(CMAKE_CUDA_RUNTIME_LIBRARY "Static")
37 if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
38 # Avoid adding our own platform standard libraries for compilers
39 # from which we might detect implicit link libraries.
40 list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=")
42 __TestCompiler_setTryCompileTargetType()
44 # Avoid failing ABI detection on warnings.
45 string(REGEX REPLACE "(^| )-Werror([= ][^ ]*)?( |$)" " " CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
47 # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
48 # and set them to "C" that way GCC's "search starts here" text is in
49 # English and we can grok it.
50 set(_orig_lc_all $ENV{LC_ALL})
51 set(_orig_lc_messages $ENV{LC_MESSAGES})
52 set(_orig_lang $ENV{LANG})
54 set(ENV{LC_MESSAGES} C)
57 try_compile(CMAKE_${lang}_ABI_COMPILED
58 ${CMAKE_BINARY_DIR} ${src}
59 CMAKE_FLAGS ${CMAKE_FLAGS}
60 # Ignore unused flags when we are just determining the ABI.
61 "--no-warn-unused-cli"
62 COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS}
63 OUTPUT_VARIABLE OUTPUT
65 COPY_FILE_ERROR _copy_error
69 # Restore original LC_ALL, LC_MESSAGES, and LANG
70 set(ENV{LC_ALL} ${_orig_lc_all})
71 set(ENV{LC_MESSAGES} ${_orig_lc_messages})
72 set(ENV{LANG} ${_orig_lang})
74 # Move result from cache to normal variable.
75 set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED})
76 unset(CMAKE_${lang}_ABI_COMPILED CACHE)
77 if(CMAKE_${lang}_ABI_COMPILED AND _copy_error)
78 set(CMAKE_${lang}_ABI_COMPILED 0)
80 set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED} PARENT_SCOPE)
82 # Load the resulting information strings.
83 if(CMAKE_${lang}_ABI_COMPILED)
84 message(CHECK_PASS "done")
85 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
86 "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
87 file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 32 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
88 set(ABI_SIZEOF_DPTR "NOTFOUND")
89 set(ABI_BYTE_ORDER "NOTFOUND")
90 set(ABI_NAME "NOTFOUND")
91 foreach(info ${ABI_STRINGS})
92 if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]" AND NOT ABI_SIZEOF_DPTR)
93 set(ABI_SIZEOF_DPTR "${CMAKE_MATCH_1}")
95 if("${info}" MATCHES "INFO:byte_order\\[(BIG_ENDIAN|LITTLE_ENDIAN)\\]")
96 set(byte_order "${CMAKE_MATCH_1}")
97 if(ABI_BYTE_ORDER STREQUAL "NOTFOUND")
98 # Tentatively use the value because this is the first occurrence.
99 set(ABI_BYTE_ORDER "${byte_order}")
100 elseif(NOT ABI_BYTE_ORDER STREQUAL "${byte_order}")
101 # Drop value because multiple occurrences do not match.
102 set(ABI_BYTE_ORDER "")
105 if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]" AND NOT ABI_NAME)
106 set(ABI_NAME "${CMAKE_MATCH_1}")
111 set(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
112 elseif(CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT)
113 set(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE)
117 set(CMAKE_${lang}_BYTE_ORDER "${ABI_BYTE_ORDER}" PARENT_SCOPE)
121 set(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
124 # Parse implicit include directory for this language, if available.
125 if(CMAKE_${lang}_VERBOSE_FLAG)
126 set (implicit_incdirs "")
127 cmake_parse_implicit_include_info("${OUTPUT}" "${lang}"
128 implicit_incdirs log rv)
129 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
130 "Parsed ${lang} implicit include dir info from above output: rv=${rv}\n${log}\n\n")
131 if("${rv}" STREQUAL "done")
132 # Entries that we have been told to explicitly pass as standard include
133 # directories will not be implicitly added by the compiler.
134 if(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES)
135 list(REMOVE_ITEM implicit_incdirs ${CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES})
138 # We parsed implicit include directories, so override the default initializer.
139 set(_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT "${implicit_incdirs}")
142 set(CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "${_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT}" PARENT_SCOPE)
144 # Parse implicit linker information for this language, if available.
145 set(implicit_dirs "")
146 set(implicit_objs "")
147 set(implicit_libs "")
148 set(implicit_fwks "")
149 if(CMAKE_${lang}_VERBOSE_FLAG)
150 CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log
151 "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}"
152 COMPUTE_IMPLICIT_OBJECTS implicit_objs)
153 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
154 "Parsed ${lang} implicit link information from above output:\n${log}\n\n")
156 # for VS IDE Intel Fortran we have to figure out the
157 # implicit link path for the fortran run time using
159 if("${lang}" MATCHES "Fortran"
160 AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
161 message(CHECK_START "Determine Intel Fortran Compiler Implicit Link Path")
162 # Build a sample project which reports symbols.
163 try_compile(IFORT_LIB_PATH_COMPILED
164 ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath
165 ${CMAKE_ROOT}/Modules/IntelVSImplicitPath
168 "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
169 OUTPUT_VARIABLE _output)
171 "${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
173 include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
174 message(CHECK_PASS "done")
177 # Implicit link libraries cannot be used explicitly for multiple
178 # OS X architectures, so we skip it.
179 if(DEFINED CMAKE_OSX_ARCHITECTURES)
180 if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
181 set(implicit_libs "")
185 set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
186 set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
187 set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)
189 cmake_parse_library_architecture(${lang} "${implicit_dirs}" "${implicit_objs}" architecture_flag)
190 if(architecture_flag)
191 set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${architecture_flag}" PARENT_SCOPE)
195 message(CHECK_FAIL "failed")
196 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
197 "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n")