Skip to content

Commit

Permalink
Merge branch 'master' into pr/1
Browse files Browse the repository at this point in the history
  • Loading branch information
OlivierLDff committed Mar 17, 2019
2 parents 2425652 + 454e192 commit ee1b54f
Show file tree
Hide file tree
Showing 5 changed files with 267 additions and 29 deletions.
113 changes: 94 additions & 19 deletions AddQtAndroidApk.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ include(CMakeParseArguments)
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})
cmake_parse_arguments(ARG "INSTALL" "NAME;VERSION_NAME;VERSION_CODE;PACKAGE_NAME;PACKAGE_SOURCES;KEYSTORE_PASSWORD;EXTRA_QML" "DEPENDS;KEYSTORE;ANDROID_MANIFEST_IN_PATH;VERBOSE" ${ARGN})

# extract the full path of the source target binary
set(QT_ANDROID_APP_PATH "$<TARGET_FILE:${SOURCE_TARGET}>") # full file path to the app's main shared library
Expand Down Expand Up @@ -93,29 +93,58 @@ 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 "Detected 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()
IF(ARGS_EXTRA_QML)
SET(QT_ANDROID_QML_IMPORT_PATH ${ARGS_EXTRA_QML})
ENDIF()

SET(QT_ANDROID_APP_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${SOURCE_TARGET}-${ANDROID_ABI})
IF(ARG_ANDROID_MANIFEST_IN_PATH)
SET(QT_ANDROID_MANIFEST_IN_REAL_PATH ${ARG_ANDROID_MANIFEST_IN_PATH})
ELSE()
SET(QT_ANDROID_MANIFEST_IN_REAL_PATH ${QT_ANDROID_SOURCE_DIR}/AndroidManifest.xml.in)
ENDIF()
MESSAGE(STATUS "Used input AndroidManifest file QT_ANDROID_MANIFEST_IN_REAL_PATH : ${QT_ANDROID_MANIFEST_IN_REAL_PATH}")

# 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()

IF(ARG_VERSION_NAME)
set(QT_ANDROID_APP_VERSION ${ARG_VERSION_NAME})
if(NOT QT_ANDROID_APP_VERSION)
set(QT_ANDROID_APP_VERSION 1)
endif()
ELSE(ARG_VERSION_NAME)
# 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()
ENDIF(ARG_VERSION_NAME)

# define the application source package directory
if(ARG_PACKAGE_SOURCES)
IF(EXISTS ${ARG_PACKAGE_SOURCES}/AndroidManifest.xml)
SET(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT ${ARG_PACKAGE_SOURCES})
ELSE()
set(QT_ANDROID_MIX_SOURCE_DEPLOY ON)
set(QT_ANDROID_APP_PACKAGE_SOURCE_IN ${ARG_PACKAGE_SOURCES})

set(QT_ANDROID_APP_PACKAGE_SOURCE_ROOT "${CMAKE_CURRENT_BINARY_DIR}/package")
set(QT_ANDROID_MANIFEST_SOURCE_IN "${CMAKE_CURRENT_BINARY_DIR}/packagein")

configure_file(${QT_ANDROID_MANIFEST_IN_REAL_PATH} ${QT_ANDROID_MANIFEST_SOURCE_IN}/AndroidManifest.xml @ONLY)
ENDIF()
else()
# 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)
configure_file(${QT_ANDROID_MANIFEST_IN_REAL_PATH} ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}/AndroidManifest.xml @ONLY)
endif()

# newer NDK toolchains don't define ANDROID_STL_PREFIX anymore,
Expand All @@ -136,14 +165,19 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
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 "${ANDROID_NDK}/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 "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/libc++_shared.so")
else()
set(QT_ANDROID_STL_PATH)
IF(ANDROID_STL_STATIC_LIBRARIES)
MESSAGE(WARNING "ANDROID_STL_SHARED_LIBRARIES isn't defined, you might need to define ANDROID_STL (${ANDROID_STL}) to a shared stl library and not a static library")
ELSE(ANDROID_STL_STATIC_LIBRARIES)
MESSAGE(WARNING "ANDROID_STL_SHARED_LIBRARIES isn't defined, you might need to define ANDROID_STL (${ANDROID_STL}) to a shared stl library (for example c++_shared or gnustl_shared)")
ENDIF(ANDROID_STL_STATIC_LIBRARIES)
endif()

# set the list of dependant libraries
Expand Down Expand Up @@ -192,7 +226,7 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
endif()

# make sure that the output directory for the Android package exists
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libs/${ANDROID_ABI})
file(MAKE_DIRECTORY ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI})

# create the configuration file that will feed androiddeployqt
# 1. replace placeholder variables at generation time
Expand All @@ -202,6 +236,9 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
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)
Expand All @@ -221,15 +258,53 @@ macro(add_qt_android_apk TARGET SOURCE_TARGET)
set(TARGET_LEVEL_OPTIONS --android-platform android-${ANDROID_PLATFORM_LEVEL})
endif()

IF(QT_ANDROID_MIX_SOURCE_DEPLOY)
SET(QT_ANDROID_MIX_SOURCE_DEPLOY_COMMANDS

COMMAND ${CMAKE_COMMAND} -E remove_directory ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT} # Remove every file in our dependencies
COMMAND ${CMAKE_COMMAND} -E make_directory ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT} # Create the directory

COMMAND ${CMAKE_COMMAND} -E copy ${QT_ANDROID_MANIFEST_SOURCE_IN}/AndroidManifest.xml ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT}/AndroidManifest.xml
COMMAND ${CMAKE_COMMAND} -E copy_directory ${QT_ANDROID_APP_PACKAGE_SOURCE_IN} ${QT_ANDROID_APP_PACKAGE_SOURCE_ROOT} #will erase the first AndroidManifest if another one exist
)
ENDIF(QT_ANDROID_MIX_SOURCE_DEPLOY)

IF(${CMAKE_BUILD_TYPE} STREQUAL "Release" OR
${CMAKE_BUILD_TYPE} STREQUAL "MinSizeRel" OR
${CMAKE_BUILD_TYPE} STREQUAL "RelWithDebInfo")
SET(QT_ANDROID_BUILD_TYPE --release)
ELSEIF(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
SET(QT_ANDROID_BUILD_TYPE --debug)
ELSE()
MESSAGE(WARNING "CMAKE_BUILD_TYPE (${CMAKE_BUILD_TYPE}) isn't set to "
"Release | MinSizeRel | RelWithDebInfo | Debug. No --release or --debug will be specified to androiddeployqt")
ENDIF()

IF(ARG_VERBOSE)
SET(QT_ANDROID_VERBOSE --verbose)
ENDIF(ARG_VERBOSE)

# 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_MIX_SOURCE_DEPLOY_COMMANDS}

COMMAND ${CMAKE_COMMAND} -E remove_directory ${QT_ANDROID_APP_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 ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${CMAKE_COMMAND} -E echo package source in : ${QT_ANDROID_STL_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${QT_ANDROID_APP_PATH} ${QT_ANDROID_APP_BINARY_DIR}/libs/${ANDROID_ABI}
COMMAND ${QT_ANDROID_QT_ROOT}/bin/androiddeployqt
${QT_ANDROID_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()
66 changes: 57 additions & 9 deletions AndroidManifest.xml.in
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
<?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">
<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"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher">
<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"/>
Expand All @@ -21,15 +35,49 @@
<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"/>-->
<!-- 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>
61 changes: 61 additions & 0 deletions build.gradle.in
Original file line number Diff line number Diff line change
@@ -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'])
}

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@
}
}
2 changes: 1 addition & 1 deletion qtdeploy.json.in
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"application-binary": "@QT_ANDROID_APP_PATH@",
"android-package": "@QT_ANDROID_APP_PACKAGE_NAME@",
"android-app-name": "@QT_ANDROID_APP_NAME@",
"qml-root-path": "@CMAKE_SOURCE_DIR@",
"qml-root-path": "@QT_ANDROID_QML_IMPORT_PATH@",
"stdcpp-path": "@QT_ANDROID_STL_PATH@",
"useLLVM": @QT_ANDROID_USE_LLVM@,
@QT_ANDROID_APP_EXTRA_LIBS@
Expand Down
Loading

0 comments on commit ee1b54f

Please sign in to comment.