Fix concurrent access to files by androiddeployqt in multi-abi builds

'androiddeployqt' supposed to copy artifacts that may not have
abi-specific identifies. One example is Qt6Android.jar file. We need
to prevent execution of multiple androiddeployqt instances in
parallel. External projects now are divided into two steps. The
first runs the build and can be executed in parallel to the build
steps from the other external projects. The second one triggers
androiddeployqt and can only be run exclusively in relation
to the similar steps from other ABI-specific external projects.

To solve the issue we build the dependency chain between the all
ABI-pecific qt_internal_${target}_copy_apk_dependencies targets to
execute androiddeployqt sequentially. This is non-optimal, but
guarantees that androiddeployqt is not running simultaneously with
another instance in external projects.

Pick-to: 6.3 6.4
Fixes: QTBUG-104013
Change-Id: I39a25dd5f38ed988e0ca74b185024bc602ab81a1
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
This commit is contained in:
Alexey Edelev 2022-06-14 17:24:52 +02:00
parent ac171469a0
commit 84e22f9e82

View File

@ -961,6 +961,7 @@ function(_qt_internal_configure_android_multiabi_target target)
endif()
set(missing_qt_abi_toolchains "")
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)
@ -1005,11 +1006,38 @@ function(_qt_internal_configure_android_multiabi_target target)
COMMAND "${CMAKE_COMMAND}"
"--build" "${android_abi_build_dir}"
"--config" "$<CONFIG>"
"--target" "qt_internal_${target}_copy_apk_dependencies"
"--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"
)
ExternalProject_Add_StepTargets("qt_internal_android_${abi}"
"${target}_copy_apk_dependencies")
set(external_project_copy_target
"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
# prevent parallel execution of androiddeployqt processes. We cannot use Ninja job pools
# here because it's not possible to define job pool for the step target in ExternalProject.
# All tricks with interlayer targets don't work, because we only can bind interlayer target
# to the job pool, but its dependencies can still be built in parallel.
add_dependencies(${previous_copy_apk_dependencies_target}
"${external_project_copy_target}")
set(previous_copy_apk_dependencies_target "${external_project_copy_target}")
endforeach()
if(missing_qt_abi_toolchains)