diff options
-rw-r--r-- | src/corelib/Qt5AndroidSupport.cmake | 191 | ||||
-rw-r--r-- | src/corelib/Qt5CoreConfigExtras.cmake.in | 4 | ||||
-rw-r--r-- | src/corelib/Qt5ModuleLocation.cmake.in | 2 | ||||
-rw-r--r-- | src/corelib/corelib.pro | 11 |
4 files changed, 207 insertions, 1 deletions
diff --git a/src/corelib/Qt5AndroidSupport.cmake b/src/corelib/Qt5AndroidSupport.cmake new file mode 100644 index 0000000000..4bf826eedc --- /dev/null +++ b/src/corelib/Qt5AndroidSupport.cmake @@ -0,0 +1,191 @@ +if (NOT ${PROJECT_NAME}-MultiAbiBuild) + + set(ANDROID_ABIS armeabi-v7a arm64-v8a x86 x86_64) + + # Match Android's sysroots + set(ANDROID_SYSROOT_armeabi-v7a arm-linux-androideabi) + set(ANDROID_SYSROOT_arm64-v8a aarch64-linux-android) + set(ANDROID_SYSROOT_x86 i686-linux-android) + set(ANDROID_SYSROOT_x86_64 x86_64-linux-android) + + foreach(abi IN LISTS ANDROID_ABIS) + set(abi_initial_value OFF) + if (abi STREQUAL ${ANDROID_ABI}) + set(abi_initial_value ON) + endif() + find_library(Qt5Core_${abi}_Probe Qt5Core_${abi}) + if (Qt5Core_${abi}_Probe) + option(ANDROID_BUILD_ABI_${abi} "Enable the build for Android ${abi}" ${abi_initial_value}) + endif() + endforeach() + + # Make sure to delete the "android-build" directory, which contains all the + # build artefacts, and also the androiddeployqt/gradle artefacts + set_property(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + APPEND PROPERTY ADDITIONAL_CLEAN_FILES ${CMAKE_BINARY_DIR}/android-build) + + if (CMAKE_VERSION VERSION_LESS 3.15) + message(STATUS "-----------------------------------------------------------------------------------------------------------") + message(STATUS "CMake version 3.15 is required to clean the <build_dir>/android-build when issuing the \"clean\" target.\n\n" + "For this CMake version please use the \"clean-android-build\" support target additionally to the \"clean\" target.") + message(STATUS "-----------------------------------------------------------------------------------------------------------") + + add_custom_target(clean-android-build + COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_BINARY_DIR}/android-build + VERBATIM) + endif() + + # Write the android_<project_name>_deployment_settings.json file + file(WRITE ${CMAKE_BINARY_DIR}/android_deployment_settings.json.in +[=[{ + "_description": "This file is created by CMake to be read by androiddeployqt and should not be modified by hand.", + "application-binary": "@QT_ANDROID_APPLICATION_BINARY@", + "architectures": { +@QT_ANDROID_ARCHITECTURES@ + }, + @QT_ANDROID_DEPLOYMENT_DEPENDENCIES@ + @QT_ANDROID_EXTRA_PLUGINS@ + @QT_ANDROID_PACKAGE_SOURCE_DIR@ + @QT_ANDROID_VERSION_CODE@ + @QT_ANDROID_VERSION_NAME@ + @QT_ANDROID_EXTRA_LIBS@ + @QT_QML_IMPORT_PATH@ + "ndk": "@ANDROID_NDK@", + "ndk-host": "@ANDROID_HOST_TAG@", + "qml-root-path": "@CMAKE_CURRENT_SOURCE_DIR@", + "qt": "@QT_DIR@", + "sdk": "@ANDROID_SDK@", + "stdcpp-path": "@ANDROID_TOOLCHAIN_ROOT@/sysroot/usr/lib/", + "tool-prefix": "llvm", + "toolchain-prefix": "llvm", + "useLLVM": true +}]=]) + + if (NOT QT_ANDROID_APPLICATION_BINARY) + set(QT_ANDROID_APPLICATION_BINARY ${PROJECT_NAME}) + endif() + + if(NOT ANDROID_SDK) + get_filename_component(ANDROID_SDK ${ANDROID_NDK}/../ ABSOLUTE) + endif() + + find_program(ANDROID_DEPLOY_QT androiddeployqt) + get_filename_component(QT_DIR ${ANDROID_DEPLOY_QT}/../../ ABSOLUTE) + + unset(QT_ANDROID_ARCHITECTURES) + foreach(abi IN LISTS ANDROID_ABIS) + if (ANDROID_BUILD_ABI_${abi}) + list(APPEND QT_ANDROID_ARCHITECTURES " \"${abi}\" : \"${ANDROID_SYSROOT_${abi}}\"") + endif() + endforeach() + string(REPLACE ";" ",\n" QT_ANDROID_ARCHITECTURES "${QT_ANDROID_ARCHITECTURES}") + + macro(generate_json_variable_list var_list json_key) + if (${var_list}) + set(QT_${var_list} "\"${json_key}\": \"") + string(REPLACE ";" "," joined_var_list "${${var_list}}") + string(APPEND QT_${var_list} "${joined_var_list}\",") + endif() + endmacro() + + macro(generate_json_variable var json_key) + if (${var}) + set(QT_${var} "\"${json_key}\": \"${${var}}\",") + endif() + endmacro() + + generate_json_variable_list(ANDROID_DEPLOYMENT_DEPENDENCIES "deployment-dependencies") + generate_json_variable_list(ANDROID_EXTRA_PLUGINS "android-extra-plugins") + generate_json_variable(ANDROID_PACKAGE_SOURCE_DIR "android-package-source-directory") + generate_json_variable(ANDROID_VERSION_CODE "android-version-code") + generate_json_variable(ANDROID_VERSION_NAME "android-version-name") + generate_json_variable_list(ANDROID_EXTRA_LIBS "android-extra-libs") + generate_json_variable_list(QML_IMPORT_PATH "qml-import-paths") + + configure_file( + "${CMAKE_BINARY_DIR}/android_deployment_settings.json.in" + "${CMAKE_BINARY_DIR}/android_deployment_settings.json" @ONLY) + + # Create "apk" and "aab" targets + if (DEFINED ENV{JAVA_HOME}) + set(JAVA_HOME $ENV{JAVA_HOME} CACHE INTERNAL "Saved JAVA_HOME variable") + endif() + if (JAVA_HOME) + set(android_deploy_qt_jdk "--jdk ${JAVA_HOME}") + endif() + + if (ANDROID_SDK_PLATFORM) + set(android_deploy_qt_platform "--android-platform ${ANDROID_SDK_PLATFORM}") + endif() + + add_custom_target(apk + COMMAND ${CMAKE_COMMAND} -E env JAVA_HOME=${JAVA_HOME} ${ANDROID_DEPLOY_QT} + --input "${CMAKE_BINARY_DIR}/android_deployment_settings.json" + --output "${CMAKE_BINARY_DIR}/android-build" + --apk "${CMAKE_BINARY_DIR}/android-build/${PROJECT_NAME}.apk" + ${android_deploy_qt_platform} + ${android_deploy_qt_jdk} + VERBATIM) + + add_custom_target(aab + COMMAND ${CMAKE_COMMAND} -E env JAVA_HOME=${JAVA_HOME} ${ANDROID_DEPLOY_QT} + --input "${CMAKE_BINARY_DIR}/android_deployment_settings.json" + --output "${CMAKE_BINARY_DIR}/android-build" + --apk "${CMAKE_BINARY_DIR}/android-build/${PROJECT_NAME}.apk" + --aab + ${android_deploy_qt_platform} + ${android_deploy_qt_jdk} + VERBATIM) + + include(ExternalProject) + macro (setup_library library_name android_abi) + # Use Qt Creator's 4.12 settings file if present + unset(QTC_SETTINGS_PARAMETER) + if (EXISTS ${CMAKE_BINARY_DIR}/qtcsettings.cmake) + set(QTC_SETTINGS_PARAMETER -C ${CMAKE_BINARY_DIR}/qtcsettings.cmake) + endif() + + # Build all the given ABI as an external project + ExternalProject_Add(${library_name}-builder + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}" + PREFIX MultiAbi + BUILD_ALWAYS YES + DOWNLOAD_COMMAND "" + INSTALL_COMMAND "" + UPDATE_COMMAND "" + PATCH_COMMAND "" + CMAKE_ARGS + ${QTC_SETTINGS_PARAMETER} + -D ANDROID_ABI=${android_abi} + -D CMAKE_FIND_ROOT_PATH=${CMAKE_FIND_ROOT_PATH} + -D CMAKE_PREFIX_PATH=${CMAKE_PREFIX_PATH} + -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D ANDROID_PLATFORM=${ANDROID_PLATFORM} + -D ANDROID_NATIVE_API_LEVEL=${ANDROID_NATIVE_API_LEVEL} + -D CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} + -D CMAKE_FIND_ROOT_PATH_MODE_PROGRAM=${CMAKE_FIND_ROOT_PATH_MODE_PROGRAM} + -D CMAKE_FIND_ROOT_PATH_MODE_LIBRARY=${CMAKE_FIND_ROOT_PATH_MODE_LIBRARY} + -D CMAKE_FIND_ROOT_PATH_MODE_INCLUDE=${CMAKE_FIND_ROOT_PATH_MODE_INCLUDE} + -D CMAKE_FIND_ROOT_PATH_MODE_PACKAGE=${CMAKE_FIND_ROOT_PATH_MODE_PACKAGE} + -D CMAKE_SHARED_LIBRARY_SUFFIX_CXX=_${android_abi}.so + -D CMAKE_LIBRARY_OUTPUT_DIRECTORY=${CMAKE_BINARY_DIR}/android-build/libs/${android_abi} + -D ${PROJECT_NAME}-MultiAbiBuild=ON + ) + endmacro() + + foreach(abi IN LISTS ANDROID_ABIS) + if (NOT abi STREQUAL ${ANDROID_ABI}) + if (ANDROID_BUILD_ABI_${abi}) + setup_library(${PROJECT_NAME}-${abi} ${abi} ${CMAKE_PREFIX_PATH}) + endif() + else() + # For the default abi just use the regular cmake run, to have + # nice IDE integration and so on + set(CMAKE_SHARED_LIBRARY_SUFFIX_CXX "_${ANDROID_ABI}.so") + set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/android-build/libs/${ANDROID_ABI}) + endif() + endforeach() +else() + # unset the variable, just not to issue an unused variable warning + unset(${PROJECT_NAME}-MultiAbiBuild) +endif() diff --git a/src/corelib/Qt5CoreConfigExtras.cmake.in b/src/corelib/Qt5CoreConfigExtras.cmake.in index 659faac6a5..9b672327ef 100644 --- a/src/corelib/Qt5CoreConfigExtras.cmake.in +++ b/src/corelib/Qt5CoreConfigExtras.cmake.in @@ -172,4 +172,8 @@ get_filename_component(_Qt5CoreConfigDir ${CMAKE_CURRENT_LIST_FILE} PATH) set(_Qt5CTestMacros \"${_Qt5CoreConfigDir}/Qt5CTestMacros.cmake\") +if (ANDROID_PLATFORM) + include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5AndroidSupport.cmake\") +endif() + _qt5_Core_check_file_exists(${_Qt5CTestMacros}) diff --git a/src/corelib/Qt5ModuleLocation.cmake.in b/src/corelib/Qt5ModuleLocation.cmake.in index 5065ada56e..cf70f6bc0e 100644 --- a/src/corelib/Qt5ModuleLocation.cmake.in +++ b/src/corelib/Qt5ModuleLocation.cmake.in @@ -4,7 +4,7 @@ get_filename_component(_qt5_root_dir \"${CMAKE_CURRENT_LIST_DIR}/../../../..\" A file(GLOB qtmodules ${_qt5_root_dir} "${_qt5_root_dir}/*") foreach(qtmodule ${qtmodules}) if(IS_DIRECTORY ${qtmodule}) - list(APPEND _qt5_module_paths ${qtmodule}) + list(APPEND _qt5_module_paths "${qtmodule}" "${qtmodule}/lib/cmake") endif() endforeach() !!ELSE diff --git a/src/corelib/corelib.pro b/src/corelib/corelib.pro index 452d2db0fd..6c101e21ca 100644 --- a/src/corelib/corelib.pro +++ b/src/corelib/corelib.pro @@ -99,6 +99,12 @@ cmake_umbrella_config_module_location_for_install.output = $$DESTDIR/cmake/insta cmake_umbrella_config_version_file.input = $$PWD/../../mkspecs/features/data/cmake/Qt5ConfigVersion.cmake.in cmake_umbrella_config_version_file.output = $$DESTDIR/cmake/Qt5/Qt5ConfigVersion.cmake +android { + cmake_android_support.input = $$PWD/Qt5AndroidSupport.cmake + cmake_android_support.output = $$DESTDIR/cmake/Qt5Core/Qt5AndroidSupport.cmake + cmake_android_support.CONFIG = verbatim +} + load(cmake_functions) defineTest(pathIsAbsolute) { @@ -144,6 +150,11 @@ QMAKE_SUBSTITUTES += \ cmake_extras_mkspec_dir \ cmake_extras_mkspec_dir_for_install +android { + QMAKE_SUBSTITUTES += cmake_android_support + ctest_qt5_module_files.files += $$cmake_android_support.output +} + ctest_qt5_module_files.files += $$ctest_macros_file.output $$cmake_extras_mkspec_dir_for_install.output ctest_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5Core |