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 9include(${CMAKE_ROOT}/Modules/CMakeParseImplicitIncludeInfo.cmake) 10include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake) 11include(${CMAKE_ROOT}/Modules/CMakeParseLibraryArchitecture.cmake) 12include(CMakeTestCompilerCommon) 13 14function(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(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC") 30 # Avoid adding our own platform standard libraries for compilers 31 # from which we might detect implicit link libraries. 32 list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=") 33 endif() 34 __TestCompiler_setTryCompileTargetType() 35 36 # Avoid failing ABI detection on warnings. 37 string(REGEX REPLACE "(^| )-Werror([= ][^ ]*)?( |$)" " " CMAKE_${lang}_FLAGS "${CMAKE_${lang}_FLAGS}") 38 39 # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables 40 # and set them to "C" that way GCC's "search starts here" text is in 41 # English and we can grok it. 42 set(_orig_lc_all $ENV{LC_ALL}) 43 set(_orig_lc_messages $ENV{LC_MESSAGES}) 44 set(_orig_lang $ENV{LANG}) 45 set(ENV{LC_ALL} C) 46 set(ENV{LC_MESSAGES} C) 47 set(ENV{LANG} C) 48 49 try_compile(CMAKE_${lang}_ABI_COMPILED 50 ${CMAKE_BINARY_DIR} ${src} 51 CMAKE_FLAGS ${CMAKE_FLAGS} 52 # Ignore unused flags when we are just determining the ABI. 53 "--no-warn-unused-cli" 54 COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS} 55 OUTPUT_VARIABLE OUTPUT 56 COPY_FILE "${BIN}" 57 COPY_FILE_ERROR _copy_error 58 __CMAKE_INTERNAL ABI 59 ) 60 61 # Restore original LC_ALL, LC_MESSAGES, and LANG 62 set(ENV{LC_ALL} ${_orig_lc_all}) 63 set(ENV{LC_MESSAGES} ${_orig_lc_messages}) 64 set(ENV{LANG} ${_orig_lang}) 65 66 # Move result from cache to normal variable. 67 set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED}) 68 unset(CMAKE_${lang}_ABI_COMPILED CACHE) 69 if(CMAKE_${lang}_ABI_COMPILED AND _copy_error) 70 set(CMAKE_${lang}_ABI_COMPILED 0) 71 endif() 72 set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED} PARENT_SCOPE) 73 74 # Load the resulting information strings. 75 if(CMAKE_${lang}_ABI_COMPILED) 76 message(CHECK_PASS "done") 77 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log 78 "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n") 79 file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 32 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]") 80 set(ABI_SIZEOF_DPTR "NOTFOUND") 81 set(ABI_BYTE_ORDER "NOTFOUND") 82 set(ABI_NAME "NOTFOUND") 83 foreach(info ${ABI_STRINGS}) 84 if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]" AND NOT ABI_SIZEOF_DPTR) 85 set(ABI_SIZEOF_DPTR "${CMAKE_MATCH_1}") 86 endif() 87 if("${info}" MATCHES "INFO:byte_order\\[(BIG_ENDIAN|LITTLE_ENDIAN)\\]") 88 set(byte_order "${CMAKE_MATCH_1}") 89 if(ABI_BYTE_ORDER STREQUAL "NOTFOUND") 90 # Tentatively use the value because this is the first occurrence. 91 set(ABI_BYTE_ORDER "${byte_order}") 92 elseif(NOT ABI_BYTE_ORDER STREQUAL "${byte_order}") 93 # Drop value because multiple occurrences do not match. 94 set(ABI_BYTE_ORDER "") 95 endif() 96 endif() 97 if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]" AND NOT ABI_NAME) 98 set(ABI_NAME "${CMAKE_MATCH_1}") 99 endif() 100 endforeach() 101 102 if(ABI_SIZEOF_DPTR) 103 set(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE) 104 elseif(CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT) 105 set(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE) 106 endif() 107 108 if(ABI_BYTE_ORDER) 109 set(CMAKE_${lang}_BYTE_ORDER "${ABI_BYTE_ORDER}" PARENT_SCOPE) 110 endif() 111 112 if(ABI_NAME) 113 set(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE) 114 endif() 115 116 # Parse implicit include directory for this language, if available. 117 if(CMAKE_${lang}_VERBOSE_FLAG) 118 set (implicit_incdirs "") 119 cmake_parse_implicit_include_info("${OUTPUT}" "${lang}" 120 implicit_incdirs log rv) 121 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log 122 "Parsed ${lang} implicit include dir info from above output: rv=${rv}\n${log}\n\n") 123 if("${rv}" STREQUAL "done") 124 # Entries that we have been told to explicitly pass as standard include 125 # directories will not be implicitly added by the compiler. 126 if(CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES) 127 list(REMOVE_ITEM implicit_incdirs ${CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES}) 128 endif() 129 130 # We parsed implicit include directories, so override the default initializer. 131 set(_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT "${implicit_incdirs}") 132 endif() 133 endif() 134 set(CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES "${_CMAKE_${lang}_IMPLICIT_INCLUDE_DIRECTORIES_INIT}" PARENT_SCOPE) 135 136 # Parse implicit linker information for this language, if available. 137 set(implicit_dirs "") 138 set(implicit_objs "") 139 set(implicit_libs "") 140 set(implicit_fwks "") 141 if(CMAKE_${lang}_VERBOSE_FLAG) 142 CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log 143 "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}" 144 COMPUTE_IMPLICIT_OBJECTS implicit_objs) 145 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log 146 "Parsed ${lang} implicit link information from above output:\n${log}\n\n") 147 endif() 148 # for VS IDE Intel Fortran we have to figure out the 149 # implicit link path for the fortran run time using 150 # a try-compile 151 if("${lang}" MATCHES "Fortran" 152 AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio") 153 message(CHECK_START "Determine Intel Fortran Compiler Implicit Link Path") 154 # Build a sample project which reports symbols. 155 try_compile(IFORT_LIB_PATH_COMPILED 156 ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath 157 ${CMAKE_ROOT}/Modules/IntelVSImplicitPath 158 IntelFortranImplicit 159 CMAKE_FLAGS 160 "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}" 161 OUTPUT_VARIABLE _output) 162 file(WRITE 163 "${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt" 164 "${_output}") 165 include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL) 166 message(CHECK_PASS "done") 167 endif() 168 169 # Implicit link libraries cannot be used explicitly for multiple 170 # OS X architectures, so we skip it. 171 if(DEFINED CMAKE_OSX_ARCHITECTURES) 172 if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";") 173 set(implicit_libs "") 174 endif() 175 endif() 176 177 set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE) 178 set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE) 179 set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE) 180 181 cmake_parse_library_architecture(${lang} "${implicit_dirs}" "${implicit_objs}" architecture_flag) 182 if(architecture_flag) 183 set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${architecture_flag}" PARENT_SCOPE) 184 endif() 185 186 else() 187 message(CHECK_FAIL "failed") 188 file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log 189 "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n") 190 endif() 191 endif() 192endfunction() 193