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>
This commit is contained in:
parent
612417ea70
commit
f90221d8cd
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
@ -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()
|
||||
|
Loading…
Reference in New Issue
Block a user