Warning, /frameworks/extra-cmake-modules/modules/ECMAddAndroidApk.cmake is written in an unsupported language. File is not indexed.
0001 # SPDX-FileCopyrightText: 2018-2023 Aleix Pol <aleixpol@kde.org> 0002 # SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org> 0003 # SPDX-License-Identifier: BSD-2-Clause 0004 0005 #[=======================================================================[.rst: 0006 ECMAddAndroidApk 0007 ---------------- 0008 0009 Functions for creating Android APK packages using Qt6's ``androiddeployqt`` tool 0010 as well as the associated Fastlane metadata. 0011 0012 :: 0013 0014 ecm_add_android_apk(<target> 0015 [ANDROID_DIR <dir>] 0016 # TODO extra args? 0017 ) 0018 0019 Creates an Android APK for the given target. 0020 0021 If ``ANDROID_DIR`` is given, the Android manifest file as well as any potential 0022 Gradle build system files or Java/Kotlin source files are taken from that directory. 0023 If not set, the standard template shipped with Qt6 is used, which in usually not 0024 what you want for production applications. 0025 0026 The use of this function creates a build target called ``create-apk-<target>`` 0027 which will run ``androiddeployqt`` to produce an (unsigned) APK, as well 0028 as convert Appstream application metadata (if present) into the Fastlane format used 0029 by F-Droid and Play store automation. 0030 0031 There's also a ``create-apk`` convenience target being created that 0032 will build all APKs defined in a project. 0033 0034 When building for another platform than Android, this function does nothing. 0035 0036 The following variables impact the behavior: 0037 ``ECM_ADDITIONAL_FIND_ROOT_PATH`` 0038 See documentation in the Android toolchain file. 0039 0040 ``ECM_APK_STAGING_ROOT_PATH`` 0041 For use with Craft's image directory. If set this is used as the source 0042 for all content of the APK rather than the search paths used for building. 0043 This allows to separate e.g. development files from what ends up in the APK. 0044 0045 Since 6.0.0 0046 #]=======================================================================] 0047 0048 # make ExecuteCoreModules test pass on Qt5 0049 include(${CMAKE_CURRENT_LIST_DIR}/../modules/QtVersionOption.cmake) 0050 if (QT_MAJOR_VERSION EQUAL 5) 0051 message(WARNING "ECMAddAndroidApk is not compatible with Qt5 - skipping.") 0052 return() 0053 endif() 0054 0055 find_package(Qt6Core REQUIRED) # required for the following to work stand-alone 0056 find_package(Qt6CoreTools REQUIRED) 0057 find_package(Python3 COMPONENTS Interpreter REQUIRED) 0058 0059 set(_ECM_TOOLCHAIN_DIR "${CMAKE_CURRENT_LIST_DIR}/../toolchain") 0060 0061 function (ecm_add_android_apk TARGET) 0062 cmake_parse_arguments(ARGS "" "ANDROID_DIR" "" ${ARGN}) 0063 if (NOT ANDROID) 0064 return() 0065 endif() 0066 0067 set(APK_OUTPUT_DIR "${CMAKE_BINARY_DIR}/${TARGET}_build_apk/") 0068 set(APK_EXECUTABLE_PATH "${APK_OUTPUT_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/lib${TARGET}_${CMAKE_ANDROID_ARCH_ABI}.so") 0069 0070 set(QML_IMPORT_PATHS "") 0071 # add build directory to the search path as well, so this works without installation 0072 if (EXISTS ${CMAKE_BINARY_DIR}/lib) 0073 set(QML_IMPORT_PATHS ${CMAKE_BINARY_DIR}/lib) 0074 endif() 0075 if (ECM_APK_STAGING_ROOT_PATH) 0076 set(QML_IMPORT_PATHS "${ECM_APK_STAGING_ROOT_PATH}/lib/qml") 0077 set(ANDROID_QT6_INSTALL_PREFIX ${ECM_APK_STAGING_ROOT_PATH}) 0078 else() 0079 foreach(prefix ${ECM_ADDITIONAL_FIND_ROOT_PATH}) 0080 # qmlimportscanner chokes on symlinks, so we need to resolve those first 0081 get_filename_component(qml_path "${prefix}/lib/qml" REALPATH) 0082 if(EXISTS ${qml_path}) 0083 if (QML_IMPORT_PATHS) 0084 set(QML_IMPORT_PATHS "${QML_IMPORT_PATHS},${qml_path}") 0085 else() 0086 set(QML_IMPORT_PATHS "${qml_path}") 0087 endif() 0088 endif() 0089 endforeach() 0090 set(ANDROID_QT6_INSTALL_PREFIX ${QT6_INSTALL_PREFIX}) 0091 endif() 0092 if (QML_IMPORT_PATHS) 0093 set(DEFINE_QML_IMPORT_PATHS "\"qml-import-paths\": \"${QML_IMPORT_PATHS}\",") 0094 endif() 0095 0096 set(EXTRA_PREFIX_DIRS "\"${CMAKE_BINARY_DIR}\"") 0097 set(EXTRA_LIB_DIRS "\"${CMAKE_BINARY_DIR}/lib\"") 0098 if (ECM_APK_STAGING_ROOT_PATH) 0099 set(EXTRA_PREFIX_DIRS "${EXTRA_PREFIX_DIRS}, \"${ECM_APK_STAGING_ROOT_PATH}\"") 0100 set(EXTRA_LIB_DIRS "${EXTRA_LIB_DIRS}, \"${ECM_APK_STAGING_ROOT_PATH}/lib\"") 0101 else() 0102 foreach(prefix ${ECM_ADDITIONAL_FIND_ROOT_PATH}) 0103 set(EXTRA_PREFIX_DIRS "${EXTRA_PREFIX_DIRS}, \"${prefix}\"") 0104 set(EXTRA_LIB_DIRS "${EXTRA_LIB_DIRS}, \"${prefix}/lib\"") 0105 endforeach() 0106 endif() 0107 0108 if (ARGS_ANDROID_DIR AND EXISTS ${ARGS_ANDROID_DIR}/AndroidManifest.xml) 0109 set(ANDROID_APK_DIR ${ARGS_ANDROID_DIR}) 0110 else() 0111 message("Using default Qt APK template - this is often not intentional!") 0112 get_filename_component(_qtCore_install_prefix "${Qt6Core_DIR}/../../../" ABSOLUTE) 0113 set(ANDROID_APK_DIR "${_qtCore_install_prefix}/src/android/templates/") 0114 endif() 0115 0116 get_target_property(QT6_RCC_BINARY Qt6::rcc LOCATION) 0117 string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" _LOWER_CMAKE_HOST_SYSTEM_NAME) 0118 configure_file("${_ECM_TOOLCHAIN_DIR}/deployment-file-qt6.json.in" "${CMAKE_BINARY_DIR}/${TARGET}-deployment.json.in") 0119 0120 if (NOT TARGET create-apk) 0121 add_custom_target(create-apk) 0122 if (NOT DEFINED ANDROID_FASTLANE_METADATA_OUTPUT_DIR) 0123 set(ANDROID_FASTLANE_METADATA_OUTPUT_DIR ${CMAKE_BINARY_DIR}/fastlane) 0124 endif() 0125 add_custom_target(create-fastlane 0126 COMMAND Python3::Interpreter ${_ECM_TOOLCHAIN_DIR}/generate-fastlane-metadata.py --output ${ANDROID_FASTLANE_METADATA_OUTPUT_DIR} --source ${CMAKE_SOURCE_DIR} 0127 ) 0128 endif() 0129 0130 if (NOT DEFINED ANDROID_APK_OUTPUT_DIR) 0131 set(ANDROID_APK_OUTPUT_DIR ${APK_OUTPUT_DIR}) 0132 endif() 0133 0134 if (CMAKE_GENERATOR STREQUAL "Unix Makefiles") 0135 set(arguments "\\$(ARGS)") 0136 endif() 0137 0138 if (NOT ECM_APK_STAGING_ROOT_PATH) 0139 set(ECM_APK_STAGING_ROOT_PATH "${CMAKE_INSTALL_PREFIX}") 0140 endif() 0141 0142 file(WRITE ${CMAKE_BINARY_DIR}/ranlib "${CMAKE_RANLIB}") 0143 set(CREATEAPK_TARGET_NAME "create-apk-${TARGET}") 0144 add_custom_target(${CREATEAPK_TARGET_NAME} 0145 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 0146 COMMAND ${CMAKE_COMMAND} -E echo "Generating $<TARGET_NAME:${TARGET}> with $<TARGET_FILE:Qt6::androiddeployqt>" 0147 COMMAND ${CMAKE_COMMAND} -E remove_directory "${APK_OUTPUT_DIR}" 0148 COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${TARGET}>" "${APK_EXECUTABLE_PATH}" 0149 COMMAND LANG=C ${CMAKE_COMMAND} "-DTARGET=$<TARGET_FILE:${TARGET}>" -P ${_ECM_TOOLCHAIN_DIR}/hasMainSymbol.cmake 0150 COMMAND LANG=C ${CMAKE_COMMAND} 0151 -DINPUT_FILE="${CMAKE_BINARY_DIR}/${TARGET}-deployment.json.in" 0152 -DOUTPUT_FILE="${CMAKE_BINARY_DIR}/${TARGET}-deployment.json" 0153 "-DTARGET=$<TARGET_FILE:${TARGET}>" 0154 "-DOUTPUT_DIR=$<TARGET_FILE_DIR:${TARGET}>" 0155 "-DEXPORT_DIR=${ECM_APK_STAGING_ROOT_PATH}" 0156 "-DECM_ADDITIONAL_FIND_ROOT_PATH=\"${ECM_ADDITIONAL_FIND_ROOT_PATH}\"" 0157 -P ${_ECM_TOOLCHAIN_DIR}/specifydependencies.cmake 0158 COMMAND Qt6::androiddeployqt 0159 ${ANDROIDDEPLOYQT_EXTRA_ARGS} 0160 --gradle 0161 --input "${CMAKE_BINARY_DIR}/${TARGET}-deployment.json" 0162 --apk "${ANDROID_APK_OUTPUT_DIR}/${TARGET}-${CMAKE_ANDROID_ARCH_ABI}.apk" 0163 --output "${APK_OUTPUT_DIR}" 0164 --android-platform android-${ANDROID_SDK_COMPILE_API} 0165 --deployment bundled 0166 --qml-importscanner-binary $<TARGET_FILE:Qt6::qmlimportscanner> 0167 ${arguments} 0168 ) 0169 0170 add_dependencies(create-apk ${CREATEAPK_TARGET_NAME}) 0171 add_dependencies(${CREATEAPK_TARGET_NAME} create-fastlane) 0172 endfunction()