Many fixes and improvements, to work with newer Android NDKs - refactoring of PR #25 by OlivierLDff (olivier.ldff@gmail.com)

This commit is contained in:
Laurent Gomila 2020-01-29 13:18:59 +01:00
parent e3bd0c4930
commit 78f06f318c
6 changed files with 297 additions and 84 deletions

View File

@ -1,5 +1,4 @@
cmake_minimum_required(VERSION 3.0)
cmake_policy(SET CMP0026 OLD) # allow use of the LOCATION target property
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
# store the current source directory for future use
set(QT_ANDROID_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR})
@ -39,7 +38,7 @@ if(NOT QT_ANDROID_NDK_ROOT)
if(NOT QT_ANDROID_NDK_ROOT)
set(QT_ANDROID_NDK_ROOT ${ANDROID_NDK})
if(NOT QT_ANDROID_NDK_ROOT)
message(FATAL_ERROR "Could not find the Android NDK. Please set either the ANDROID_NDK environment or CMake variable, or the QT_ANDROID_NDK_ROOT CMake variable to the root directory of the Android NDK")
message(FATAL_ERROR "Could not find the Android NDK. Please set either the ANDROID_NDK environment or CMake variable, or the QT_ANDROID_NDK_ROOT CMake variable to the root directory of the Android NDK")
endif()
endif()
endif()
@ -61,18 +60,14 @@ include(CMakeParseArguments)
# DEPENDS a_linked_target "path/to/a_linked_library.so" ...
# INSTALL
#)
#
#
macro(add_qt_android_apk TARGET SOURCE_TARGET)
# parse the macro arguments
cmake_parse_arguments(ARG "INSTALL" "NAME;VERSION_CODE;PACKAGE_NAME;PACKAGE_SOURCES;KEYSTORE_PASSWORD" "DEPENDS;KEYSTORE" ${ARGN})
# extract the full path of the source target binary
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
get_property(QT_ANDROID_APP_PATH TARGET ${SOURCE_TARGET} PROPERTY DEBUG_LOCATION)
else()
get_property(QT_ANDROID_APP_PATH TARGET ${SOURCE_TARGET} PROPERTY LOCATION)
endif()
set(QT_ANDROID_APP_PATH "$<TARGET_FILE:${SOURCE_TARGET}>") # full file path to the app's main shared library
# define the application name
if(ARG_NAME)
@ -97,41 +92,82 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
set(QT_ANDROID_SDK_BUILDTOOLS_REVISION ${BUILD_TOOLS_VERSION})
endif()
endforeach()
message("Detected Android SDK build tools version ${QT_ANDROID_SDK_BUILDTOOLS_REVISION}")
message(STATUS "Found Android SDK build tools version: ${QT_ANDROID_SDK_BUILDTOOLS_REVISION}")
# define the application source package directory
if(ARG_PACKAGE_SOURCES)
set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT ${ARG_PACKAGE_SOURCES})
else()
# get version code from arguments, or generate a fixed one if not provided
set(QT_ANDROID_APP_VERSION_CODE ${ARG_VERSION_CODE})
if(NOT QT_ANDROID_APP_VERSION_CODE)
set(QT_ANDROID_APP_VERSION_CODE 1)
endif()
# get version code from arguments, or generate a fixed one if not provided
set(QT_ANDROID_APP_VERSION_CODE ${ARG_VERSION_CODE})
if(NOT QT_ANDROID_APP_VERSION_CODE)
set(QT_ANDROID_APP_VERSION_CODE 1)
endif()
# try to extract the app version from the target properties, or use the version code if not provided
get_property(QT_ANDROID_APP_VERSION TARGET ${SOURCE_TARGET} PROPERTY VERSION)
if(NOT QT_ANDROID_APP_VERSION)
# try to extract the app version from the target properties, or use the version code if not provided
get_property(QT_ANDROID_APP_VERSION TARGET ${SOURCE_TARGET} PROPERTY VERSION)
if(NOT QT_ANDROID_APP_VERSION)
if(${PROJECT_VERSION} STREQUAL "")
set(QT_ANDROID_APP_VERSION ${QT_ANDROID_APP_VERSION_CODE})
else()
set(QT_ANDROID_APP_VERSION ${PROJECT_VERSION})
endif()
endif()
# create a subdirectory for the extra package sources
# check if the user provides a custom source package and its own manifest file
if(ARG_PACKAGE_SOURCES)
if(EXISTS "${ARG_PACKAGE_SOURCES}/AndroidManifest.xml")
# custom manifest provided, use the provided source package directly
set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT ${ARG_PACKAGE_SOURCES})
elseif(EXISTS "${ARG_PACKAGE_SOURCES}/AndroidManifest.xml.in")
# custom manifest template provided
set(QT_ANDROID_MANIFEST_TEMPLATE "${ARG_PACKAGE_SOURCES}/AndroidManifest.xml.in")
endif()
endif()
# generate a source package directory if none was provided, or if we need to configure a manifest file
if(NOT QT_ANDROID_APP_PACKAGE_SOURCE_ROOT)
# create our own configured package directory in build dir
set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT "${CMAKE_CURRENT_BINARY_DIR}/package")
# generate a manifest from the template
configure_file(${QT_ANDROID_SOURCE_DIR}/AndroidManifest.xml.in ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}/AndroidManifest.xml @ONLY)
# create the manifest from the template file
if(NOT QT_ANDROID_MANIFEST_TEMPLATE)
set(QT_ANDROID_MANIFEST_TEMPLATE "${QT_ANDROID_SOURCE_DIR}/AndroidManifest.xml.in")
endif()
configure_file(${QT_ANDROID_MANIFEST_TEMPLATE} ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml @ONLY)
# define commands that will be added before the APK target build commands, to refresh the source package directory
set(QT_ANDROID_PRE_COMMANDS ${QT_ANDROID_PRE_COMMANDS} COMMAND ${CMAKE_COMMAND} -E remove_directory ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}) # clean the destination directory
set(QT_ANDROID_PRE_COMMANDS ${QT_ANDROID_PRE_COMMANDS} COMMAND ${CMAKE_COMMAND} -E make_directory ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}) # re-create it
if(ARG_PACKAGE_SOURCES)
set(QT_ANDROID_PRE_COMMANDS ${QT_ANDROID_PRE_COMMANDS} COMMAND ${CMAKE_COMMAND} -E copy_directory ${ARG_PACKAGE_SOURCES} ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}) # copy the user package
endif()
set(QT_ANDROID_PRE_COMMANDS ${QT_ANDROID_PRE_COMMANDS} COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_BINARY_DIR}/AndroidManifest.xml ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}/AndroidManifest.xml) # copy the generated manifest
endif()
# newer NDK toolchains don't define ANDROID_STL_PREFIX anymore,
# so this is a fallback to the only supported value in recent versions
if(NOT ANDROID_STL_PREFIX)
if(ANDROID_STL MATCHES "^c\\+\\+_")
set(ANDROID_STL_PREFIX llvm-libc++)
endif()
endif()
if(NOT ANDROID_STL_PREFIX)
message(WARNING "Failed to determine ANDROID_STL_PREFIX value for ANDROID_STL=${ANDROID_STL}")
endif()
# define the STL shared library path
# up until NDK r18, ANDROID_STL_SHARED_LIBRARIES is populated by the NDK's toolchain file
# since NDK r19, the only option for a shared STL library is libc++_shared
if(ANDROID_STL_SHARED_LIBRARIES)
list(GET ANDROID_STL_SHARED_LIBRARIES 0 STL_LIBRARY_NAME) # we can only give one to androiddeployqt
if(ANDROID_STL_PATH)
set(QT_ANDROID_STL_PATH "${ANDROID_STL_PATH}/libs/${ANDROID_ABI}/lib${STL_LIBRARY_NAME}.so")
set(QT_ANDROID_STL_PATH "${ANDROID_STL_PATH}/libs/${ANDROID_ABI}/lib${ANDROID_STL}.so")
else()
set(QT_ANDROID_STL_PATH "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/lib${STL_LIBRARY_NAME}.so")
set(QT_ANDROID_STL_PATH "${QT_ANDROID_NDK_ROOT}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/lib${ANDROID_STL}.so")
endif()
elseif(ANDROID_STL STREQUAL c++_shared)
set(QT_ANDROID_STL_PATH "${QT_ANDROID_NDK_ROOT}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/libc++_shared.so")
else()
set(QT_ANDROID_STL_PATH)
message(WARNING "ANDROID_STL (${ANDROID_STL}) isn't a known shared stl library."
"You should consider setting ANDROID_STL to c++_shared (like Qt).")
set(QT_ANDROID_STL_PATH "${QT_ANDROID_NDK_ROOT}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/libc++_shared.so")
endif()
# set the list of dependant libraries
@ -139,42 +175,66 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
foreach(LIB ${ARG_DEPENDS})
if(TARGET ${LIB})
# item is a CMake target, extract the library path
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
get_property(LIB_PATH TARGET ${LIB} PROPERTY DEBUG_LOCATION)
else()
get_property(LIB_PATH TARGET ${LIB} PROPERTY LOCATION)
endif()
set(LIB ${LIB_PATH})
set(LIB "$<TARGET_FILE:${LIB}>")
endif()
if(EXTRA_LIBS)
set(EXTRA_LIBS "${EXTRA_LIBS},${LIB}")
else()
set(EXTRA_LIBS "${LIB}")
endif()
if(EXTRA_LIBS)
set(EXTRA_LIBS "${EXTRA_LIBS},${LIB}")
else()
set(EXTRA_LIBS "${LIB}")
endif()
endforeach()
set(QT_ANDROID_APP_EXTRA_LIBS "\"android-extra-libs\": \"${EXTRA_LIBS}\",")
endif()
# determine whether to use the gcc- or llvm/clang- toolchain;
# if ANDROID_USE_LLVM was explicitly set, use its value directly,
# otherwise ANDROID_TOOLCHAIN value (set by the NDK's toolchain file)
# says whether llvm/clang or gcc is used
if(DEFINED ANDROID_USE_LLVM)
string(TOLOWER "${ANDROID_USE_LLVM}" QT_ANDROID_USE_LLVM)
elseif(ANDROID_TOOLCHAIN STREQUAL clang)
set(QT_ANDROID_USE_LLVM "true")
else()
set(QT_ANDROID_USE_LLVM "false")
endif()
# set some toolchain variables used by androiddeployqt;
# unfortunately, Qt tries to build paths from these variables although these full paths
# are already available in the toochain file, so we have to parse them
string(REGEX MATCH "${ANDROID_NDK}/toolchains/(.*)-(.*)/prebuilt/.*" ANDROID_TOOLCHAIN_PARSED ${ANDROID_TOOLCHAIN_ROOT})
if(ANDROID_TOOLCHAIN_PARSED)
set(QT_ANDROID_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
set(QT_ANDROID_TOOLCHAIN_VERSION ${CMAKE_MATCH_2})
# are already available in the toochain file, so we have to parse them if using gcc
if(QT_ANDROID_USE_LLVM STREQUAL "true")
set(QT_ANDROID_TOOLCHAIN_PREFIX "llvm")
set(QT_ANDROID_TOOLCHAIN_VERSION)
set(QT_ANDROID_TOOL_PREFIX "llvm")
else()
message(FATAL_ERROR "Failed to parse ANDROID_TOOLCHAIN_ROOT to get toolchain prefix and version")
string(REGEX MATCH "${QT_ANDROID_NDK_ROOT}/toolchains/(.*)-(.*)/prebuilt/.*/bin/(.*)-" ANDROID_TOOLCHAIN_PARSED ${ANDROID_TOOLCHAIN_PREFIX})
if(ANDROID_TOOLCHAIN_PARSED)
set(QT_ANDROID_TOOLCHAIN_PREFIX ${CMAKE_MATCH_1})
set(QT_ANDROID_TOOLCHAIN_VERSION ${CMAKE_MATCH_2})
set(QT_ANDROID_TOOL_PREFIX ${CMAKE_MATCH_3})
else()
message(FATAL_ERROR "Failed to parse ANDROID_TOOLCHAIN_PREFIX to get toolchain prefix and version and tool prefix")
endif()
endif()
# make sure that the output directory for the Android package exists
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_ABI})
set(QT_ANDROID_APP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SOURCE_TARGET}-${ANDROID_ABI})
file(MAKE_DIRECTORY ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI})
# create the configuration file that will feed androiddeployqt
configure_file(${QT_ANDROID_SOURCE_DIR}/qtdeploy.json.in ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json @ONLY)
# 1. replace placeholder variables at generation time
configure_file(${QT_ANDROID_SOURCE_DIR}/qtdeploy.json.in ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json.in @ONLY)
# 2. evaluate generator expressions at build time
file(GENERATE
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json
INPUT ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json.in
)
# 3. Configure build.gradle to properly work with Android Studio import
set(QT_ANDROID_NATIVE_API_LEVEL ${ANDROID_NATIVE_API_LEVEL})
configure_file(${QT_ANDROID_SOURCE_DIR}/build.gradle.in ${QT_ANDROID_APP_BINARY_DIR}/build.gradle @ONLY)
# check if the apk must be signed
if(ARG_KEYSTORE)
set(SIGN_OPTIONS --release --sign ${ARG_KEYSTORE} --tsa http://timestamp.digicert.com)
set(SIGN_OPTIONS --sign ${ARG_KEYSTORE})
if(ARG_KEYSTORE_PASSWORD)
set(SIGN_OPTIONS ${SIGN_OPTIONS} --storepass ${ARG_KEYSTORE_PASSWORD})
endif()
@ -190,15 +250,32 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
set(TARGET_LEVEL_OPTIONS --android-platform android-${ANDROID_PLATFORM_LEVEL})
endif()
# determine the build type to pass to androiddeployqt
if(CMAKE_BUILD_TYPE AND ${CMAKE_BUILD_TYPE} STREQUAL "Debug" AND NOT ARG_KEYSTORE)
set(QT_ANDROID_BUILD_TYPE --debug)
elseif()
set(QT_ANDROID_BUILD_TYPE --release)
endif()
# create a custom command that will run the androiddeployqt utility to prepare the Android package
add_custom_target(
${TARGET}
ALL
DEPENDS ${SOURCE_TARGET}
COMMAND ${CMAKE_COMMAND} -E remove_directory ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_ABI} # it seems that recompiled libraries are not copied if we don't remove them first
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E copy ${QT_ANDROID_APP_PATH} ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${QT_ANDROID_QT_ROOT}/bin/androiddeployqt --verbose --output ${CMAKE_CURRENT_BINARY_DIR} --input ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json --gradle ${TARGET_LEVEL_OPTIONS} ${INSTALL_OPTIONS} ${SIGN_OPTIONS}
${QT_ANDROID_PRE_COMMANDS}
# it seems that recompiled libraries are not copied if we don't remove them first
COMMAND ${CMAKE_COMMAND} -E remove_directory ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E make_directory ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E copy ${QT_ANDROID_APP_PATH} ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${QT_ANDROID_QT_ROOT}/bin/androiddeployqt
--verbose
--output ${QT_ANDROID_APP_BINARY_DIR}
--input ${CMAKE_CURRENT_BINARY_DIR}/qtdeploy.json
--gradle
${QT_ANDROID_BUILD_TYPE}
${TARGET_LEVEL_OPTIONS}
${INSTALL_OPTIONS}
${SIGN_OPTIONS}
)
endmacro()

View File

@ -1,35 +1,81 @@
<?xml version="1.0"?>
<manifest android:versionName="@QT_ANDROID_APP_VERSION@" package="@QT_ANDROID_APP_PACKAGE_NAME@" android:installLocation="auto" xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="@QT_ANDROID_APP_VERSION_CODE@">
<application android:label="@QT_ANDROID_APP_NAME@" android:name="org.qtproject.qt5.android.bindings.QtApplication">
<activity android:label="@QT_ANDROID_APP_NAME@" android:name="org.qtproject.qt5.android.bindings.QtActivity" android:screenOrientation="unspecified" android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Messages maps -->
<!--<meta-data android:name="android.app.ministro_not_found_msg" android:value="@string/ministro_not_found_msg"/>
<meta-data android:name="android.app.ministro_needed_msg" android:value="@string/ministro_needed_msg"/>
<meta-data android:name="android.app.fatal_error_msg" android:value="@string/fatal_error_msg"/>-->
</activity>
</application>
<supports-screens android:anyDensity="true" android:normalScreens="true" android:smallScreens="true" android:largeScreens="true"/>
<manifest android:versionName="@QT_ANDROID_APP_VERSION@"
package="@QT_ANDROID_APP_PACKAGE_NAME@"
android:installLocation="auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="@QT_ANDROID_APP_VERSION_CODE@">
<application
android:label="@QT_ANDROID_APP_NAME@"
android:name="org.qtproject.qt5.android.bindings.QtApplication">
<activity
android:label="@QT_ANDROID_APP_NAME@"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:screenOrientation="unspecified"
android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="android.app.lib_name" android:value="-- %%INSERT_APP_LIB_NAME%% --"/>
<meta-data android:name="android.app.qt_sources_resource_id" android:resource="@array/qt_sources"/>
<meta-data android:name="android.app.repository" android:value="default"/>
<meta-data android:name="android.app.qt_libs_resource_id" android:resource="@array/qt_libs"/>
<meta-data android:name="android.app.bundled_libs_resource_id" android:resource="@array/bundled_libs"/>
<!-- Deploy Qt libs as part of package -->
<meta-data android:name="android.app.bundle_local_qt_libs" android:value="-- %%BUNDLE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.bundled_in_lib_resource_id" android:resource="@array/bundled_in_lib"/>
<meta-data android:name="android.app.bundled_in_assets_resource_id" android:resource="@array/bundled_in_assets"/>
<!-- Run with local libs -->
<meta-data android:name="android.app.use_local_qt_libs" android:value="-- %%USE_LOCAL_QT_LIBS%% --"/>
<meta-data android:name="android.app.libs_prefix" android:value="/data/local/tmp/qt/"/>
<meta-data android:name="android.app.load_local_libs" android:value="-- %%INSERT_LOCAL_LIBS%% --"/>
<meta-data android:name="android.app.load_local_jars" android:value="-- %%INSERT_LOCAL_JARS%% --"/>
<meta-data android:name="android.app.static_init_classes" android:value="-- %%INSERT_INIT_CLASSES%% --"/>
<!-- Used to specify custom system library path to run with local system libs -->
<!-- <meta-data android:name="android.app.system_libs_prefix" android:value="/system/lib/"/> -->
<!-- Messages maps -->
<!-- Splash screen -->
<!-- meta-data android:name="android.app.splash_screen_drawable" android:resource="@drawable/logo"/ -->
<!-- meta-data android:name="android.app.splash_screen_sticky" android:value="true"/ -->
<!-- Splash screen -->
<!-- Background running -->
<!-- Warning: changing this value to true may cause unexpected crashes if the
application still try to draw after
"applicationStateChanged(Qt::ApplicationSuspended)"
signal is sent! -->
<meta-data android:name="android.app.background_running" android:value="false"/>
<!-- Background running -->
<!-- auto screen scale factor -->
<meta-data android:name="android.app.auto_screen_scale_factor" android:value="false"/>
<!-- auto screen scale factor -->
<!-- extract android style -->
<!-- available android:values :
* default - In most cases this will be the same as "full", but it can also be something else if needed, e.g., for compatibility reasons
* full - useful QWidget & Quick Controls 1 apps
* minimal - useful for Quick Controls 2 apps, it is much faster than "full"
* none - useful for apps that don't use any of the above Qt modules
-->
<meta-data android:name="android.app.extract_android_style" android:value="default"/>
<!-- extract android style -->
</activity>
<!-- For adding service(s) please check: https://wiki.qt.io/AndroidServices -->
</application>
<supports-screens android:anyDensity="true" android:normalScreens="true" android:smallScreens="true" android:largeScreens="true"/>
<!-- The following comment will be replaced upon deployment with default permissions based on the dependencies of the application.
Remove the comment if you do not require these default permissions. -->
<!-- %%INSERT_PERMISSIONS -->
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="19"/>
<uses-permission android:name="android.permission.INTERNET" />
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES -->
</manifest>

25
CMakeLists.txt Normal file
View File

@ -0,0 +1,25 @@
#
# This CMakeLists.txt goal is to be used with CMake's FetchContent function
# In your CMake script you should do :
#
# FetchContent_Declare(
# QtAndroidCMake
# GIT_REPOSITORY https://github.com/LaurentGomila/qt-android-cmake
# GIT_TAG master
# )
# FetchContent_MakeAvailable(QtAndroidCMake)
#
# Then you can call add_qt_android_apk when you want.
# This code snippet will download the repository if not already done and include the CMakeLists
# (that will include the script).
# Everything will be working out of the box.
#
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
include(${CMAKE_CURRENT_LIST_DIR}/AddQtAndroidApk.cmake)
set(QT_ANDROID_SOURCE_DIR ${QT_ANDROID_SOURCE_DIR} CACHE STRING "Source directory of AddQtAndroidApk.cmake")
set(QT_ANDROID_QT_ROOT ${QT_ANDROID_QT_ROOT} CACHE STRING "Qt SDK root folder")
set(QT_ANDROID_SDK_ROOT ${QT_ANDROID_SDK_ROOT} CACHE STRING "" FORCE)
set(QT_ANDROID_NDK_ROOT ${QT_ANDROID_NDK_ROOT} CACHE STRING "" FORCE)

61
build.gradle.in Normal file
View File

@ -0,0 +1,61 @@
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
}
}
repositories {
google()
jcenter()
}
apply plugin: 'com.android.application'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}
android {
/*******************************************************
* The following variables:
* - androidBuildToolsVersion,
* - androidCompileSdkVersion
* - qt5AndroidDir - holds the path to qt android files
* needed to build any Qt application
* on Android.
*
* are defined in gradle.properties file. This file is
* updated by QtCreator and androiddeployqt tools.
* Changing them manually might break the compilation!
*******************************************************/
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
res.srcDirs = [qt5AndroidDir + '/res', 'res']
resources.srcDirs = ['src']
renderscript.srcDirs = ['src']
assets.srcDirs = ['assets']
jniLibs.srcDirs = ['libs']
}
}
lintOptions {
abortOnError false
}
defaultConfig {
minSdkVersion 16
targetSdkVersion @QT_ANDROID_NATIVE_API_LEVEL@
}
}

View File

@ -5,7 +5,7 @@
"ndk": "@QT_ANDROID_NDK_ROOT@",
"sdkBuildToolsRevision": "@QT_ANDROID_SDK_BUILDTOOLS_REVISION@",
"toolchain-prefix": "@QT_ANDROID_TOOLCHAIN_PREFIX@",
"tool-prefix": "@QT_ANDROID_TOOLCHAIN_PREFIX@",
"tool-prefix": "@QT_ANDROID_TOOL_PREFIX@",
"toolchain-version": "@QT_ANDROID_TOOLCHAIN_VERSION@",
"ndk-host": "@ANDROID_NDK_HOST_SYSTEM_NAME@",
"target-architecture": "@ANDROID_ABI@",
@ -14,6 +14,7 @@
"android-app-name": "@QT_ANDROID_APP_NAME@",
"qml-root-path": "@CMAKE_SOURCE_DIR@",
"stdcpp-path": "@QT_ANDROID_STL_PATH@",
"useLLVM": @QT_ANDROID_USE_LLVM@,
@QT_ANDROID_APP_EXTRA_LIBS@
"android-package-source-directory": "@QT_ANDROID_APP_PACKAGE_SOURCE_ROOT@"
}

View File

@ -133,6 +133,8 @@ The path to a directory containing additional files for the package (custom mani
If you don't provide this argument, a default manifest is generated from the ```AndroidManifest.xml.in``` template and automatically used for building the APK.
If your PACKAGE_SOURCES directory contains a ```AndroidManifest.xml.in``` template file rather than a direct ```AndroidManifest.xml``` , it is automatically detected by the tool, configured and outputted as ```AndroidManifest.xml```, so that you can still use the provided CMake variables in your custom manifest.
Example:
```cmake
@ -189,6 +191,7 @@ add_qt_android_apk(my_app_apk my_app
INSTALL
)
```
## Troubleshooting
In case of