android_gradle_projects.cmake 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. # https://developer.android.com/studio/releases/gradle-plugin
  2. set(ANDROID_GRADLE_PLUGIN_VERSION "8.6.0" CACHE STRING "Android Gradle Plugin version")
  3. message(STATUS "Android Gradle Plugin version: ${ANDROID_GRADLE_PLUGIN_VERSION}")
  4. set(KOTLIN_PLUGIN_VERSION "1.8.20" CACHE STRING "Kotlin Plugin version")
  5. message(STATUS "Kotlin Plugin version: ${KOTLIN_PLUGIN_VERSION}")
  6. if(BUILD_KOTLIN_EXTENSIONS)
  7. set(KOTLIN_PLUGIN_DECLARATION "apply plugin: 'kotlin-android'" CACHE STRING "Kotlin Plugin version")
  8. set(KOTLIN_STD_LIB "implementation 'org.jetbrains.kotlin:kotlin-stdlib:${KOTLIN_PLUGIN_VERSION}'" CACHE STRING "Kotlin Standard Library dependency")
  9. else()
  10. set(KOTLIN_PLUGIN_DECLARATION "" CACHE STRING "Kotlin Plugin version")
  11. set(KOTLIN_STD_LIB "" CACHE STRING "Kotlin Standard Library dependency")
  12. endif()
  13. set(GRADLE_VERSION "8.11.1" CACHE STRING "Gradle version")
  14. message(STATUS "Gradle version: ${GRADLE_VERSION}")
  15. set(ANDROID_COMPILE_SDK_VERSION "34" CACHE STRING "Android compileSdkVersion")
  16. if(ANDROID_NATIVE_API_LEVEL GREATER 21)
  17. set(ANDROID_MIN_SDK_VERSION "${ANDROID_NATIVE_API_LEVEL}" CACHE STRING "Android minSdkVersion")
  18. else()
  19. set(ANDROID_MIN_SDK_VERSION "21" CACHE STRING "Android minSdkVersion")
  20. endif()
  21. set(ANDROID_TARGET_SDK_VERSION "34" CACHE STRING "Android targetSdkVersion")
  22. set(ANDROID_BUILD_BASE_DIR "${OpenCV_BINARY_DIR}/opencv_android" CACHE INTERNAL "")
  23. set(ANDROID_TMP_INSTALL_BASE_DIR "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/install/opencv_android")
  24. set(ANDROID_INSTALL_SAMPLES_DIR "samples")
  25. set(ANDROID_BUILD_ABI_FILTER "
  26. reset()
  27. include '${ANDROID_ABI}'
  28. ")
  29. set(ANDROID_INSTALL_ABI_FILTER "
  30. reset()
  31. include 'armeabi-v7a'
  32. include 'arm64-v8a'
  33. include 'x86'
  34. include 'x86_64'
  35. ")
  36. if(NOT INSTALL_CREATE_DISTRIB)
  37. set(ANDROID_INSTALL_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
  38. endif()
  39. # BUG: Ninja generator generates broken targets with ANDROID_ABI_FILTER name (CMake 3.11.2)
  40. #set(__spaces " ")
  41. #string(REPLACE "\n" "\n${__spaces}" ANDROID_ABI_FILTER "${__spaces}${ANDROID_BUILD_ABI_FILTER}")
  42. #string(REPLACE REGEX "[ ]+$" "" ANDROID_ABI_FILTER "${ANDROID_ABI_FILTER}")
  43. set(ANDROID_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
  44. set(ANDROID_STRICT_BUILD_CONFIGURATION "true")
  45. configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_BUILD_BASE_DIR}/build.gradle" @ONLY)
  46. set(ANDROID_ABI_FILTER "${ANDROID_INSTALL_ABI_FILTER}")
  47. # CI uses NDK 26d to overcome https://github.com/opencv/opencv/issues/26072
  48. # It's ahead of default configuration and we have to force version to get non-controversial parts of the package
  49. #set(ANDROID_STRICT_BUILD_CONFIGURATION "false")
  50. configure_file("${OpenCV_SOURCE_DIR}/samples/android/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" @ONLY)
  51. install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/${ANDROID_INSTALL_SAMPLES_DIR}/build.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}" COMPONENT samples)
  52. configure_file("${OpenCV_SOURCE_DIR}/platforms/android/gradle-wrapper/gradle/wrapper/gradle-wrapper.properties.in" "${ANDROID_BUILD_BASE_DIR}/gradle/wrapper/gradle-wrapper.properties" @ONLY)
  53. install(FILES "${ANDROID_BUILD_BASE_DIR}/gradle/wrapper/gradle-wrapper.properties" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/gradle/wrapper" COMPONENT samples)
  54. set(GRADLE_WRAPPER_FILES
  55. "gradle/wrapper/gradle-wrapper.jar"
  56. "gradlew.bat"
  57. "gradlew"
  58. "gradle.properties"
  59. )
  60. foreach(fname ${GRADLE_WRAPPER_FILES})
  61. get_filename_component(__dir "${fname}" DIRECTORY)
  62. set(__permissions "")
  63. set(__permissions_prefix "")
  64. if(fname STREQUAL "gradlew")
  65. set(__permissions FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
  66. endif()
  67. file(COPY "${OpenCV_SOURCE_DIR}/platforms/android/gradle-wrapper/${fname}" DESTINATION "${ANDROID_BUILD_BASE_DIR}/${__dir}" ${__permissions})
  68. string(REPLACE "FILE_PERMISSIONS" "PERMISSIONS" __permissions "${__permissions}")
  69. if("${__dir}" STREQUAL "")
  70. set(__dir ".")
  71. endif()
  72. install(FILES "${OpenCV_SOURCE_DIR}/platforms/android/gradle-wrapper/${fname}" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples ${__permissions})
  73. endforeach()
  74. # set build.gradle namespace
  75. if(NOT (ANDROID_GRADLE_PLUGIN_VERSION VERSION_LESS "7.3.0"))
  76. ocv_update(OPENCV_ANDROID_NAMESPACE_DECLARATION "namespace 'org.opencv'")
  77. else()
  78. ocv_update(OPENCV_ANDROID_NAMESPACE_DECLARATION "")
  79. endif()
  80. if(NOT (ANDROID_GRADLE_PLUGIN_VERSION VERSION_LESS "8.0.0"))
  81. # AGP-8.0 requires a minimum JDK version of JDK17
  82. ocv_update(ANDROID_GRADLE_JAVA_VERSION_INIT "17")
  83. else()
  84. ocv_update(ANDROID_GRADLE_JAVA_VERSION_INIT "1_8")
  85. endif()
  86. set(ANDROID_GRADLE_JAVA_VERSION "${ANDROID_GRADLE_JAVA_VERSION_INIT}" CACHE STRING "Android Gradle Java version")
  87. message(STATUS "Android Gradle Java version: ${ANDROID_GRADLE_JAVA_VERSION}")
  88. # force reusing of the same CMake version
  89. if(NOT OPENCV_SKIP_ANDROID_FORCE_CMAKE)
  90. if(NOT DEFINED _CMAKE_INSTALL_DIR)
  91. get_filename_component(_CMAKE_INSTALL_DIR "${CMAKE_ROOT}" PATH)
  92. get_filename_component(_CMAKE_INSTALL_DIR "${_CMAKE_INSTALL_DIR}" PATH)
  93. endif()
  94. ocv_update_file("${ANDROID_BUILD_BASE_DIR}/local.properties" "cmake.dir=${_CMAKE_INSTALL_DIR}\nndk.dir=${ANDROID_NDK}")
  95. endif()
  96. file(WRITE "${ANDROID_BUILD_BASE_DIR}/settings.gradle" "
  97. gradle.ext {
  98. // possible options: 'maven_central', 'maven_local', 'sdk_path'
  99. opencv_source = 'sdk_path'
  100. }
  101. include ':opencv'
  102. ")
  103. file(WRITE "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" "
  104. rootProject.name = 'opencv_samples'
  105. gradle.ext {
  106. // possible options: 'maven_central', 'maven_local', 'sdk_path'
  107. opencv_source = 'sdk_path'
  108. }
  109. if (gradle.opencv_source == 'maven_local') {
  110. gradle.ext {
  111. opencv_maven_path = '<path_to_maven_repo>'
  112. }
  113. }
  114. if (gradle.opencv_source == 'sdk_path') {
  115. def opencvsdk = '../'
  116. //def opencvsdk='/<path to OpenCV-android-sdk>'
  117. //println opencvsdk
  118. include ':opencv'
  119. project(':opencv').projectDir = new File(opencvsdk + '/sdk')
  120. }
  121. ")
  122. ocv_check_environment_variables(OPENCV_GRADLE_VERBOSE_OPTIONS)
  123. ocv_update(OPENCV_GRADLE_VERBOSE_OPTIONS "-i")
  124. separate_arguments(OPENCV_GRADLE_VERBOSE_OPTIONS UNIX_COMMAND "${OPENCV_GRADLE_VERBOSE_OPTIONS}")
  125. macro(add_android_project target path)
  126. get_filename_component(__dir "${path}" NAME)
  127. set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "")
  128. if(DEFINED ANDROID_TOOLCHAIN)
  129. set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "${OPENCV_ANDROID_CMAKE_EXTRA_ARGS},\n\"-DANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN}\"")
  130. endif()
  131. if(DEFINED ANDROID_STL)
  132. set(OPENCV_ANDROID_CMAKE_EXTRA_ARGS "${OPENCV_ANDROID_CMAKE_EXTRA_ARGS},\n\"-DANDROID_STL=${ANDROID_STL}\"")
  133. endif()
  134. #
  135. # Build
  136. #
  137. set(ANDROID_SAMPLE_JNI_PATH "${path}/jni")
  138. set(ANDROID_SAMPLE_JAVA_PATH "${path}/src")
  139. set(ANDROID_SAMPLE_RES_PATH "${path}/res")
  140. set(ANDROID_SAMPLE_MANIFEST_PATH "${path}/gradle/AndroidManifest.xml")
  141. set(ANDROID_ABI_FILTER "${ANDROID_BUILD_ABI_FILTER}")
  142. set(ANDROID_PROJECT_JNI_PATH "../../")
  143. string(REPLACE ";" "', '" ANDROID_SAMPLE_JAVA_PATH "['${ANDROID_SAMPLE_JAVA_PATH}']")
  144. string(REPLACE ";" "', '" ANDROID_SAMPLE_RES_PATH "['${ANDROID_SAMPLE_RES_PATH}']")
  145. configure_file("${path}/build.gradle.in" "${ANDROID_BUILD_BASE_DIR}/${__dir}/build.gradle" @ONLY)
  146. file(APPEND "${ANDROID_BUILD_BASE_DIR}/settings.gradle" "
  147. include ':${__dir}'
  148. ")
  149. if (BUILD_ANDROID_EXAMPLES)
  150. # build apk
  151. set(APK_FILE "${ANDROID_BUILD_BASE_DIR}/${__dir}/build/outputs/apk/release/${__dir}-${ANDROID_ABI}-release-unsigned.apk")
  152. add_custom_command(
  153. OUTPUT "${APK_FILE}" "${OPENCV_DEPHELPER}/android_sample_${__dir}"
  154. COMMAND ./gradlew ${OPENCV_GRADLE_VERBOSE_OPTIONS} "${__dir}:assemble"
  155. COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/android_sample_${__dir}"
  156. WORKING_DIRECTORY "${ANDROID_BUILD_BASE_DIR}"
  157. DEPENDS ${depends} opencv_java_android
  158. COMMENT "Building OpenCV Android sample project: ${__dir}"
  159. )
  160. else() # install only
  161. # copy samples
  162. add_custom_command(
  163. OUTPUT "${OPENCV_DEPHELPER}/android_sample_${__dir}"
  164. COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/android_sample_${__dir}"
  165. WORKING_DIRECTORY "${ANDROID_BUILD_BASE_DIR}"
  166. DEPENDS ${depends} opencv_java_android
  167. COMMENT "Copying OpenCV Android sample project: ${__dir}"
  168. )
  169. endif()
  170. file(REMOVE "${OPENCV_DEPHELPER}/android_sample_${__dir}") # force rebuild after CMake run
  171. add_custom_target(android_sample_${__dir} ALL DEPENDS "${OPENCV_DEPHELPER}/android_sample_${__dir}" SOURCES "${ANDROID_SAMPLE_MANIFEST_PATH}")
  172. #
  173. # Install
  174. #
  175. set(ANDROID_SAMPLE_JNI_PATH "jni")
  176. set(ANDROID_SAMPLE_JAVA_PATH "src")
  177. set(ANDROID_SAMPLE_RES_PATH "res")
  178. set(ANDROID_SAMPLE_MANIFEST_PATH "AndroidManifest.xml")
  179. install(DIRECTORY "${path}/res" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples OPTIONAL)
  180. install(DIRECTORY "${path}/src" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
  181. install(DIRECTORY "${path}/jni" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples OPTIONAL)
  182. install(FILES "${path}/gradle/AndroidManifest.xml" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
  183. set(ANDROID_ABI_FILTER "${ANDROID_INSTALL_ABI_FILTER}")
  184. set(ANDROID_PROJECT_JNI_PATH "native/jni")
  185. string(REPLACE ";" "', '" ANDROID_SAMPLE_JAVA_PATH "['${ANDROID_SAMPLE_JAVA_PATH}']")
  186. string(REPLACE ";" "', '" ANDROID_SAMPLE_RES_PATH "['${ANDROID_SAMPLE_RES_PATH}']")
  187. configure_file("${path}/build.gradle.in" "${ANDROID_TMP_INSTALL_BASE_DIR}/${__dir}/build.gradle" @ONLY)
  188. install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/${__dir}/build.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}/${__dir}" COMPONENT samples)
  189. file(APPEND "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" "
  190. include ':${__dir}'
  191. ")
  192. endmacro()
  193. install(FILES "${ANDROID_TMP_INSTALL_BASE_DIR}/settings.gradle" DESTINATION "${ANDROID_INSTALL_SAMPLES_DIR}" COMPONENT samples)