Android-Common.cmake 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. # Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. # file Copyright.txt or https://cmake.org/licensing for details.
  3. # This module is shared by multiple languages; use include blocker.
  4. if(__ANDROID_COMPILER_COMMON)
  5. return()
  6. endif()
  7. set(__ANDROID_COMPILER_COMMON 1)
  8. if(CMAKE_ANDROID_NDK)
  9. # <ndk>/build/core/definitions.mk
  10. set(_ANDROID_STL_TYPES
  11. none
  12. system
  13. c++_static
  14. c++_shared
  15. gabi++_static
  16. gabi++_shared
  17. gnustl_static
  18. gnustl_shared
  19. stlport_static
  20. stlport_shared
  21. )
  22. if(CMAKE_ANDROID_STL_TYPE)
  23. list(FIND _ANDROID_STL_TYPES "${CMAKE_ANDROID_STL_TYPE}" _ANDROID_STL_TYPE_FOUND)
  24. if(_ANDROID_STL_TYPE_FOUND EQUAL -1)
  25. string(REPLACE ";" "\n " _msg ";${_ANDROID_STL_TYPES}")
  26. message(FATAL_ERROR
  27. "The CMAKE_ANDROID_STL_TYPE '${CMAKE_ANDROID_STL_TYPE}' is not one of the allowed values:${_msg}\n"
  28. )
  29. endif()
  30. unset(_ANDROID_STL_TYPE_FOUND)
  31. elseif(IS_DIRECTORY ${CMAKE_ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++)
  32. set(CMAKE_ANDROID_STL_TYPE "gnustl_static")
  33. else()
  34. set(CMAKE_ANDROID_STL_TYPE "c++_static")
  35. endif()
  36. unset(_ANDROID_STL_TYPES)
  37. # Forward Android-specific platform variables to try_compile projects.
  38. list(APPEND CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
  39. CMAKE_ANDROID_STL_TYPE
  40. )
  41. endif()
  42. if(CMAKE_ANDROID_STL_TYPE)
  43. if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
  44. if(CMAKE_ANDROID_STL_TYPE STREQUAL "system")
  45. set(_ANDROID_STL_EXCEPTIONS 0)
  46. set(_ANDROID_STL_RTTI 0)
  47. macro(__android_stl lang)
  48. string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libstdc++")
  49. endmacro()
  50. elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_static")
  51. set(_ANDROID_STL_EXCEPTIONS 1)
  52. set(_ANDROID_STL_RTTI 1)
  53. macro(__android_stl lang)
  54. string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
  55. string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -static-libstdc++")
  56. endmacro()
  57. elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "c++_shared")
  58. set(_ANDROID_STL_EXCEPTIONS 1)
  59. set(_ANDROID_STL_RTTI 1)
  60. macro(__android_stl lang)
  61. string(APPEND CMAKE_${lang}_FLAGS_INIT " -stdlib=libc++")
  62. endmacro()
  63. elseif(CMAKE_ANDROID_STL_TYPE STREQUAL "none")
  64. set(_ANDROID_STL_RTTI 0)
  65. set(_ANDROID_STL_EXCEPTIONS 0)
  66. macro(__android_stl lang)
  67. # FIXME: Add a way to add project-wide language-specific compile-only flags.
  68. set(CMAKE_CXX_COMPILE_OBJECT
  69. "<CMAKE_CXX_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> -nostdinc++")
  70. string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -nostdlib++")
  71. endmacro()
  72. else()
  73. message(FATAL_ERROR
  74. "Android: STL '${CMAKE_ANDROID_STL_TYPE}' not supported by this NDK."
  75. )
  76. endif()
  77. elseif(CMAKE_ANDROID_NDK)
  78. macro(__android_stl_inc lang dir req)
  79. if(EXISTS "${dir}")
  80. list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${dir}")
  81. elseif(${req})
  82. message(FATAL_ERROR
  83. "Android: STL '${CMAKE_ANDROID_STL_TYPE}' include directory not found:\n"
  84. " ${dir}"
  85. )
  86. endif()
  87. endmacro()
  88. macro(__android_stl_lib lang lib req)
  89. if(CMAKE_ANDROID_ARCH_ABI MATCHES "^armeabi" AND NOT CMAKE_ANDROID_ARM_MODE)
  90. get_filename_component(_ANDROID_STL_LIBDIR "${lib}" DIRECTORY)
  91. get_filename_component(_ANDROID_STL_LIBNAME "${lib}" NAME)
  92. set(_ANDROID_STL_LIBTHUMB "${_ANDROID_STL_LIBDIR}/thumb/${_ANDROID_STL_LIBNAME}")
  93. unset(_ANDROID_STL_LIBDIR)
  94. unset(_ANDROID_STL_LIBNAME)
  95. else()
  96. set(_ANDROID_STL_LIBTHUMB "")
  97. endif()
  98. if(_ANDROID_STL_LIBTHUMB AND EXISTS "${_ANDROID_STL_LIBTHUMB}")
  99. string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " \"${_ANDROID_STL_LIBTHUMB}\"")
  100. elseif(EXISTS "${lib}")
  101. string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " \"${lib}\"")
  102. elseif(${req})
  103. message(FATAL_ERROR
  104. "Android: STL '${CMAKE_ANDROID_STL_TYPE}' library file not found:\n"
  105. " ${lib}"
  106. )
  107. endif()
  108. unset(_ANDROID_STL_LIBTHUMB)
  109. endmacro()
  110. include(Platform/Android/ndk-stl-${CMAKE_ANDROID_STL_TYPE})
  111. else()
  112. macro(__android_stl lang)
  113. endmacro()
  114. endif()
  115. else()
  116. macro(__android_stl lang)
  117. endmacro()
  118. endif()
  119. # The NDK toolchain configuration files at:
  120. #
  121. # <ndk>/[build/core/]toolchains/*/setup.mk
  122. #
  123. # contain logic to set TARGET_CFLAGS and TARGET_LDFLAGS (and debug/release
  124. # variants) to tell their build system what flags to pass for each ABI.
  125. # We need to produce the same flags here to produce compatible binaries.
  126. # We initialize these variables here and set them in the compiler-specific
  127. # modules that include this one. Then we use them in the macro below when
  128. # it is called.
  129. set(_ANDROID_ABI_INIT_CFLAGS "")
  130. set(_ANDROID_ABI_INIT_CFLAGS_DEBUG "")
  131. set(_ANDROID_ABI_INIT_CFLAGS_RELEASE "")
  132. set(_ANDROID_ABI_INIT_LDFLAGS "")
  133. set(_ANDROID_ABI_INIT_EXE_LDFLAGS "")
  134. macro(__android_compiler_common lang)
  135. if(_ANDROID_ABI_INIT_CFLAGS)
  136. string(APPEND CMAKE_${lang}_FLAGS_INIT " ${_ANDROID_ABI_INIT_CFLAGS}")
  137. endif()
  138. if(_ANDROID_ABI_INIT_CFLAGS_DEBUG)
  139. string(APPEND CMAKE_${lang}_FLAGS_DEBUG_INIT " ${_ANDROID_ABI_INIT_CFLAGS_DEBUG}")
  140. endif()
  141. if(_ANDROID_ABI_INIT_CFLAGS_RELEASE)
  142. string(APPEND CMAKE_${lang}_FLAGS_RELEASE_INIT " ${_ANDROID_ABI_INIT_CFLAGS_RELEASE}")
  143. string(APPEND CMAKE_${lang}_FLAGS_MINSIZEREL_INIT " ${_ANDROID_ABI_INIT_CFLAGS_RELEASE}")
  144. string(APPEND CMAKE_${lang}_FLAGS_RELWITHDEBINFO_INIT " ${_ANDROID_ABI_INIT_CFLAGS_RELEASE}")
  145. endif()
  146. if(_ANDROID_ABI_INIT_LDFLAGS)
  147. foreach(t EXE SHARED MODULE)
  148. string(APPEND CMAKE_${t}_LINKER_FLAGS_INIT " ${_ANDROID_ABI_INIT_LDFLAGS}")
  149. endforeach()
  150. endif()
  151. if(_ANDROID_ABI_INIT_EXE_LDFLAGS)
  152. string(APPEND CMAKE_EXE_LINKER_FLAGS_INIT " ${_ANDROID_ABI_INIT_EXE_LDFLAGS}")
  153. endif()
  154. if(DEFINED _ANDROID_STL_EXCEPTIONS)
  155. if(_ANDROID_STL_EXCEPTIONS)
  156. string(APPEND CMAKE_${lang}_FLAGS_INIT " -fexceptions")
  157. else()
  158. string(APPEND CMAKE_${lang}_FLAGS_INIT " -fno-exceptions")
  159. endif()
  160. endif()
  161. if("x${lang}" STREQUAL "xCXX" AND DEFINED _ANDROID_STL_RTTI)
  162. if(_ANDROID_STL_RTTI)
  163. string(APPEND CMAKE_${lang}_FLAGS_INIT " -frtti")
  164. else()
  165. string(APPEND CMAKE_${lang}_FLAGS_INIT " -fno-rtti")
  166. endif()
  167. endif()
  168. if("x${lang}" STREQUAL "xCXX")
  169. __android_stl(CXX)
  170. endif()
  171. if(CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
  172. string(APPEND CMAKE_${lang}_STANDARD_LIBRARIES " -latomic -lm")
  173. endif()
  174. # <ndk>/build/core/definitions.mk appends the sysroot's include directory
  175. # explicitly at the end of the command-line include path so that it
  176. # precedes the toolchain's builtin include directories. This is
  177. # necessary so that Android API-version-specific headers are preferred
  178. # over those in the toolchain's `include-fixed` directory (which cannot
  179. # possibly match all versions).
  180. #
  181. # Do not do this for a standalone toolchain because it is already
  182. # tied to a specific API version.
  183. if(CMAKE_ANDROID_NDK AND NOT CMAKE_ANDROID_NDK_TOOLCHAIN_UNIFIED)
  184. if(CMAKE_SYSROOT_COMPILE)
  185. set(_cmake_sysroot_compile "${CMAKE_SYSROOT_COMPILE}")
  186. else()
  187. set(_cmake_sysroot_compile "${CMAKE_SYSROOT}")
  188. endif()
  189. if(NOT CMAKE_ANDROID_NDK_DEPRECATED_HEADERS)
  190. list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES
  191. "${_cmake_sysroot_compile}/usr/include"
  192. "${_cmake_sysroot_compile}/usr/include/${CMAKE_ANDROID_ARCH_TRIPLE}"
  193. )
  194. else()
  195. list(APPEND CMAKE_${lang}_STANDARD_INCLUDE_DIRECTORIES "${_cmake_sysroot_compile}/usr/include")
  196. endif()
  197. unset(_cmake_sysroot_compile)
  198. endif()
  199. endmacro()