summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Edelev <alexey.edelev@qt.io>2021-12-17 13:02:04 +0100
committerAlexey Edelev <alexey.edelev@qt.io>2022-01-03 14:35:13 +0100
commitf90221d8cd2fdc8d4bf2105f0821ee30395443c7 (patch)
treecd1de31e6e6e55090533db097ed6eb23a81e4229
parent612417ea701b5276abd392af383fff3133b95a47 (diff)
Replace ANDROID_ABI argument with the QT_ANDROID_ABI target property
This change tries to make the API more user friendly and prevent wrong use of multi-abi API. ANDROID_ABI argument of qt6_add_executable was position-depend and needed to be placed after the executable 'sources'. Using the target property we solve this problem and provide more consistent and common way to enable multi-abi build for the single target. This meanwhile also requires to execute multi-abi build configuration in the finalizer, since the property might be set at any point. Also the priority of the QT_ANDROID_ABI target property now is higher than the priority of the QT_ANDROID_BUILD_ALL_ABIS variable. So target will only build packages with the ABIs specified in QT_ANDROID_ABI property if both are set. Pick-to: 6.3 Task-number: QTBUG-88841 Change-Id: I3515297ed267974498913c59619433dc234ec217 Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io>
-rw-r--r--cmake/QtAndroidHelpers.cmake9
-rw-r--r--cmake/QtExecutableHelpers.cmake1
-rw-r--r--src/corelib/Qt6AndroidMacros.cmake108
-rw-r--r--src/corelib/Qt6CoreMacros.cmake108
4 files changed, 122 insertions, 104 deletions
diff --git a/cmake/QtAndroidHelpers.cmake b/cmake/QtAndroidHelpers.cmake
index 24233ac622..49c384f698 100644
--- a/cmake/QtAndroidHelpers.cmake
+++ b/cmake/QtAndroidHelpers.cmake
@@ -75,6 +75,15 @@ define_property(TARGET
"Qt Module android feature list."
)
+define_property(TARGET
+ PROPERTY
+ QT_ANDROID_ABIS
+ BRIEF_DOCS
+ "List of ABIs that the target packages are built with."
+ FULL_DOCS
+ "List of ABIs that the target packages are built with."
+)
+
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)
diff --git a/cmake/QtExecutableHelpers.cmake b/cmake/QtExecutableHelpers.cmake
index 3d0933942a..a7f7678e9e 100644
--- a/cmake/QtExecutableHelpers.cmake
+++ b/cmake/QtExecutableHelpers.cmake
@@ -21,6 +21,7 @@ function(qt_internal_add_executable name)
_qt_internal_create_executable(${name})
if (ANDROID)
+ _qt_internal_configure_android_multiabi_target("${name}")
qt_android_generate_deployment_settings("${name}")
qt_android_add_apk_target("${name}")
endif()
diff --git a/src/corelib/Qt6AndroidMacros.cmake b/src/corelib/Qt6AndroidMacros.cmake
index 3db5ce2132..d61f0e070d 100644
--- a/src/corelib/Qt6AndroidMacros.cmake
+++ b/src/corelib/Qt6AndroidMacros.cmake
@@ -795,3 +795,111 @@ function(_qt_internal_collect_default_android_abis)
"Build project using the list of autodetected Qt for Android ABIs"
)
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.
+function(_qt_internal_configure_android_multiabi_target target)
+ # Functionality is only applicable for the primary ABI
+ if(QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT)
+ return()
+ endif()
+
+ get_target_property(target_abis ${target} QT_ANDROID_ABIS)
+ if(target_abis)
+ # Use target-specific Qt for Android ABIs.
+ set(android_abis ${target_abis})
+ elseif(QT_ANDROID_BUILD_ALL_ABIS)
+ # Use autodetected Qt for Android ABIs.
+ set(android_abis ${QT_DEFAULT_ANDROID_ABIS})
+ elseif(QT_ANDROID_ABIS)
+ # Use project-wide Qt for Android ABIs.
+ set(android_abis ${QT_ANDROID_ABIS})
+ else()
+ # User have an empty list of Qt for Android ABIs.
+ message(FATAL_ERROR
+ "The list of Android ABIs is empty, when building ${target}.\n"
+ "You have the following options to select ABIs for a target:\n"
+ " - Set the QT_ANDROID_ABIS variable before calling qt6_add_executable\n"
+ " - Set the ANDROID_ABIS property for ${target}\n"
+ " - Set QT_ANDROID_BUILD_ALL_ABIS flag to try building with\n"
+ " the list of autodetected Qt for Android:\n ${QT_DEFAULT_ANDROID_ABIS}"
+ )
+ endif()
+
+ set(missing_qt_abi_toolchains "")
+ # 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})
+ list(REMOVE_ITEM android_abis "${abi}")
+ continue()
+ endif()
+
+ get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
+ if(is_multi_config)
+ list(JOIN CMAKE_CONFIGURATION_TYPES "$<SEMICOLON>" escaped_configuration_types)
+ set(config_arg "-DCMAKE_CONFIGURATION_TYPES=${escaped_configuration_types}")
+ else()
+ set(config_arg "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
+ 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_get_android_abi_path(qt_abi_path ${abi})
+ set(qt_abi_toolchain_path
+ "${qt_abi_path}/lib/cmake/${QT_CMAKE_EXPORT_NAMESPACE}/qt.toolchain.cmake")
+ ExternalProject_Add("qt_internal_android_${abi}"
+ SOURCE_DIR "${CMAKE_SOURCE_DIR}"
+ BINARY_DIR "${android_abi_build_dir}"
+ CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${qt_abi_toolchain_path}"
+ "-DQT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT=ON"
+ "-DQT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR=${CMAKE_BINARY_DIR}"
+ "${config_arg}"
+ EXCLUDE_FROM_ALL TRUE
+ STETPS_TARGETS
+ 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
+ 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}_build")
+ add_dependencies(${target} "qt_internal_android_${abi}-${target}_build")
+ endforeach()
+
+ if(missing_qt_abi_toolchains)
+ list(JOIN missing_qt_abi_toolchains ", " missing_qt_abi_toolchains_string)
+ message(FATAL_ERROR "Cannot find toolchain files for the manually specified Android"
+ " ABIs: ${missing_qt_abi_toolchains_string}"
+ "\nNote that you also may manually specify the path to the required Qt for"
+ " Android ABI using QT_PATH_ANDROID_ABI_<abi> CMake variable.\n")
+ endif()
+
+ list(JOIN android_abis ", " android_abis_string)
+ if(android_abis_string)
+ set(android_abis_string "${CMAKE_ANDROID_ARCH_ABI}(default), ${android_abis_string}")
+ else()
+ set(android_abis_string "${CMAKE_ANDROID_ARCH_ABI}(default)")
+ endif()
+ if(NOT QT_NO_ANDROID_ABI_STATUS_MESSAGE)
+ message(STATUS "Configuring '${target}' for the following Android ABIs:"
+ " ${android_abis_string}")
+ endif()
+ set_target_properties(${target} PROPERTIES _qt_android_abis "${android_abis}")
+endfunction()
diff --git a/src/corelib/Qt6CoreMacros.cmake b/src/corelib/Qt6CoreMacros.cmake
index 1949ca7066..afaa416349 100644
--- a/src/corelib/Qt6CoreMacros.cmake
+++ b/src/corelib/Qt6CoreMacros.cmake
@@ -542,10 +542,9 @@ function(qt6_add_executable target)
endfunction()
function(_qt_internal_create_executable target)
- cmake_parse_arguments(arg "" "" "ANDROID_ABIS" ${ARGN})
if(ANDROID)
- list(REMOVE_ITEM arg_UNPARSED_ARGUMENTS "WIN32" "MACOSX_BUNDLE")
- add_library("${target}" MODULE ${arg_UNPARSED_ARGUMENTS})
+ list(REMOVE_ITEM ARGN "WIN32" "MACOSX_BUNDLE")
+ add_library("${target}" MODULE ${ARGN})
# On our qmake builds we do don't compile the executables with
# visibility=hidden. Not having this flag set will cause the
# executable to have main() hidden and can then no longer be loaded
@@ -556,108 +555,8 @@ function(_qt_internal_create_executable target)
set_property(TARGET "${target}" PROPERTY OBJCXX_VISIBILITY_PRESET default)
qt6_android_apply_arch_suffix("${target}")
set_property(TARGET "${target}" PROPERTY _qt_is_android_executable TRUE)
- # Build per-abi binaries for android
- if(NOT QT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT)
- if(QT_ANDROID_BUILD_ALL_ABIS)
- # Use autodetected Qt for Android ABIs.
- set(android_abis ${QT_DEFAULT_ANDROID_ABIS})
- elseif(arg_ANDROID_ABIS)
- # Use target-specific Qt for Android ABIs.
- set(android_abis ${arg_ANDROID_ABIS})
- elseif(QT_ANDROID_ABIS)
- # Use project-wide Qt for Android ABIs.
- set(android_abis ${QT_ANDROID_ABIS})
- else()
- # User have an empty list of Qt for Android ABIs.
- message(FATAL_ERROR
- "The list of Android ABIs is empty, when building ${target}.\n"
- "You have the following options to select ABIs for a target:\n"
- " - Set the QT_ANDROID_ABIS variable before calling qt6_add_executable\n"
- " - Add the ANDROID_ABIS parameter to the qt6_add_executable call\n"
- " - Set QT_ANDROID_BUILD_ALL_ABIS flag to try building with\n"
- " the list of autodetected Qt for Android:\n ${QT_DEFAULT_ANDROID_ABIS}"
- )
- endif()
-
- set(missing_qt_abi_toolchains "")
- # 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})
- list(REMOVE_ITEM android_abis "${abi}")
- continue()
- endif()
-
- get_cmake_property(is_multi_config GENERATOR_IS_MULTI_CONFIG)
- if(is_multi_config)
- list(JOIN CMAKE_CONFIGURATION_TYPES "$<SEMICOLON>" escaped_configuration_types)
- set(config_arg "-DCMAKE_CONFIGURATION_TYPES=${escaped_configuration_types}")
- else()
- set(config_arg "-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}")
- 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_get_android_abi_path(qt_abi_path ${abi})
- set(qt_abi_toolchain_path
- "${qt_abi_path}/lib/cmake/${QT_CMAKE_EXPORT_NAMESPACE}/qt.toolchain.cmake")
- ExternalProject_Add("qt_internal_android_${abi}"
- SOURCE_DIR "${CMAKE_SOURCE_DIR}"
- BINARY_DIR "${android_abi_build_dir}"
- CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${qt_abi_toolchain_path}"
- "-DQT_IS_ANDROID_MULTI_ABI_EXTERNAL_PROJECT=ON"
- "-DQT_INTERNAL_ANDROID_MULTI_ABI_BINARY_DIR=${CMAKE_BINARY_DIR}"
- "${config_arg}"
- EXCLUDE_FROM_ALL TRUE
- STETPS_TARGETS
- 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
- 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}_build")
- add_dependencies(${target} "qt_internal_android_${abi}-${target}_build")
- endforeach()
-
- if(missing_qt_abi_toolchains)
- list(JOIN missing_qt_abi_toolchains ", " missing_qt_abi_toolchains_string)
- message(FATAL_ERROR "Cannot find toolchain files for the manually specified Android"
- " ABIs: ${missing_qt_abi_toolchains_string}"
- "\nSkipping these ABIs."
- "\nNote that you also may manually specify the path to the required Qt for"
- " Android ABI using QT_PATH_ANDROID_ABI_<abi> CMake variable.\n")
- endif()
-
- list(JOIN android_abis ", " android_abis_string)
- if(android_abis_string)
- set(android_abis_string "${CMAKE_ANDROID_ARCH_ABI}(default), ${android_abis_string}")
- else()
- set(android_abis_string "${CMAKE_ANDROID_ARCH_ABI}(default)")
- endif()
- if(NOT QT_NO_ANDROID_ABI_STATUS_MESSAGE)
- message(STATUS "Configuring '${target}' for the following Android ABIs:"
- " ${android_abis_string}")
- endif()
- set_target_properties(${target} PROPERTIES _qt_android_abis "${android_abis}")
- endif()
else()
- add_executable("${target}" ${arg_UNPARSED_ARGUMENTS})
+ add_executable("${target}" ${ARGN})
endif()
_qt_internal_set_up_static_runtime_library("${target}")
@@ -719,6 +618,7 @@ function(_qt_internal_finalize_executable target)
endif()
if(ANDROID)
+ _qt_internal_configure_android_multiabi_target("${target}")
qt6_android_generate_deployment_settings("${target}")
qt6_android_add_apk_target("${target}")
endif()