diff options
-rw-r--r-- | cmake/QtPlatformAndroid.cmake | 226 | ||||
-rw-r--r-- | mkspecs/features/android/android_deployment_settings.prf | 3 | ||||
-rw-r--r-- | qmake/doc/src/qmake-manual.qdoc | 13 | ||||
-rw-r--r-- | src/android/templates/AndroidManifest.xml | 2 | ||||
-rw-r--r-- | src/corelib/Qt5AndroidSupport.cmake | 2 | ||||
-rw-r--r-- | src/tools/androiddeployqt/main.cpp | 10 |
6 files changed, 254 insertions, 2 deletions
diff --git a/cmake/QtPlatformAndroid.cmake b/cmake/QtPlatformAndroid.cmake index ba5c86d918..dd76b1e81e 100644 --- a/cmake/QtPlatformAndroid.cmake +++ b/cmake/QtPlatformAndroid.cmake @@ -131,6 +131,15 @@ define_property(TARGET define_property(TARGET PROPERTY + QT_ANDROID_APPLICATION_ARGUMENTS + BRIEF_DOCS + "This variable can be used to specify command-line arguments to the Android app." + FULL_DOCS + "Specifies extra command-line arguments to the Android app using the AndroidManifest.xml with the tag android.app.arguments." +) + +define_property(TARGET + PROPERTY QT_ANDROID_DEPLOYMENT_SETTINGS_FILE BRIEF_DOCS " " @@ -138,9 +147,224 @@ define_property(TARGET " " ) +# Generate deployment tool json +function(qt_android_generate_deployment_settings target) + # Information extracted from mkspecs/features/android/android_deployment_settings.prf + if (NOT TARGET ${target}) + message(SEND_ERROR "${target} is not a cmake target") + return() + endif() + + get_target_property(target_type ${target} TYPE) + + if (NOT "${target_type}" STREQUAL "MODULE_LIBRARY") + message(SEND_ERROR "QT_ANDROID_GENERATE_DEPLOYMENT_SETTINGS only works on Module targets") + return() + endif() + + get_target_property(target_source_dir ${target} SOURCE_DIR) + get_target_property(target_binary_dir ${target} BINARY_DIR) + get_target_property(target_output_name ${target} OUTPUT_NAME) + if (NOT target_output_name) + set(target_output_name ${target}) + endif() + set(deploy_file "${target_binary_dir}/android-lib${target_output_name}.so-deployment-settings.json") + + set(file_contents "{\n") + # content begin + string(APPEND file_contents + " \"description\": \"This file is generated by cmake to be read by androiddeployqt and should not be modified by hand.\",\n") + + # Host Qt Android install path + if (NOT QT_BUILDING_QT) + set(file_check "${Qt6_DIR}/plugins/platforms/android/libqtforandroid_${CMAKE_ANDROID_ARCH_ABI}.so") + if (NOT EXISTS ${file_check}) + message(SEND_ERROR "Detected Qt installation does not contain libqtforandroid.so. This is most likely due to the installation not being a build of Qt for Android. Please update your settings.") + return() + endif() + set(qt_android_install_dir ${Qt6_Dir}) + else() + # Building from source, use the same install prefix + set(qt_android_install_dir ${CMAKE_INSTALL_PREFIX}) + endif() + + file(TO_NATIVE_PATH "${qt_android_install_dir}" qt_android_install_dir_native) + string(APPEND file_contents + " \"qt\": \"${qt_android_install_dir_native}\",\n") + + # Android SDK path + file(TO_NATIVE_PATH "${ANDROID_SDK_ROOT}" android_sdk_root_native) + string(APPEND file_contents + " \"sdk\": \"${android_sdk_root_native}\",\n") + + # Android SDK Build Tools Revision + string(APPEND file_contents + " \"sdkBuildToolsRevision\": \"${QT_ANDROID_SDK_BUILD_TOOLS_VERSION}\",\n") + + # Android NDK + file(TO_NATIVE_PATH "${ANDROID_NDK}" android_ndk_root_native) + string(APPEND file_contents + " \"ndk\": \"${android_ndk_root_native}\",\n") + + # Setup LLVM toolchain + string(APPEND file_contents + " \"toolchain-prefix\": \"llvm\",\n") + string(APPEND file_contents + " \"tool-prefix\": \"llvm\",\n") + string(APPEND file_contents + " \"useLLVM\": true,\n") + + # NDK Toolchain Version + string(APPEND file_contents + " \"toolchain-version\": \"${CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION}\",\n") + + # NDK Host + string(APPEND file_contents + " \"ndk-host\": \"${ANDROID_NDK_HOST_SYSTEM_NAME}\",\n") + + if (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86") + set(arch_value "i686-linux-android") + elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "x86_64") + set(arch_value "x86_64-linux-android") + elseif (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") + set(arch_value "aarch64-linux-android") + else() + set(arch_value "arm-linux-androideabi") + endif() + + # Architecture + string(APPEND file_contents + " \"architectures\": { \"${CMAKE_ANDROID_ARCH_ABI}\" : \"${arch_value}\" },\n") + + # deployment dependencies + get_target_property(android_deployment_dependencies + ${target} QT_ANDROID_DEPLOYMENT_DEPENDENCIES) + if (android_deployment_dependencies) + list(JOIN android_deployment_dependencies "," android_deployment_dependencies) + string(APPEND file_contents + " \"deployment-dependencies\": \"${android_deployment_dependencies}\",\n") + endif() + + # Extra plugins + get_target_property(android_extra_plugins + ${target} QT_ANDROID_EXTRA_PLUGINS) + if (android_extra_plugins) + list(JOIN android_extra_plugins "," android_extra_plugins) + string(APPEND file_contents + " \"android-extra-plugins\": \"${android_extra_plugins}\",\n") + endif() + + # Extra libs + get_target_property(android_extra_libs + ${target} QT_ANDROID_EXTRA_LIBS) + if (android_extra_libs) + list(JOIN android_extra_libs "," android_extra_libs) + string(APPEND file_contents + " \"android-extra-libs\": \"${android_extra_libs}\",\n") + endif() + + # package source dir + get_target_property(android_package_source_dir + ${target} QT_ANDROID_PACKAGE_SOURCE_DIR) + if (android_package_source_dir) + file(TO_NATIVE_PATH "${android_package_source_dir}" android_package_source_dir_native) + string(APPEND file_contents + " \"android-package-source-directory\": \"${android_package_source_dir_native}\",\n") +endif() + + #TODO: ANDROID_VERSION_NAME, doesn't seem to be used? + + #TODO: ANDROID_VERSION_CODE, doesn't seem to be used? + + get_target_property(qml_import_path ${target} QT_QML_IMPORT_PATH) + if (qml_import_path) + file(TO_NATIVE_PATH "${qml_import_path}" qml_import_path_native) + string(APPEND file_contents + " \"qml-import-path\": \"${qml_import_path_native}\",\n") + endif() + + get_target_property(qml_root_path ${target} QT_QML_ROOT_PATH) + if(NOT qml_root_path) + set(qml_root_path "${target_source_dir}") + endif() + file(TO_NATIVE_PATH "${qml_root_path}" qml_root_path_native) + string(APPEND file_contents + " \"qml-root-path\": \"${qml_root_path_native}\",\n") + + # App binary + string(APPEND file_contents + " \"application-binary\": \"${target_output_name}\",\n") + + # App command-line arguments + string(APPEND file_contents + " \"android-application-arguments\": \"${QT_ANDROID_APPLICATION_ARGUMENTS}\",\n") + + # Override qmlimportscanner binary path + set(qml_importscanner_binary_path "${QT_HOST_PATH}/bin/qmlimportscanner") + if (WIN32) + string(APPEND qml_importscanner_binary_path ".exe") + endif() + file(TO_NATIVE_PATH "${qml_importscanner_binary_path}" qml_importscanner_binary_path_native) + string(APPEND file_contents + " \"qml-importscanner-binary\" : \"${qml_importscanner_binary_path_native}\",\n") + + # Last item in json file + + # base location of stdlibc++, will be suffixed by androiddeploy qt + set(android_ndk_stdlib_base_path + "${ANDROID_NDK}/toolchains/llvm/prebuilt/linux-x86_64/sysroot/usr/lib/" + ) + string(APPEND file_contents + " \"stdcpp-path\": \"${android_ndk_stdlib_base_path}\"\n") + + # content end + string(APPEND file_contents "}\n") + + file(WRITE ${deploy_file} ${file_contents}) + + set_target_properties(${target} + PROPERTIES + QT_ANDROID_DEPLOYMENT_SETTINGS_FILE ${deploy_file} + ) +endfunction() + +function(qt_android_apply_arch_suffix target) + get_target_property(target_type ${target} TYPE) + if (target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY") + set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.so") + elseif (target_type STREQUAL "STATIC_LIBRARY") + set_property(TARGET "${target}" PROPERTY SUFFIX "_${CMAKE_ANDROID_ARCH_ABI}.a") + endif() +endfunction() + +# Add custom target to package the APK +function(qt_android_add_apk_target target) + get_target_property(deployment_file ${target} QT_ANDROID_DEPLOYMENT_SETTINGS_FILE) + if (NOT deployment_file) + message(FATAL_ERROR "Target ${target} is not a valid android executable target\n") + endif() + + set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt") + set(apk_dir "$<TARGET_PROPERTY:${target},BINARY_DIR>/android-build") + add_custom_target(${target}_prepare_apk_dir + DEPENDS ${target} + COMMAND ${CMAKE_COMMAND} + -E copy $<TARGET_FILE:${target}> + "${apk_dir}/libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>" + COMMENT "Copying ${target} binarty to apk folder" + ) + + add_custom_target(${target}_make_apk + DEPENDS ${target}_prepare_apk_dir + COMMAND ${deployment_tool} + --input ${deployment_file} + --output ${apk_dir} + COMMENT "Creating APK for ${target}" + ) +endfunction() + # Add a test for Android which will be run by the android test runner tool function(qt_android_add_test target) - set(deployment_tool "${QT_HOST_PATH}/bin/androiddeployqt") set(test_runner "${QT_HOST_PATH}/bin/androidtestrunner") diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf index 573fa1bdfe..23caae2f4d 100644 --- a/mkspecs/features/android/android_deployment_settings.prf +++ b/mkspecs/features/android/android_deployment_settings.prf @@ -70,6 +70,9 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded { } unset(qml_import_paths) + !isEmpty(ANDROID_APPLICATION_ARGUMENTS): \ + FILE_CONTENT += " \"android-application-arguments\": $$emitString($$ANDROID_APPLICATION_ARGUMENTS)," + isEmpty(QML_ROOT_PATH): \ QML_ROOT_PATH = $$_PRO_FILE_PWD_ FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH)," diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index 2631abe3aa..9335d27b13 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -937,6 +937,19 @@ Specifies the Android API level number. For more information, see \l{Android: Build Numbers}{Android Build Numbers}. + \target ANDROID_APPLICATION_ARGUMENTS + \section1 ANDROID_APPLICATION_ARGUMENTS + + \note This variable applies only to Android targets. + + Specifies extra command-line arguments to the Android app using the + \c AndroidManifest.xml with the tag "android.app.arguments". This takes + a string of arguments: + + \badcode + ANDROID_APPLICATION_ARGUMENTS = "arg1 arg2 arg3" + \endcode + \target ANDROID_BUNDLED_JAR_DEPENDENCIES \section1 ANDROID_BUNDLED_JAR_DEPENDENCIES diff --git a/src/android/templates/AndroidManifest.xml b/src/android/templates/AndroidManifest.xml index 092cf16545..62c6da5a32 100644 --- a/src/android/templates/AndroidManifest.xml +++ b/src/android/templates/AndroidManifest.xml @@ -17,7 +17,7 @@ </intent-filter> <!-- Application arguments --> - <!-- meta-data android:name="android.app.arguments" android:value="arg1 arg2 arg3"/ --> + <meta-data android:name="android.app.arguments" android:value="-- %%INSERT_APP_ARGUMENTS%% --"/> <!-- Application arguments --> <meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/> diff --git a/src/corelib/Qt5AndroidSupport.cmake b/src/corelib/Qt5AndroidSupport.cmake index 662dd87c1f..cb908a29c6 100644 --- a/src/corelib/Qt5AndroidSupport.cmake +++ b/src/corelib/Qt5AndroidSupport.cmake @@ -42,6 +42,7 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild) [=[{ "_description": "This file is created by CMake to be read by androiddeployqt and should not be modified by hand.", "application-binary": "@QT_ANDROID_APPLICATION_BINARY@", + "application-arguments": "@QT_ANDROID_APPLICATION_ARGUMENTS@", "architectures": { @QT_ANDROID_ARCHITECTURES@ }, @@ -99,6 +100,7 @@ if (NOT ${PROJECT_NAME}-MultiAbiBuild) generate_json_variable_list(ANDROID_DEPLOYMENT_DEPENDENCIES "deployment-dependencies") generate_json_variable_list(ANDROID_EXTRA_PLUGINS "android-extra-plugins") generate_json_variable(ANDROID_PACKAGE_SOURCE_DIR "android-package-source-directory") + generate_json_variable(ANDROID_APPLICATION_ARGUMENTS "android-application-arguments") generate_json_variable(ANDROID_VERSION_CODE "android-version-code") generate_json_variable(ANDROID_VERSION_NAME "android-version-name") generate_json_variable_list(ANDROID_EXTRA_LIBS "android-extra-libs") diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp index 9415554608..621d5554f0 100644 --- a/src/tools/androiddeployqt/main.cpp +++ b/src/tools/androiddeployqt/main.cpp @@ -167,6 +167,7 @@ struct Options QString outputDirectory; QString inputFileName; QString applicationBinary; + QString applicationArguments; QString rootPath; QStringList qmlImportPaths; QStringList qrcFiles; @@ -885,6 +886,14 @@ bool readInputFile(Options *options) } { + const QJsonValue applicationArguments = jsonObject.value(QLatin1String("android-application-arguments")); + if (!applicationArguments.isUndefined()) + options->applicationArguments = applicationArguments.toString(); + else + options->applicationArguments = QStringLiteral(""); + } + + { const QJsonValue androidVersionName = jsonObject.value(QLatin1String("android-version-name")); if (!androidVersionName.isUndefined()) options->versionName = androidVersionName.toString(); @@ -1430,6 +1439,7 @@ bool updateAndroidManifest(Options &options) QHash<QString, QString> replacements; replacements[QStringLiteral("-- %%INSERT_APP_NAME%% --")] = options.applicationBinary; + replacements[QStringLiteral("-- %%INSERT_APP_ARGUMENTS%% --")] = options.applicationArguments; replacements[QStringLiteral("-- %%INSERT_APP_LIB_NAME%% --")] = options.applicationBinary; replacements[QStringLiteral("-- %%INSERT_LOCAL_JARS%% --")] = options.localJars.join(QLatin1Char(':')); replacements[QStringLiteral("-- %%INSERT_INIT_CLASSES%% --")] = options.initClasses.join(QLatin1Char(':')); |