CMakeDetermineCompilerABI.cmake 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. # Function to compile a source file to identify the compiler ABI.
  4. # This is used internally by CMake and should not be included by user
  5. # code.
  6. include(${CMAKE_ROOT}/Modules/CMakeParseImplicitLinkInfo.cmake)
  7. include(CMakeTestCompilerCommon)
  8. function(CMAKE_DETERMINE_COMPILER_ABI lang src)
  9. if(NOT DEFINED CMAKE_${lang}_ABI_COMPILED)
  10. message(STATUS "Detecting ${lang} compiler ABI info")
  11. # Compile the ABI identification source.
  12. set(BIN "${CMAKE_PLATFORM_INFO_DIR}/CMakeDetermineCompilerABI_${lang}.bin")
  13. set(CMAKE_FLAGS )
  14. set(COMPILE_DEFINITIONS )
  15. if(DEFINED CMAKE_${lang}_VERBOSE_FLAG)
  16. set(CMAKE_FLAGS "-DEXE_LINKER_FLAGS=${CMAKE_${lang}_VERBOSE_FLAG}")
  17. set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_FLAG}")
  18. endif()
  19. if(DEFINED CMAKE_${lang}_VERBOSE_COMPILE_FLAG)
  20. set(COMPILE_DEFINITIONS "${CMAKE_${lang}_VERBOSE_COMPILE_FLAG}")
  21. endif()
  22. if(NOT "x${CMAKE_${lang}_COMPILER_ID}" STREQUAL "xMSVC")
  23. # Avoid adding our own platform standard libraries for compilers
  24. # from which we might detect implicit link libraries.
  25. list(APPEND CMAKE_FLAGS "-DCMAKE_${lang}_STANDARD_LIBRARIES=")
  26. endif()
  27. __TestCompiler_setTryCompileTargetType()
  28. # Save the current LC_ALL, LC_MESSAGES, and LANG environment variables
  29. # and set them to "C" that way GCC's "search starts here" text is in
  30. # English and we can grok it.
  31. set(_orig_lc_all $ENV{LC_ALL})
  32. set(_orig_lc_messages $ENV{LC_MESSAGES})
  33. set(_orig_lang $ENV{LANG})
  34. set(ENV{LC_ALL} C)
  35. set(ENV{LC_MESSAGES} C)
  36. set(ENV{LANG} C)
  37. try_compile(CMAKE_${lang}_ABI_COMPILED
  38. ${CMAKE_BINARY_DIR} ${src}
  39. CMAKE_FLAGS ${CMAKE_FLAGS}
  40. # Ignore unused flags when we are just determining the ABI.
  41. "--no-warn-unused-cli"
  42. COMPILE_DEFINITIONS ${COMPILE_DEFINITIONS}
  43. OUTPUT_VARIABLE OUTPUT
  44. COPY_FILE "${BIN}"
  45. COPY_FILE_ERROR _copy_error
  46. )
  47. # Restore original LC_ALL, LC_MESSAGES, and LANG
  48. set(ENV{LC_ALL} ${_orig_lc_all})
  49. set(ENV{LC_MESSAGES} ${_orig_lc_messages})
  50. set(ENV{LANG} ${_orig_lang})
  51. # Move result from cache to normal variable.
  52. set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED})
  53. unset(CMAKE_${lang}_ABI_COMPILED CACHE)
  54. set(CMAKE_${lang}_ABI_COMPILED ${CMAKE_${lang}_ABI_COMPILED} PARENT_SCOPE)
  55. # Load the resulting information strings.
  56. if(CMAKE_${lang}_ABI_COMPILED AND NOT _copy_error)
  57. message(STATUS "Detecting ${lang} compiler ABI info - done")
  58. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  59. "Detecting ${lang} compiler ABI info compiled with the following output:\n${OUTPUT}\n\n")
  60. file(STRINGS "${BIN}" ABI_STRINGS LIMIT_COUNT 2 REGEX "INFO:[A-Za-z0-9_]+\\[[^]]*\\]")
  61. foreach(info ${ABI_STRINGS})
  62. if("${info}" MATCHES "INFO:sizeof_dptr\\[0*([^]]*)\\]")
  63. set(ABI_SIZEOF_DPTR "${CMAKE_MATCH_1}")
  64. endif()
  65. if("${info}" MATCHES "INFO:abi\\[([^]]*)\\]")
  66. set(ABI_NAME "${CMAKE_MATCH_1}")
  67. endif()
  68. endforeach()
  69. if(ABI_SIZEOF_DPTR)
  70. set(CMAKE_${lang}_SIZEOF_DATA_PTR "${ABI_SIZEOF_DPTR}" PARENT_SCOPE)
  71. elseif(CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT)
  72. set(CMAKE_${lang}_SIZEOF_DATA_PTR "${CMAKE_${lang}_SIZEOF_DATA_PTR_DEFAULT}" PARENT_SCOPE)
  73. endif()
  74. if(ABI_NAME)
  75. set(CMAKE_${lang}_COMPILER_ABI "${ABI_NAME}" PARENT_SCOPE)
  76. endif()
  77. # Parse implicit linker information for this language, if available.
  78. set(implicit_dirs "")
  79. set(implicit_libs "")
  80. set(implicit_fwks "")
  81. if(CMAKE_${lang}_VERBOSE_FLAG)
  82. CMAKE_PARSE_IMPLICIT_LINK_INFO("${OUTPUT}" implicit_libs implicit_dirs implicit_fwks log
  83. "${CMAKE_${lang}_IMPLICIT_OBJECT_REGEX}")
  84. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeOutput.log
  85. "Parsed ${lang} implicit link information from above output:\n${log}\n\n")
  86. endif()
  87. # for VS IDE Intel Fortran we have to figure out the
  88. # implicit link path for the fortran run time using
  89. # a try-compile
  90. if("${lang}" MATCHES "Fortran"
  91. AND "${CMAKE_GENERATOR}" MATCHES "Visual Studio")
  92. set(_desc "Determine Intel Fortran Compiler Implicit Link Path")
  93. message(STATUS "${_desc}")
  94. # Build a sample project which reports symbols.
  95. try_compile(IFORT_LIB_PATH_COMPILED
  96. ${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath
  97. ${CMAKE_ROOT}/Modules/IntelVSImplicitPath
  98. IntelFortranImplicit
  99. CMAKE_FLAGS
  100. "-DCMAKE_Fortran_FLAGS:STRING=${CMAKE_Fortran_FLAGS}"
  101. OUTPUT_VARIABLE _output)
  102. file(WRITE
  103. "${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.txt"
  104. "${_output}")
  105. include(${CMAKE_BINARY_DIR}/CMakeFiles/IntelVSImplicitPath/output.cmake OPTIONAL)
  106. set(_desc "Determine Intel Fortran Compiler Implicit Link Path -- done")
  107. message(STATUS "${_desc}")
  108. endif()
  109. # Implicit link libraries cannot be used explicitly for multiple
  110. # OS X architectures, so we skip it.
  111. if(DEFINED CMAKE_OSX_ARCHITECTURES)
  112. if("${CMAKE_OSX_ARCHITECTURES}" MATCHES ";")
  113. set(implicit_libs "")
  114. endif()
  115. endif()
  116. set(CMAKE_${lang}_IMPLICIT_LINK_LIBRARIES "${implicit_libs}" PARENT_SCOPE)
  117. set(CMAKE_${lang}_IMPLICIT_LINK_DIRECTORIES "${implicit_dirs}" PARENT_SCOPE)
  118. set(CMAKE_${lang}_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "${implicit_fwks}" PARENT_SCOPE)
  119. # Detect library architecture directory name.
  120. if(CMAKE_LIBRARY_ARCHITECTURE_REGEX)
  121. foreach(dir ${implicit_dirs})
  122. if("${dir}" MATCHES "/lib/${CMAKE_LIBRARY_ARCHITECTURE_REGEX}$")
  123. get_filename_component(arch "${dir}" NAME)
  124. set(CMAKE_${lang}_LIBRARY_ARCHITECTURE "${arch}" PARENT_SCOPE)
  125. break()
  126. endif()
  127. endforeach()
  128. endif()
  129. else()
  130. message(STATUS "Detecting ${lang} compiler ABI info - failed")
  131. file(APPEND ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeError.log
  132. "Detecting ${lang} compiler ABI info failed to compile with the following output:\n${OUTPUT}\n${_copy_error}\n\n")
  133. endif()
  134. endif()
  135. endfunction()