aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt4
-rw-r--r--toolchain/Android.cmake183
-rw-r--r--toolchain/deployment-file.json.in15
3 files changed, 202 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b230bb28..6bccfbc5 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,6 +15,7 @@ if(BUILD_TESTING)
endif()
set(SHARE_INSTALL_DIR share)
+set(TOOLCHAIN_MODULES_INSTALL_DIR ${SHARE_INSTALL_DIR}/ECM/toolchain/)
set(MODULES_INSTALL_DIR ${SHARE_INSTALL_DIR}/ECM/modules/)
set(KDE_MODULES_INSTALL_DIR ${SHARE_INSTALL_DIR}/ECM/kde-modules/)
set(FIND_MODULES_INSTALL_DIR ${SHARE_INSTALL_DIR}/ECM/find-modules/)
@@ -33,6 +34,9 @@ install(FILES ${installKdeModuleFiles} DESTINATION ${KDE_MODULES_INSTALL_DIR})
file(GLOB installFindModuleFiles ${CMAKE_SOURCE_DIR}/find-modules/*[^~])
install(FILES ${installFindModuleFiles} DESTINATION ${FIND_MODULES_INSTALL_DIR})
+file(GLOB installToolchainModuleFiles ${CMAKE_SOURCE_DIR}/toolchain/*[^~])
+install(FILES ${installToolchainModuleFiles} DESTINATION ${TOOLCHAIN_MODULES_INSTALL_DIR})
+
include(CMakePackageConfigHelpers)
diff --git a/toolchain/Android.cmake b/toolchain/Android.cmake
new file mode 100644
index 00000000..8272ef9d
--- /dev/null
+++ b/toolchain/Android.cmake
@@ -0,0 +1,183 @@
+#.rst:
+# AndroidToolchain
+# -------------------
+#
+# Enable easy compilation of cmake projects on Android
+#
+# By using this android toolchain, the projects will be set up to compile the
+# specified project targeting an Android platform, depending on its input.
+# Furthermore, if desired, an APK can be directly generated by using the
+# androiddeployqt tool.
+#
+# Note: Requires CMake 3.1
+#
+# How to use it?
+# --------------
+# First of all, to make use of this toolchain file it's required to specify the
+# CMAKE_TOOLCHAIN_FILE variable pointing to AndroidToolchain.cmake.
+#
+# Then, there's many settings that we may want to specify under what circumstances
+# the project will be built. This will be done through environment variables:
+# - ANDROID_NDK: points to the NDK root path
+# - ANDROID_SDK_ROOT: points to the SDK root path
+#
+# Also there's some cache variables we can pass as well to narrow down the
+# preferred settings:
+# - ANDROID_NDK: Points to the NDK root, defaults to the environment variable
+# with the same name.
+# - ANDROID_SDK_ROOT: Points to the Android SDK root, defaults to the environment
+# variable with the same name.
+# - ANDROID_ARCHITECTURE: Specifies the used architecture, "arm" by default. See
+# arch-* directory.
+# - ANDROID_TOOLCHAIN: Specifies the toolchain to be used. Defaults to
+# "arm-linux-androideabi". See <ndk>/toolchains/ directory.
+# - ANDROID_ABI: Specifies the ABI to be used. Defaults to "armeabi-v7a". See
+# <ndk>/sources/cxx-stl/gnu-libstdc++/*/libs/ directories.
+# - ANDROID_GCC_VERSION: Specifies the GCC version. Defaults to "4.9".
+# - ANDROID_API_LEVEL: Specifies the API level to require. Defaults to "14". See
+# http://developer.android.com/guide/topics/manifest/uses-sdk-element.html
+# - ANDROID_SDK_BUILD_TOOLS_REVISION: Specifies the build tools version to be used.
+# Defaults to "21.1.1".
+#
+# Once we have the application built, we will want to generate an APK that we
+# can run on an Android device. To this end we've integrated androiddeployqt so
+# this can be done easily. This won't work with non-qt projects.
+# To make use of the APK generation, we'll define QTANDROID_EXPORTED_TARGET with
+# the target we want to have exported.
+# Additionally, we'll need to specify a ANDROID_APK_DIR with the base information
+# to set the project up. For more information see:
+# https://qt-project.org/doc/qt-5-snapshot/deployment-android.html
+#
+# Once set up, after building, make create-apk-<target_name> will process this
+# input and generate an apk that can be found inside the build directory:
+# ${CMAKE_BINARY_DIR}/<target_name>_build_apk/bin/QtApp-*.apk.
+#
+# =============================================================================
+# Copyright 2014 Aleix Pol i Gonzalez <aleixpol@kde.org>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file COPYING-CMAKE-SCRIPTS for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of extra-cmake-modules, substitute the full
+# License text for the above reference.)
+
+cmake_minimum_required(VERSION "3.1")
+
+#input
+set(ANDROID_NDK "$ENV{ANDROID_NDK}" CACHE path "Android NDK path")
+set(ANDROID_SDK_ROOT "$ENV{ANDROID_SDK_ROOT}" CACHE path "Android SDK path")
+set(ANDROID_ARCHITECTURE "arm" CACHE string "Used Architecture, related to the ABI and TOOLCHAIN")
+set(ANDROID_TOOLCHAIN "arm-linux-androideabi" CACHE string "Used SDK")
+set(ANDROID_ABI "armeabi-v7a" CACHE string "Used ABI")
+set(ANDROID_GCC_VERSION "4.9" CACHE string "Used GCC version" )
+set(ANDROID_API_LEVEL "14" CACHE string "Android API Level")
+set(ANDROID_SDK_BUILD_TOOLS_REVISION "21.1.1" CACHE string "Android API Level")
+
+set(_HOST "${CMAKE_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
+string(TOLOWER "${_HOST}" _HOST)
+
+get_filename_component(_CMAKE_ANDROID_DIR "${CMAKE_TOOLCHAIN_FILE}" PATH)
+
+cmake_policy(SET CMP0011 OLD)
+cmake_policy(SET CMP0017 OLD)
+
+set(CMAKE_SYSROOT
+ "${ANDROID_NDK}/platforms/android-${ANDROID_API_LEVEL}/arch-${ANDROID_ARCHITECTURE}")
+if(NOT EXISTS ${CMAKE_SYSROOT})
+ message(FATAL_ERROR "Couldn't find the Android NDK Root in ${CMAKE_SYSROOT}")
+endif()
+
+#actual code
+SET(CMAKE_SYSTEM_NAME Android)
+SET(CMAKE_SYSTEM_VERSION 1)
+
+set(ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN}-${ANDROID_GCC_VERSION}/prebuilt/${_HOST}/bin")
+set(ANDROID_LIBS_ROOT "${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/${ANDROID_GCC_VERSION}")
+
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM "${ANDROID_TOOLCHAIN_ROOT}")
+set(ANDROID_LIBRARIES_PATH
+ "${CMAKE_SYSROOT}/usr/lib")
+set(CMAKE_SYSTEM_LIBRARY_PATH
+ ${ANDROID_LIBRARIES_PATH}
+ "${ANDROID_LIBS_ROOT}/libs/${ANDROID_ABI}/"
+)
+set(CMAKE_FIND_LIBRARY_SUFFIXES ".so")
+set(CMAKE_FIND_LIBRARY_PREFIXES "lib")
+find_library(GNUSTL_SHARED gnustl_shared)
+if(NOT GNUSTL_SHARED)
+ message(FATAL_ERROR "you need gnustl_shared: ${CMAKE_SYSTEM_LIBRARY_PATH}")
+endif()
+include_directories(SYSTEM
+ "${CMAKE_SYSROOT}/usr/include"
+ "${ANDROID_LIBS_ROOT}/include/"
+ "${ANDROID_LIBS_ROOT}/libs/${ANDROID_ABI}/include"
+)
+
+link_directories(${CMAKE_SYSTEM_LIBRARY_PATH})
+
+set(CMAKE_C_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN}-gcc")
+set(CMAKE_CXX_COMPILER "${ANDROID_TOOLCHAIN_ROOT}/${ANDROID_TOOLCHAIN}-g++")
+
+SET(CMAKE_FIND_ROOT_PATH ${ANDROID_NDK})
+SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+
+set(CMAKE_EXE_LINKER_FLAGS "${GNUSTL_SHARED} -Wl,-rpath-link,${ANDROID_LIBRARIES_PATH} -llog -lz -lm -ldl -lc -lgcc" CACHE STRING "")
+set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "")
+set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "")
+
+#we want executables to be shared libraries, hooks will invoke the exported cmake function
+set(CMAKE_CXX_LINK_EXECUTABLE
+ "<CMAKE_CXX_COMPILER> <CMAKE_SHARED_LIBRARY_CXX_FLAGS> <LINK_FLAGS> <CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS> <SONAME_FLAG><TARGET_SONAME> -o <TARGET> <OBJECTS> <LINK_LIBRARIES>"
+)
+
+######### generation
+
+set(CREATEAPK_TARGET_NAME "create-apk-${QTANDROID_EXPORTED_TARGET}")
+if(DEFINED QTANDROID_EXPORTED_TARGET AND NOT TARGET ${CREATEAPK_TARGET_NAME})
+ if(NOT EXISTS "${ANDROID_APK_DIR}/AndroidManifest.xml")
+ message(FATAL_ERROR "Define an apk dir to initialize from using -DANDROID_APK_DIR=<path>. The specified directory must contain the AndroidManifest.xml file.")
+ endif()
+
+ function(EOFHook)
+ if(CMAKE_PARENT_LIST_FILE STREQUAL "")
+ generate_deployment_file()
+ endif()
+ endfunction()
+
+ function(generate_deployment_file)
+ get_property(_DEPENDENCIES TARGET ${QTANDROID_EXPORTED_TARGET} PROPERTY INTERFACE_LINK_LIBRARIES)
+ set(_DEPS_LIST)
+ foreach(_DEP IN LISTS _DEPENDENCIES)
+ if(NOT _DEP MATCHES "Qt5::.*")
+ get_property(_DEP_LOCATION TARGET ${_DEP} PROPERTY "LOCATION_${CMAKE_BUILD_TYPE}")
+ list(APPEND _DEPS_LIST ${_DEP_LOCATION})
+ endif()
+ endforeach()
+ string(REPLACE ";" "," _DEPS "${_DEPS_LIST}")
+ configure_file("${_CMAKE_ANDROID_DIR}/deployment-file.json.in" "${QTANDROID_EXPORTED_TARGET}-deployment.json")
+ endfunction()
+
+# Create the target that will eventually generate the apk
+ get_filename_component(QTDIR "${Qt5Core_DIR}/../../../" ABSOLUTE)
+ find_program(ANDROID_DEPLOY_QT androiddeployqt HINTS "${QTDIR}/bin")
+ set(EXPORT_DIR "${CMAKE_BINARY_DIR}/${QTANDROID_EXPORTED_TARGET}_build_apk/")
+ set(EXECUTABLE_DESTINATION_PATH "${EXPORT_DIR}/libs/${ANDROID_ABI}/lib${QTANDROID_EXPORTED_TARGET}.so")
+
+ add_custom_target(${CREATEAPK_TARGET_NAME}
+ COMMAND cmake -E echo "Generating $<TARGET_NAME:${QTANDROID_EXPORTED_TARGET}> with ${ANDROID_DEPLOY_QT}"
+ COMMAND cmake -E copy_directory "${ANDROID_APK_DIR}" "${EXPORT_DIR}"
+ COMMAND cmake -E copy "$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" "${EXECUTABLE_DESTINATION_PATH}"
+ COMMAND ${ANDROID_DEPLOY_QT} --input "${QTANDROID_EXPORTED_TARGET}-deployment.json" --output "${EXPORT_DIR}" --deployment bundled "\\$(ARGS)"
+ )
+
+ #we want to call the function after the project has been set up
+ variable_watch(CMAKE_PARENT_LIST_FILE EOFHook)
+else()
+ message(STATUS "You can export a target by specifying -DQTANDROID_EXPORTED_TARGET=<targetname>")
+endif()
diff --git a/toolchain/deployment-file.json.in b/toolchain/deployment-file.json.in
new file mode 100644
index 00000000..e662795a
--- /dev/null
+++ b/toolchain/deployment-file.json.in
@@ -0,0 +1,15 @@
+{
+ "qt": "@QTDIR@",
+ "sdk": "@ANDROID_SDK_ROOT@",
+ "ndk": "@ANDROID_NDK@",
+ "toolchain-prefix": "@ANDROID_TOOLCHAIN@",
+ "tool-prefix": "@ANDROID_TOOLCHAIN@",
+ "toolchain-version": "@ANDROID_GCC_VERSION@",
+ "ndk-host": "@_HOST@",
+ "target-architecture": "@ANDROID_ABI@",
+ "application-binary": "@EXECUTABLE_DESTINATION_PATH@",
+ "android-extra-libs": "@_DEPS@",
+ "android-extra-plugins": "@CMAKE_PREFIX_PATH@/share,@CMAKE_PREFIX_PATH@/lib/qml",
+ "android-package-source-directory": "@ANDROID_APK_DIR@",
+ "sdkBuildToolsRevision": "@ANDROID_SDK_BUILD_TOOLS_REVISION@"
+}