2015-02-12 13:52:33 +01:00
cmake_minimum_required ( VERSION 3.0 )
cmake_policy ( SET CMP0026 OLD ) # allow use of the LOCATION target property
# store the current source directory for future use
set ( QT_ANDROID_SOURCE_DIR ${ CMAKE_CURRENT_LIST_DIR } )
# check the JAVA_HOME environment variable
# (I couldn't find a way to set it from this script, it has to be defined outside)
set ( JAVA_HOME $ENV{ JAVA_HOME } )
if ( NOT JAVA_HOME )
message ( FATAL_ERROR "The JAVA_HOME environment variable is not set. Please set it to the root directory of the JDK." )
endif ( )
# make sure that the Android toolchain is used
if ( NOT ANDROID )
message ( FATAL_ERROR "Trying to use the CMake Android package without the Android toolchain. Please use the provided toolchain (toolchain/android.toolchain.cmake)" )
endif ( )
# find the Qt root directory
if ( NOT Qt5Core_DIR )
find_package ( Qt5Core REQUIRED )
endif ( )
get_filename_component ( QT_ANDROID_QT_ROOT "${Qt5Core_DIR}/../../.." ABSOLUTE )
message ( STATUS "Found Qt for Android: ${QT_ANDROID_QT_ROOT}" )
# find the Android SDK
if ( NOT QT_ANDROID_SDK_ROOT )
set ( QT_ANDROID_SDK_ROOT $ENV{ ANDROID_SDK } )
if ( NOT QT_ANDROID_SDK_ROOT )
message ( FATAL_ERROR "Could not find the Android SDK. Please set either the ANDROID_SDK environment variable, or the QT_ANDROID_SDK_ROOT CMake variable to the root directory of the Android SDK" )
endif ( )
endif ( )
string ( REPLACE "\\" "/" QT_ANDROID_SDK_ROOT ${ QT_ANDROID_SDK_ROOT } ) # androiddeployqt doesn't like backslashes in paths
message ( STATUS "Found Android SDK: ${QT_ANDROID_SDK_ROOT}" )
# find the Android NDK
if ( NOT QT_ANDROID_NDK_ROOT )
set ( QT_ANDROID_NDK_ROOT $ENV{ ANDROID_NDK } )
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" )
endif ( )
endif ( )
endif ( )
string ( REPLACE "\\" "/" QT_ANDROID_NDK_ROOT ${ QT_ANDROID_NDK_ROOT } ) # androiddeployqt doesn't like backslashes in paths
message ( STATUS "Found Android NDK: ${QT_ANDROID_NDK_ROOT}" )
include ( CMakeParseArguments )
# define a macro to create an Android APK target
#
# example:
# add_qt_android_apk(my_app_apk my_app
# NAME "My App"
2016-08-16 15:09:56 +02:00
# VERSION_CODE 12
2015-02-12 13:52:33 +01:00
# PACKAGE_NAME "org.mycompany.myapp"
# PACKAGE_SOURCES ${CMAKE_CURRENT_LIST_DIR}/my-android-sources
2017-02-06 13:12:15 +01:00
# BUILDTOOLS_REVISION "23.0.3"
2015-02-12 13:52:33 +01:00
# KEYSTORE ${CMAKE_CURRENT_LIST_DIR}/mykey.keystore myalias
# KEYSTORE_PASSWORD xxxx
# DEPENDS a_linked_target "path/to/a_linked_library.so" ...
# INSTALL
#)
#
macro ( add_qt_android_apk TARGET SOURCE_TARGET )
# parse the macro arguments
2017-02-06 12:11:59 +01:00
cmake_parse_arguments ( ARG "INSTALL" "NAME;VERSION_CODE;PACKAGE_NAME;PACKAGE_SOURCES;KEYSTORE_PASSWORD;BUILDTOOLS_REVISION" "DEPENDS;KEYSTORE" ${ ARGN } )
2015-02-12 13:52:33 +01:00
# 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 ( )
# define the application name
if ( ARG_NAME )
set ( QT_ANDROID_APP_NAME ${ ARG_NAME } )
else ( )
set ( QT_ANDROID_APP_NAME ${ SOURCE_TARGET } )
endif ( )
# define the application package name
if ( ARG_PACKAGE_NAME )
set ( QT_ANDROID_APP_PACKAGE_NAME ${ ARG_PACKAGE_NAME } )
else ( )
set ( QT_ANDROID_APP_PACKAGE_NAME org.qtproject. ${ SOURCE_TARGET } )
endif ( )
2017-02-06 12:11:59 +01:00
# set the Android SDK build-tools revision
if ( ARG_BUILDTOOLS_REVISION )
set ( QT_ANDROID_SDK_BUILDTOOLS_REVISION ${ ARG_BUILDTOOLS_REVISION } )
else ( )
set ( QT_ANDROID_SDK_BUILDTOOLS_REVISION "" )
endif ( )
2015-02-12 13:52:33 +01:00
# define the application source package directory
if ( ARG_PACKAGE_SOURCES )
set ( QT_ANDROID_APP_PACKAGE_SOURCE_ROOT ${ ARG_PACKAGE_SOURCES } )
else ( )
2016-08-16 15:09:56 +02:00
# 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 ( )
2015-02-12 13:52:33 +01:00
2016-08-16 15:09:56 +02:00
# 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 )
set ( QT_ANDROID_APP_VERSION ${ QT_ANDROID_APP_VERSION_CODE } )
endif ( )
2015-02-12 13:52:33 +01:00
# create a subdirectory for the extra package sources
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 )
endif ( )
# set the list of dependant libraries
if ( ARG_DEPENDS )
foreach ( LIB ${ ARG_DEPENDS } )
if ( TARGET ${ LIB } )
2015-02-12 15:34:57 +01:00
# item is a CMake target, extract the library path
2015-02-12 13:52:33 +01:00
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 ( )
2015-02-12 15:34:57 +01:00
set ( LIB ${ LIB_PATH } )
2015-02-12 13:52:33 +01:00
endif ( )
2015-02-12 15:34:57 +01:00
if ( EXTRA_LIBS )
set ( EXTRA_LIBS "${EXTRA_LIBS},${LIB}" )
else ( )
set ( EXTRA_LIBS "${LIB}" )
endif ( )
2015-02-12 13:52:33 +01:00
endforeach ( )
2015-02-12 15:34:57 +01:00
set ( QT_ANDROID_APP_EXTRA_LIBS "\" android-extra-libs\ ": \" ${ EXTRA_LIBS } \",")
2015-02-12 13:52:33 +01:00
endif ( )
# make sure that the output directory for the Android package exists
file ( MAKE_DIRECTORY ${ CMAKE_CURRENT_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 )
# check if the apk must be signed
if ( ARG_KEYSTORE )
2015-05-12 10:15:12 +02:00
set ( SIGN_OPTIONS --release --sign ${ ARG_KEYSTORE } --tsa http://timestamp.digicert.com )
2015-02-12 13:52:33 +01:00
if ( ARG_KEYSTORE_PASSWORD )
set ( SIGN_OPTIONS ${ SIGN_OPTIONS } --storepass ${ ARG_KEYSTORE_PASSWORD } )
endif ( )
endif ( )
2015-11-06 11:22:46 +01:00
# check if the apk must be installed to the device
2015-02-12 13:52:33 +01:00
if ( ARG_INSTALL )
2015-11-06 11:22:46 +01:00
set ( INSTALL_OPTIONS --reinstall )
2015-02-12 13:52:33 +01:00
endif ( )
2017-05-19 12:08:45 +02:00
# specify the Android API level
if ( ANDROID_NATIVE_API_LEVEL )
2017-05-19 14:10:04 +02:00
set ( TARGET_LEVEL_OPTIONS --android-platform android- ${ ANDROID_NATIVE_API_LEVEL } )
2017-05-19 12:08:45 +02:00
endif ( )
2015-02-12 13:52:33 +01:00
# create a custom command that will run the androiddeployqt utility to prepare the Android package
add_custom_target (
$ { T A R G E T }
A L L
2017-05-19 14:58:12 +02:00
D E P E N D S $ { S O U R C E _ T A R G E T }
C O M M A N D $ { C M A K E _ C O M M A N D } - E r e m o v e _ d i r e c t o r y $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / l i b s / $ { A N D R O I D _ A B I } # it seems that recompiled libraries are not copied if we don't remove them first
C O M M A N D $ { C M A K E _ C O M M A N D } - E m a k e _ d i r e c t o r y $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / l i b s / $ { A N D R O I D _ A B I }
C O M M A N D $ { C M A K E _ C O M M A N D } - E c o p y $ { Q T _ A N D R O I D _ A P P _ P A T H } $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / l i b s / $ { A N D R O I D _ A B I }
C O M M A N D $ { Q T _ A N D R O I D _ Q T _ R O O T } / b i n / a n d r o i d d e p l o y q t - - v e r b o s e - - o u t p u t $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } - - i n p u t $ { C M A K E _ C U R R E N T _ B I N A R Y _ D I R } / q t d e p l o y . j s o n - - g r a d l e $ { T A R G E T _ L E V E L _ O P T I O N S } $ { I N S T A L L _ O P T I O N S } $ { S I G N _ O P T I O N S }
2015-02-12 13:52:33 +01:00
)
endmacro ( )