82a6d21a417101ce98ec142737e11b6c450f9ce9
[platform/upstream/cmake.git] / Modules / CMakeDetermineCompilerABI.cmake
1 # Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
2 # file Copyright.txt or https://cmake.org/licensing for details.
3
4
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
7 # code.
8
9 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitIncludeInfo.cmake)
10 include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
11 include(${CMAKE_ROOT}/Modules/CMakeParseLibraryArchitecture.cmake)
12 include(CMakeTestCompilerCommon)
13
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")
17
18     # Compile the ABI identification source.
19     set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
20     set(CMAKE_FLAGS )
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}")
25     endif()
26     if(DEFINED CMAKE_${lang}_VERBOSE_COMPILE_FLAG)
27       set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_COMPILE_FLAG}")
28     endif()
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")
34       endif()
35       set(CMAKE_CUDA_RUNTIME_LIBRARY "Static")
36     endif()
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=")
41     endif()
42     __TestCompiler_setTryCompileTargetType()
43
44     # Avoid failing ABI detection on warnings.
45     string(REGEX REPLACE "(^| )-Werror([= ][^ ]*)?( |$)" " " CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}")
46
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})
53     set(ENV{LC_ALL}      C)
54     set(ENV{LC_MESSAGES} C)
55     set(ENV{LANG}        C)
56
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
64       COPY_FILE "${BIN}"
65       COPY_FILE_ERROR _copy_error
66       __CMAKE_INTERNAL ABI
67       )
68
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})
73
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)
79     endif()
80     set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED} PARENT_SCOPE)
81
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}")
94         endif()
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 "")
103           endif()
104         endif()
105         if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]" AND NOT ABI_NAME)
106           set(ABI_NAME "${CMAKE_MATCH_1}")
107         endif()
108       endforeach()
109
110       if(ABI_SIZEOF_DPTR)
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)
114       endif()
115
116       if(ABI_BYTE_ORDER)
117         set(CMAKE_${lang}_BYTE_ORDER "${ABI_BYTE_ORDER}" PARENT_SCOPE)
118       endif()
119
120       if(ABI_NAME)
121         set(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
122       endif()
123
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})
136           endif()
137
138           # We parsed implicit include directories, so override the default initializer.
139           set(_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT "${implicit_incdirs}")
140         endif()
141       endif()
142       set(CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "${_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT}" PARENT_SCOPE)
143
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")
155       endif()
156       # for VS IDE Intel Fortran we have to figure out the
157       # implicit link path for the fortran run time using
158       # a try-compile
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
166           IntelFortranImplicit
167           CMAKE_FLAGS
168           "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
169           OUTPUT_VARIABLE _output)
170         file(WRITE
171           "${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
172           "${_output}")
173         include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
174         message(CHECK_PASS "done")
175       endif()
176
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 "")
182         endif()
183       endif()
184
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)
188
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)
192       endif()
193
194     else()
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")
198     endif()
199   endif()
200 endfunction()