From d6367aca869ee30e15a3861b2990baafb9972aa1 Mon Sep 17 00:00:00 2001 From: Assam Boudjelthia Date: Wed, 10 Feb 2021 00:07:58 +0200 Subject: [PATCH] CMake: make sure to collect Android dependencies for plugins androiddeployqt relies on *-android-dependencies.xml files to know what dependencies like jar files and permissions a Qt module requires. CMake create those files under Qt prefix's lib dir but CMake was not accounting for module plugins. Fixes: QTBUG-90812 Pick-to: 6.1 6.0 Change-Id: Ib3b2e2bb237159b4851ac0f23dc75f8e56af3f7a Reviewed-by: Alexandru Croitor --- cmake/QtAndroidHelpers.cmake | 105 +++++++++++++++++++------------ cmake/QtModuleHelpers.cmake | 2 +- cmake/QtPostProcessHelpers.cmake | 2 +- 3 files changed, 67 insertions(+), 42 deletions(-) diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake index 49fb0627ef..24233ac622 100644 --- a/cmake/QtAndroidHelpers.cmake +++ b/cmake/QtAndroidHelpers.cmake @@ -8,7 +8,7 @@ define_property(TARGET BRIEF_DOCS "Recorded install location for a Qt Module." FULL_DOCS - "Recorded install location for a Qt Module. Used by qt_android_dependencies()." + "Recorded install location for a Qt Module. Used by qt_internal_android_dependencies()." ) @@ -75,15 +75,7 @@ define_property(TARGET "Qt Module android feature list." ) -# Generate Qt Module -android-dependencies.xml required by the -# androiddeploytoolqt to successfully copy all the plugins and other dependent -# items into tha APK -function(qt_android_dependencies target) - get_target_property(target_type "${target}" TYPE) - if(target_type STREQUAL "INTERFACE_LIBRARY") - return() - endif() - +function(qt_internal_android_dependencies_content target file_content_out) get_target_property(arg_JAR_DEPENDENCIES ${target} QT_ANDROID_JAR_DEPENDENCIES) get_target_property(arg_BUNDLED_JAR_DEPENDENCIES ${target} QT_ANDROID_BUNDLED_JAR_DEPENDENCIES) get_target_property(arg_LIB_DEPENDENCIES ${target} QT_ANDROID_LIB_DEPENDENCIES) @@ -91,28 +83,18 @@ function(qt_android_dependencies target) get_target_property(arg_BUNDLED_FILES ${target} QT_ANDROID_BUNDLED_FILES) get_target_property(arg_PERMISSIONS ${target} QT_ANDROID_PERMISSIONS) get_target_property(arg_FEATURES ${target} QT_ANDROID_FEATURES) - get_target_property(module_plugins ${target} MODULE_PLUGIN_TYPES) - if ((NOT module_plugins) - AND (NOT arg_JAR_DEPENDENCIES) - AND (NOT arg_LIB_DEPENDENCY_REPLACEMENTS) - AND (NOT arg_LIB_DEPENDENCIES) + if ((NOT arg_JAR_DEPENDENCIES) AND (NOT arg_BUNDLED_JAR_DEPENDENCIES) + AND (NOT arg_LIB_DEPENDENCIES) + AND (NOT arg_LIB_DEPENDENCY_REPLACEMENTS) + AND (NOT arg_BUNDLED_FILES) AND (NOT arg_PERMISSIONS) - AND (NOT arg_FEATURES) - AND (NOT arg_BUNDLED_FILES)) + AND (NOT arg_FEATURES)) # None of the values were set, so there's nothing to do return() endif() - - get_target_property(target_output_name ${target} OUTPUT_NAME) - if (NOT target_output_name) - set(target_name ${target}) - else() - set(target_name ${target_output_name}) - endif() - # mimic qmake's section and string splitting from # mkspecs/feature/qt_android_deps.prf macro(section string delimiter first second) @@ -127,10 +109,7 @@ function(qt_android_dependencies target) endif() endmacro() - set(dependency_file "${QT_BUILD_DIR}/${INSTALL_LIBDIR}/${target_name}_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml") - - set(file_contents "\n") - string(APPEND file_contents "\n") + set(file_contents "") # Jar Dependencies if(arg_JAR_DEPENDENCIES) @@ -183,7 +162,6 @@ function(qt_android_dependencies target) endforeach() endif() - # Bundled files if(arg_BUNDLED_FILES) foreach(bundled_file IN LISTS arg_BUNDLED_FILES) @@ -192,13 +170,6 @@ function(qt_android_dependencies target) endforeach() endif() - # Module plugins - if(module_plugins) - foreach(plugin IN LISTS module_plugins) - string(APPEND file_contents "\n") - endforeach() - endif() - # Android Permissions if(arg_PERMISSIONS) foreach(permission IN LISTS arg_PERMISSIONS) @@ -213,13 +184,67 @@ function(qt_android_dependencies target) endforeach() endif() - string(APPEND file_contents "") - string(APPEND file_contents "\n") + set(${file_content_out} ${file_contents} PARENT_SCOPE) +endfunction() + +# Generate Qt Module -android-dependencies.xml required by the +# androiddeploytoolqt to successfully copy all the plugins and other dependent +# items into the APK +function(qt_internal_android_dependencies target) + get_target_property(target_type "${target}" TYPE) + if(target_type STREQUAL "INTERFACE_LIBRARY") + return() + endif() + + # Get plugins for the current module + get_target_property(module_plugin_types ${target} MODULE_PLUGIN_TYPES) + + # Get depends for the current module + qt_internal_android_dependencies_content(${target} file_contents) + + # Get plugins from the module's plugin types and get their dependencies + foreach(plugin ${QT_KNOWN_PLUGINS}) + get_target_property(iter_known_plugin_type ${plugin} QT_PLUGIN_TYPE) + foreach(plugin_type ${module_plugin_types}) + if (plugin_type STREQUAL iter_known_plugin_type) + qt_internal_android_dependencies_content(${plugin} plugin_file_contents) + string(APPEND file_contents ${plugin_file_contents}) + endif() + endforeach() + endforeach() + + if ((NOT module_plugin_types) + AND (NOT file_contents)) + # None of the values were set, so there's nothing to do + return() + endif() + + get_target_property(target_output_name ${target} OUTPUT_NAME) + if (NOT target_output_name) + set(target_name ${target}) + else() + set(target_name ${target_output_name}) + endif() + + string(PREPEND file_contents "\n") + string(PREPEND file_contents "\n") + + # Module plugins + if(module_plugin_types) + foreach(plugin IN LISTS module_plugin_types) + string(APPEND file_contents "\n") + endforeach() + endif() + + string(APPEND file_contents "\n") + string(APPEND file_contents "") + + qt_path_join(dependency_file "${QT_BUILD_DIR}" "${INSTALL_LIBDIR}" "${target_name}_${CMAKE_ANDROID_ARCH_ABI}-android-dependencies.xml") file(WRITE ${dependency_file} ${file_contents}) get_target_property(target_install_dir ${target} QT_ANDROID_MODULE_INSTALL_DIR) if (NOT target_install_dir) - message(SEND_ERROR "qt_android_dependencies: Target ${target} is either not a Qt Module or has no recorded install location") + message(SEND_ERROR "qt_internal_android_dependencies: Target ${target} is either not a Qt Module or has no recorded install location") return() endif() diff --git a/cmake/QtModuleHelpers.cmake b/cmake/QtModuleHelpers.cmake index 597895b7b6..6268bfe960 100644 --- a/cmake/QtModuleHelpers.cmake +++ b/cmake/QtModuleHelpers.cmake @@ -567,7 +567,7 @@ set(QT_CMAKE_EXPORT_NAMESPACE ${QT_CMAKE_EXPORT_NAMESPACE})") if (ANDROID AND NOT arg_HEADER_MODULE) # Record install library location so it can be accessed by - # qt_android_dependencies without having to specify it again. + # qt_internal_android_dependencies without having to specify it again. set_target_properties(${target} PROPERTIES QT_ANDROID_MODULE_INSTALL_DIR ${INSTALL_LIBDIR}) endif() diff --git a/cmake/QtPostProcessHelpers.cmake b/cmake/QtPostProcessHelpers.cmake index 89b112c2b0..2e8de1e15d 100644 --- a/cmake/QtPostProcessHelpers.cmake +++ b/cmake/QtPostProcessHelpers.cmake @@ -633,7 +633,7 @@ endfunction() function(qt_modules_process_android_dependencies) qt_internal_get_qt_repo_known_modules(repo_known_modules) foreach (target ${repo_known_modules}) - qt_android_dependencies(${target}) + qt_internal_android_dependencies(${target}) endforeach() endfunction()