diff options
Diffstat (limited to 'src/corelib/Qt6AndroidMacros.cmake')
-rw-r--r-- | src/corelib/Qt6AndroidMacros.cmake | 410 |
1 files changed, 339 insertions, 71 deletions
diff --git a/src/corelib/Qt6AndroidMacros.cmake b/src/corelib/Qt6AndroidMacros.cmake index d454423a72..40620ee5b1 100644 --- a/src/corelib/Qt6AndroidMacros.cmake +++ b/src/corelib/Qt6AndroidMacros.cmake @@ -107,7 +107,7 @@ function(qt6_android_generate_deployment_settings target) set(config_suffix "$<$<NOT:$<CONFIG:${first_config_type}>>:-$<CONFIG>>") endif() set(deploy_file - "${target_binary_dir}/android-${target_output_name}-deployment-settings${config_suffix}.json") + "${target_binary_dir}/android-${target}-deployment-settings${config_suffix}.json") set(file_contents "{\n") # content begin @@ -197,7 +197,7 @@ function(qt6_android_generate_deployment_settings target) " \"architectures\": { ${architecture_records} },\n") # deployment dependencies - _qt_internal_add_android_deployment_multi_value_property(file_contents "dependencies" + _qt_internal_add_android_deployment_multi_value_property(file_contents "deployment-dependencies" ${target} "QT_ANDROID_DEPLOYMENT_DEPENDENCIES" ) # Extra plugins @@ -217,6 +217,10 @@ function(qt6_android_generate_deployment_settings target) ${target} "_qt_android_native_package_source_dir") # version code + _qt_internal_add_android_deployment_property(file_contents "android-package-name" + ${target} "QT_ANDROID_PACKAGE_NAME") + + # version code _qt_internal_add_android_deployment_property(file_contents "android-version-code" ${target} "QT_ANDROID_VERSION_CODE") @@ -236,6 +240,10 @@ function(qt6_android_generate_deployment_settings target) _qt_internal_add_android_deployment_property(file_contents "android-no-deploy-qt-libs" ${target} "QT_ANDROID_NO_DEPLOY_QT_LIBS") + __qt_internal_collect_plugin_targets_from_dependencies("${target}" plugin_targets) + __qt_internal_collect_plugin_library_files("${target}" "${plugin_targets}" plugin_targets) + string(APPEND file_contents " \"android-deploy-plugins\":\"${plugin_targets}\",\n") + # App binary string(APPEND file_contents " \"application-binary\": \"${target_output_name}\",\n") @@ -292,6 +300,13 @@ function(qt6_android_generate_deployment_settings target) string(APPEND file_contents " \"zstdCompression\": ${is_zstd_enabled},\n") + if(QT_ANDROID_GENERATE_JAVA_QML_COMPONENTS) + set(is_generate_java_qml_components "true") + else() + set(is_generate_java_qml_components "false") + endif() + string(APPEND file_contents + " \"generate-java-qml-components\": ${is_generate_java_qml_components},\n") # Last item in json file # base location of stdlibc++, will be suffixed by androiddeploy qt @@ -303,7 +318,7 @@ function(qt6_android_generate_deployment_settings target) # content end string(APPEND file_contents "}\n") - file(GENERATE OUTPUT ${deploy_file} CONTENT ${file_contents}) + file(GENERATE OUTPUT ${deploy_file} CONTENT "${file_contents}") set_target_properties(${target} PROPERTIES @@ -367,12 +382,19 @@ function(qt6_android_add_apk_target target) endif() # Use genex to get path to the deployment settings, the above check only to confirm that # qt6_android_add_apk_target is called on an android executable target. - set(deployment_file "$<TARGET_PROPERTY:${target},QT_ANDROID_DEPLOYMENT_SETTINGS_FILE>") + string(JOIN "" deployment_file + "$<GENEX_EVAL:" + "$<TARGET_PROPERTY:${target},QT_ANDROID_DEPLOYMENT_SETTINGS_FILE>" + ">" + ) # Make global apk and aab targets depend on the current apk target. if(TARGET aab) add_dependencies(aab ${target}_make_aab) endif() + if(TARGET aar) + add_dependencies(aar ${target}_make_aar) + endif() if(TARGET apk) add_dependencies(apk ${target}_make_apk) _qt_internal_create_global_apk_all_target_if_needed() @@ -381,16 +403,50 @@ function(qt6_android_add_apk_target target) set(deployment_tool "${QT_HOST_PATH}/${QT6_HOST_INFO_BINDIR}/androiddeployqt") # No need to use genex for the BINARY_DIR since it's read-only. get_target_property(target_binary_dir ${target} BINARY_DIR) - set(apk_final_dir "${target_binary_dir}/android-build") + + if("$CACHE{QT_USE_TARGET_ANDROID_BUILD_DIR}" AND + "$CACHE{QT_USE_TARGET_ANDROID_BUILD_DIR}" STREQUAL "${QT_USE_TARGET_ANDROID_BUILD_DIR}") + set(apk_final_dir "${target_binary_dir}/android-build-${target}") + else() + if(QT_USE_TARGET_ANDROID_BUILD_DIR) + message(WARNING "QT_USE_TARGET_ANDROID_BUILD_DIR needs to be set in CACHE") + endif() + + get_property(known_android_build GLOBAL PROPERTY _qt_internal_known_android_build_dir) + get_property(already_warned GLOBAL PROPERTY _qt_internal_already_warned_android_build_dir) + set(apk_final_dir "${target_binary_dir}/android-build") + if(NOT QT_SKIP_ANDROID_BUILD_DIR_CHECK AND "${apk_final_dir}" IN_LIST known_android_build + AND NOT "${apk_final_dir}" IN_LIST already_warned) + message(WARNING "${CMAKE_CURRENT_SOURCE_DIR}/CMakeLists.txt contains multiple" + " Qt Android executable targets. This can lead to mixing of deployment artifacts" + " of targets defined there. Setting QT_USE_TARGET_ANDROID_BUILD_DIR=TRUE" + " allows building multiple executable targets within a single CMakeLists.txt." + " Note: This option is not supported by Qt Creator versions older than 13." + " Set QT_SKIP_ANDROID_BUILD_DIR_CHECK=TRUE to suppress this warning." + ) + set_property(GLOBAL APPEND PROPERTY _qt_internal_already_warned_android_build_dir + "${apk_final_dir}") + else() + set_property(GLOBAL APPEND PROPERTY + _qt_internal_known_android_build_dir "${apk_final_dir}") + endif() + endif() + set(apk_file_name "${target}.apk") + set(aar_file_name "${target}.aar") set(dep_file_name "${target}.d") set(apk_final_file_path "${apk_final_dir}/${apk_file_name}") + set(aar_final_file_path "${apk_final_dir}/${aar_file_name}") set(dep_file_path "${apk_final_dir}/${dep_file_name}") set(target_file_copy_relative_path "libs/${CMAKE_ANDROID_ARCH_ABI}/$<TARGET_FILE_NAME:${target}>") set(extra_deps "") + if(QT_ENABLE_VERBOSE_DEPLOYMENT) + set(uses_terminal USES_TERMINAL) + endif() + # Plugins still might be added after creating the deployment targets. if(NOT TARGET qt_internal_plugins) add_custom_target(qt_internal_plugins) @@ -410,6 +466,7 @@ function(qt6_android_add_apk_target target) DEPENDS ${target} ${extra_deps} COMMAND ${copy_command} COMMENT "Copying ${target} binary to apk folder" + ${uses_terminal} ) set(sign_apk "") @@ -429,6 +486,26 @@ function(qt6_android_add_apk_target target) list(APPEND extra_args "--verbose") endif() + if(QT_ANDROID_DEPLOY_RELEASE) + message(WARNING "QT_ANDROID_DEPLOY_RELEASE is not a valid Qt variable." + " Please set QT_ANDROID_DEPLOYMENT_TYPE to RELEASE instead.") + endif() + # Setting QT_ANDROID_DEPLOYMENT_TYPE to a value other than Release disables + # release package signing regardless of the build type. + if(QT_ANDROID_DEPLOYMENT_TYPE) + string(TOUPPER "${QT_ANDROID_DEPLOYMENT_TYPE}" deployment_type_upper) + if("${deployment_type_upper}" STREQUAL "RELEASE") + list(APPEND extra_args "--release") + endif() + elseif(NOT QT_BUILD_TESTS) + # Workaround for tests: do not set automatically --release flag if QT_BUILD_TESTS is set. + # Release package need to be signed. Signing is currently not supported by CI. + # What is more, also androidtestrunner is not working on release APKs, + # For example running "adb shell run-as" on release APK will finish with the error: + # run-as: Package '[PACKAGE-NAME]' is not debuggable + list(APPEND extra_args $<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:--release>) + endif() + _qt_internal_check_depfile_support(has_depfile_support) if(has_depfile_support) @@ -461,11 +538,35 @@ function(qt6_android_add_apk_target target) DEPENDS "${target}" "${deployment_file}" ${extra_deps} DEPFILE "${dep_file_path}" VERBATIM + ${uses_terminal} + ) + + # Add custom command that creates the aar and triggers rebuild if files listed in + # ${dep_file_path} are changed. + add_custom_command(OUTPUT "${aar_final_file_path}" + COMMAND ${CMAKE_COMMAND} + -E copy "$<TARGET_FILE:${target}>" + "${apk_final_dir}/${target_file_copy_relative_path}" + COMMAND "${deployment_tool}" + --input "${deployment_file}" + --output "${apk_final_dir}" + --apk "${aar_final_file_path}" + --depfile "${dep_file_path}" + --builddir "${relative_to_dir}" + --build-aar + ${extra_args} + COMMENT "Creating AAR for ${target}" + DEPENDS "${target}" "${deployment_file}" ${extra_deps} + DEPFILE "${dep_file_path}" + VERBATIM + ${uses_terminal} ) cmake_policy(POP) # Create a ${target}_make_apk target to trigger the apk build. add_custom_target(${target}_make_apk DEPENDS "${apk_final_file_path}") + # Create a ${target}_make_aar target to trigger the aar build. + add_custom_target(${target}_make_aar DEPENDS "${aar_final_file_path}") else() add_custom_target(${target}_make_apk DEPENDS ${target}_prepare_apk_dir @@ -477,6 +578,20 @@ function(qt6_android_add_apk_target target) ${sign_apk} COMMENT "Creating APK for ${target}" VERBATIM + ${uses_terminal} + ) + + add_custom_target(${target}_make_aar + DEPENDS ${target}_prepare_apk_dir + COMMAND ${deployment_tool} + --input ${deployment_file} + --output ${apk_final_dir} + --apk ${aar_final_file_path} + --build-aar + ${extra_args} + COMMENT "Creating AAR for ${target}" + VERBATIM + ${uses_terminal} ) endif() @@ -493,6 +608,7 @@ function(qt6_android_add_apk_target target) ${sign_aab} ${extra_args} COMMENT "Creating AAB for ${target}" + ${uses_terminal} ) if(QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT) @@ -532,6 +648,7 @@ function(qt6_android_add_apk_target target) COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK" DEPFILE "${dep_file}" VERBATIM + ${uses_terminal} ) add_custom_target(qt_internal_${target}_copy_apk_dependencies DEPENDS "${timestamp_file}") @@ -545,6 +662,7 @@ function(qt6_android_add_apk_target target) --copy-dependencies-only ${extra_args} COMMENT "Resolving ${CMAKE_ANDROID_ARCH_ABI} dependencies for the ${target} APK" + ${uses_terminal} ) endif() endif() @@ -573,6 +691,11 @@ function(_qt_internal_create_global_android_targets) # It will trigger building all the apk build targets that are added as part of the project. # Allow opting out. _qt_internal_create_global_android_targets_impl(aab) + + # Create a top-level "aar" target for convenience, so that users can call 'ninja aar'. + # It will trigger building all the aar build targets that are added as part of the project. + # Allow opting out. + _qt_internal_create_global_android_targets_impl(aar) endfunction() # The function collects all known non-imported shared libraries that are created in the build tree. @@ -626,7 +749,8 @@ function(_qt_internal_collect_apk_dependencies) get_property(apk_targets GLOBAL PROPERTY _qt_apk_targets) - _qt_internal_collect_buildsystem_shared_libraries(libs "${CMAKE_SOURCE_DIR}") + _qt_internal_collect_buildsystem_targets(libs + "${CMAKE_SOURCE_DIR}" INCLUDE SHARED_LIBRARY MODULE_LIBRARY) list(REMOVE_DUPLICATES libs) if(NOT TARGET qt_internal_plugins) @@ -655,28 +779,6 @@ function(_qt_internal_collect_apk_dependencies) ) endfunction() -# This function recursively walks the current directory and its subdirectories to collect shared -# library targets built in those directories. -function(_qt_internal_collect_buildsystem_shared_libraries out_var subdir) - set(result "") - get_directory_property(buildsystem_targets DIRECTORY ${subdir} BUILDSYSTEM_TARGETS) - foreach(buildsystem_target IN LISTS buildsystem_targets) - if(buildsystem_target AND TARGET ${buildsystem_target}) - get_target_property(target_type ${buildsystem_target} TYPE) - if(target_type STREQUAL "SHARED_LIBRARY" OR target_type STREQUAL "MODULE_LIBRARY") - list(APPEND result ${buildsystem_target}) - endif() - endif() - endforeach() - - get_directory_property(subdirs DIRECTORY "${subdir}" SUBDIRECTORIES) - foreach(dir IN LISTS subdirs) - _qt_internal_collect_buildsystem_shared_libraries(result_inner "${dir}") - endforeach() - list(APPEND result ${result_inner}) - set(${out_var} "${result}" PARENT_SCOPE) -endfunction() - # This function collects all imported shared libraries that might be dependencies for # the main apk targets. The actual collection is deferred until the target's directory scope # is processed. @@ -837,6 +939,9 @@ function(_qt_internal_add_android_deployment_list_property out_var json_key) set(add_quote_genex "$<$<BOOL:${property_genex}>:\">" ) + + # Add comma only if next property genex contains non-empty value. + set(add_comma_genex "$<$<BOOL:${property_genex}>:${add_comma_genex}>") string(JOIN "" list_join_genex "${list_join_genex}" "${add_comma_genex}${add_quote_genex}" @@ -881,15 +986,55 @@ endfunction() # It doesn't overwrite public properties, but instead writes formatted values to internal # properties. function(_qt_internal_android_format_deployment_paths target) - if(QT_BUILD_STANDALONE_TESTS OR QT_BUILDING_QT) + if(QT_BUILD_STANDALONE_TESTS OR QT_BUILDING_QT OR QT_INTERNAL_IS_STANDALONE_TEST) + set(android_deployment_paths_policy NEW) + else() + set(policy_path_properties + QT_QML_IMPORT_PATH + QT_QML_ROOT_PATH + QT_ANDROID_PACKAGE_SOURCE_DIR + QT_ANDROID_EXTRA_PLUGINS + QT_ANDROID_EXTRA_LIBS + ) + + # Check if any of paths contains the value and stop the evaluation if all properties are + # empty or -NOTFOUND + set(has_android_paths FALSE) + foreach(prop_name IN LISTS policy_path_properties) + get_target_property(prop_value ${target} ${prop_name}) + if(prop_value) + set(has_android_paths TRUE) + break() + endif() + endforeach() + if(has_android_paths) + __qt_internal_setup_policy(QTP0002 "6.6.0" + "Target properties that specify android-specific paths may contain generator\ + expressions but they must evaluate to valid JSON strings.\ + Check https://doc.qt.io/qt-6/qt-cmake-policy-qtp0002.html for policy details." + ) + qt6_policy(GET QTP0002 android_deployment_paths_policy) + endif() + endif() + if(android_deployment_paths_policy STREQUAL "NEW") # When building standalone tests or Qt itself we obligate developers to not use # windows paths when setting QT_* properties below, so their values are used as is when # generating deployment settings. + string(JOIN "" qml_root_path_genex + "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},QT_QML_ROOT_PATH>>" + "$<" + "$<AND:" + "$<BOOL:$<GENEX_EVAL:$<TARGET_PROPERTY:${target},QT_QML_ROOT_PATH>>>," + "$<BOOL:$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_internal_qml_root_path>>>" + ">:;" + ">" + "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},_qt_internal_qml_root_path>>" + ) set_target_properties(${target} PROPERTIES _qt_native_qml_import_paths "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},QT_QML_IMPORT_PATH>>" _qt_android_native_qml_root_paths - "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},QT_QML_ROOT_PATH>>" + "${qml_root_path_genex}" _qt_android_native_package_source_dir "$<GENEX_EVAL:$<TARGET_PROPERTY:${target},QT_ANDROID_PACKAGE_SOURCE_DIR>>" _qt_android_native_extra_plugins @@ -907,6 +1052,9 @@ function(_qt_internal_android_format_deployment_paths target) QT_QML_ROOT_PATH _qt_android_native_qml_root_paths) _qt_internal_android_format_deployment_path_property(${target} + _qt_internal_qml_root_path _qt_android_native_qml_root_paths APPEND) + + _qt_internal_android_format_deployment_path_property(${target} QT_ANDROID_PACKAGE_SOURCE_DIR _qt_android_native_package_source_dir) _qt_internal_android_format_deployment_path_property(${target} @@ -920,7 +1068,20 @@ endfunction() # The function converts the value of target property to JSON compatible path and writes the # result to out_property. Property might be either single value, semicolon separated list or system # path spec. +# The APPEND argument controls the property is set. The argument should be added after all +# the required arguments. function(_qt_internal_android_format_deployment_path_property target property out_property) + set(should_append "") + if(ARGC EQUAL 4) + if("${ARGV3}" STREQUAL "APPEND") + set(should_append APPEND) + else() + message(FATAL_ERROR "Unexpected argument ${ARGV3}") + endif() + elseif(ARGC GREATER 4) + message(FATAL_ERROR "Unexpected arguments ${ARGN}") + endif() + get_target_property(_paths ${target} ${property}) if(_paths) set(native_paths "") @@ -928,7 +1089,7 @@ function(_qt_internal_android_format_deployment_path_property target property ou file(TO_CMAKE_PATH "${_path}" _path) list(APPEND native_paths "${_path}") endforeach() - set_target_properties(${target} PROPERTIES + set_property(TARGET ${target} ${should_append} PROPERTY ${out_property} "${native_paths}") endif() endfunction() @@ -981,10 +1142,11 @@ function(_qt_internal_get_android_abi_cmake_dir_path out_path abi) else() _qt_internal_get_android_abi_prefix_path(prefix_path ${abi}) if((PROJECT_NAME STREQUAL "QtBase" OR QT_SUPERBUILD) AND QT_BUILDING_QT AND - NOT QT_BUILD_STANDALONE_TESTS) + NOT QT_BUILD_STANDALONE_TESTS AND NOT QT_INTERNAL_IS_STANDALONE_TEST) set(cmake_dir "${QT_CONFIG_BUILD_DIR}") else() - set(cmake_dir "${prefix_path}/${QT6_INSTALL_LIBS}/cmake") + string(TOUPPER "${QT_CMAKE_EXPORT_NAMESPACE}" export_namespace_upper) + set(cmake_dir "${prefix_path}/${${export_namespace_upper}_INSTALL_LIBS}/cmake") endif() endif() @@ -1000,7 +1162,7 @@ function(_qt_internal_get_android_abi_toolchain_path out_path abi) endfunction() function(_qt_internal_get_android_abi_subdir_path out_path subdir abi) - set(install_paths_path "${QT_CMAKE_EXPORT_NAMESPACE}Core/QtInstallPaths.cmake") + set(install_paths_path "${QT_CMAKE_EXPORT_NAMESPACE}/QtInstallPaths.cmake") _qt_internal_get_android_abi_cmake_dir_path(cmake_dir ${abi}) include("${cmake_dir}/${install_paths_path}") set(${out_path} "${${subdir}}" PARENT_SCOPE) @@ -1080,6 +1242,91 @@ function(_qt_internal_collect_default_android_abis) ) endfunction() +# Returns a path to the timestamp file for the specific step of the multi-ABI Android project +function(_qt_internal_get_android_abi_step_stampfile out project abi step) + get_target_property(build_dir ${project} _qt_android_build_directory) + get_property(is_multi GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(is_multi) + set(${out} "${build_dir}/$<CONFIG>/${project}_${step}_stamp" PARENT_SCOPE) + else() + set(${out} "${build_dir}/${project}_${step}_stamp" PARENT_SCOPE) + endif() +endfunction() + +# Creates the multi-ABI Android projects and assigns the JOB_POOL to them if it's possible +function(_qt_internal_add_android_abi_project project abi) + add_custom_target(${project}) + + set(build_dir "${CMAKE_BINARY_DIR}/android_abi_builds/${abi}") + set_target_properties(${project} PROPERTIES + _qt_android_build_directory "${build_dir}" + ) + + file(MAKE_DIRECTORY "${build_dir}") + if(CMAKE_GENERATOR MATCHES "^Ninja") + set_property(GLOBAL APPEND PROPERTY JOB_POOLS _qt_android_${project}_pool=1) + endif() +endfunction() + +# Adds the custom build step to the multi-ABI Android project +function(_qt_internal_add_android_abi_step project abi step) + cmake_parse_arguments(arg "" "" "COMMAND;DEPENDS" ${ARGV}) + + if(NOT arg_COMMAND) + message(FATAL_ERROR "COMMAND is not set for ${project} step ${step} Android ABI ${abi}.") + endif() + + set(dep_stamps "") + foreach(dep ${arg_DEPENDS}) + _qt_internal_get_android_abi_step_stampfile(stamp ${project} ${abi} ${dep}) + list(APPEND dep_stamps "${stamp}") + endforeach() + + get_target_property(build_dir ${project} _qt_android_build_directory) + + if(CMAKE_GENERATOR MATCHES "^Ninja") + set(add_to_pool JOB_POOL _qt_android_${project}_pool) + else() + set(add_to_pool "") + endif() + + _qt_internal_get_android_abi_step_stampfile(stamp ${project} ${abi} ${step}) + add_custom_command(OUTPUT "${stamp}" + COMMAND ${arg_COMMAND} + COMMAND "${CMAKE_COMMAND}" -E touch "${stamp}" + ${add_to_pool} + DEPENDS + ${dep_stamps} + WORKING_DIRECTORY + "${build_dir}" + VERBATIM + ) + add_custom_target("${project}_${step}" DEPENDS "${stamp}") + + get_target_property(known_steps ${project} _qt_android_abi_steps) + if(NOT CMAKE_GENERATOR MATCHES "^Ninja") + if(NOT QT_NO_WARN_ANDROID_MULTI_ABI_GENERATOR) + get_property(is_warned GLOBAL PROPERTY _qt_internal_warn_android_multi_abi_generator) + if(NOT is_warned) + set_property(GLOBAL PROPERTY _qt_internal_warn_android_multi_abi_generator TRUE) + message(WARNING "Building Multi-ABI Qt projects with the '${CMAKE_GENERATOR}'" + " generator has limitations. All targets from non-main ABI will be built" + " unconditionally. Please use the 'Ninja' or 'Ninja Multi-config' generators" + " with ninja build instead. Set QT_NO_WARN_ANDROID_MULTI_ABI_GENERATOR to" + " 'TRUE' to suppress this warning." + ) + endif() + endif() + if(known_steps) + list(GET known_steps 0 first) + add_dependencies(${first} ${project}_${step}) + endif() + endif() + + list(PREPEND known_steps ${project}_${step}) + set_target_properties(${project} PROPERTIES _qt_android_abi_steps "${known_steps}") +endfunction() + # The function configures external projects for ABIs that target packages need to build with. # Each target adds build step to the external project that is linked to the # qt_internal_android_${abi}-${target}_build target in the primary ABI build tree. @@ -1189,7 +1436,6 @@ function(_qt_internal_configure_android_multiabi_target target) set(previous_copy_apk_dependencies_target ${target}) # Create external projects for each android ABI except the main one. list(REMOVE_ITEM android_abis "${CMAKE_ANDROID_ARCH_ABI}") - include(ExternalProject) foreach(abi IN ITEMS ${android_abis}) if(NOT "${abi}" IN_LIST QT_DEFAULT_ANDROID_ABIS) list(APPEND missing_qt_abi_toolchains ${abi}) @@ -1197,16 +1443,17 @@ function(_qt_internal_configure_android_multiabi_target target) continue() endif() - set(android_abi_build_dir "${CMAKE_BINARY_DIR}/android_abi_builds/${abi}") get_property(abi_external_projects GLOBAL PROPERTY _qt_internal_abi_external_projects) if(NOT abi_external_projects OR NOT "qt_internal_android_${abi}" IN_LIST abi_external_projects) + _qt_internal_add_android_abi_project(qt_internal_android_${abi} ${abi}) + + get_target_property(android_abi_build_dir qt_internal_android_${abi} + _qt_android_build_directory) _qt_internal_get_android_abi_toolchain_path(qt_abi_toolchain_path ${abi}) - ExternalProject_Add("qt_internal_android_${abi}" - SOURCE_DIR "${CMAKE_SOURCE_DIR}" - BINARY_DIR "${android_abi_build_dir}" - CONFIGURE_COMMAND + _qt_internal_add_android_abi_step(qt_internal_android_${abi} ${abi} configure + COMMAND "${CMAKE_COMMAND}" "-G${CMAKE_GENERATOR}" "-DCMAKE_TOOLCHAIN_FILE=${qt_abi_toolchain_path}" @@ -1218,44 +1465,36 @@ function(_qt_internal_configure_android_multiabi_target target) "${user_cmake_args}" "-B" "${android_abi_build_dir}" "-S" "${CMAKE_SOURCE_DIR}" - EXCLUDE_FROM_ALL TRUE - BUILD_COMMAND "" # avoid top-level build of external project ) set_property(GLOBAL APPEND PROPERTY _qt_internal_abi_external_projects "qt_internal_android_${abi}") endif() - ExternalProject_Add_Step("qt_internal_android_${abi}" - "${target}_build" - DEPENDEES configure - # TODO: Remove this when the step will depend on DEPFILE generated by - # androiddeployqt for the ${target}. - ALWAYS TRUE - EXCLUDE_FROM_MAIN TRUE - COMMAND "${CMAKE_COMMAND}" - "--build" "${android_abi_build_dir}" - "--config" "$<CONFIG>" - "--target" "${target}" + + get_target_property(android_abi_build_dir qt_internal_android_${abi} + _qt_android_build_directory) + _qt_internal_add_android_abi_step(qt_internal_android_${abi} ${abi} ${target}_build + DEPENDS + configure + COMMAND + "${CMAKE_COMMAND}" + --build "${android_abi_build_dir}" + --config $<CONFIG> + --target ${target} ) - ExternalProject_Add_StepTargets("qt_internal_android_${abi}" - "${target}_build") - add_dependencies(${target} "qt_internal_android_${abi}-${target}_build") - - ExternalProject_Add_Step("qt_internal_android_${abi}" - "${target}_copy_apk_dependencies" - DEPENDEES "${target}_build" - # TODO: Remove this when the step will depend on DEPFILE generated by - # androiddeployqt for the ${target}. - ALWAYS TRUE - EXCLUDE_FROM_MAIN TRUE - COMMAND "${CMAKE_COMMAND}" - "--build" "${android_abi_build_dir}" - "--config" "$<CONFIG>" - "--target" "qt_internal_${target}_copy_apk_dependencies" + add_dependencies(${target} "qt_internal_android_${abi}_${target}_build") + + _qt_internal_add_android_abi_step(qt_internal_android_${abi} ${abi} + ${target}_copy_apk_dependencies + DEPENDS + ${target}_build + COMMAND + "${CMAKE_COMMAND}" + --build "${android_abi_build_dir}" + --config $<CONFIG> + --target qt_internal_${target}_copy_apk_dependencies ) - ExternalProject_Add_StepTargets("qt_internal_android_${abi}" - "${target}_copy_apk_dependencies") set(external_project_copy_target - "qt_internal_android_${abi}-${target}_copy_apk_dependencies") + "qt_internal_android_${abi}_${target}_copy_apk_dependencies") # Need to build dependency chain between the # qt_internal_android_${abi}-${target}_copy_apk_dependencies targets for all ABI's, to @@ -1297,7 +1536,36 @@ endfunction() function(_qt_internal_android_executable_finalizer target) set_property(TARGET ${target} PROPERTY _qt_android_executable_finalizer_called TRUE) + _qt_internal_expose_android_package_source_dir_to_ide(${target}) + _qt_internal_configure_android_multiabi_target("${target}") qt6_android_generate_deployment_settings("${target}") qt6_android_add_apk_target("${target}") endfunction() + +function(_qt_internal_expose_android_package_source_dir_to_ide target) + get_target_property(android_package_source_dir ${target} QT_ANDROID_PACKAGE_SOURCE_DIR) + if(android_package_source_dir) + get_target_property(target_source_dir ${target} SOURCE_DIR) + if(NOT IS_ABSOLUTE "${android_package_source_dir}") + string(JOIN "/" android_package_source_dir + "${target_source_dir}" + "${android_package_source_dir}" + ) + endif() + + if(EXISTS "${android_package_source_dir}") + file(GLOB_RECURSE android_package_sources + RELATIVE "${target_source_dir}" + "${android_package_source_dir}/*" + ) + endif() + + foreach(f IN LISTS android_package_sources) + _qt_internal_expose_source_file_to_ide(${target} "${f}") + endforeach() + endif() +endfunction() + +set(QT_INTERNAL_ANDROID_TARGET_BUILD_DIR_SUPPORT ON CACHE INTERNAL + "Indicates that Qt supports per-target Android build directories") |