Say hello to Android multi arch build in one go

Multi arch build in one go is need to support the new .aab packaging format.

By default the users apps are built for all Android ABIs: arm64-v8a armeabi-v7a x86_64 x86
The user can pass ANDROID_ABIS to qmake to filter the ABIs during development,
e.g. qmake ANDROID_ABIS="arm64-v8a armeabi-v7a" will build only for arm ABIs.

[ChangeLog][Android] Android multi arch build in one go,
needed to support the new .aab packaging format.

Change-Id: I3a64caf9621c2a195863976a62a57cdf47e6e3b5
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
BogDan Vatra 2019-08-01 08:56:59 +03:00
parent 77de5a329c
commit 5bb178c479
31 changed files with 828 additions and 986 deletions

View File

@ -3,9 +3,6 @@ targetinfofile ~= s/pro$/target.txt/
win32 {
ext = .exe
} else:android {
file_prefix = lib
ext = .so
} else:wasm {
equals(WASM_OBJECT_FILES, 1): \
ext = .o

View File

@ -8,35 +8,102 @@ CONFIG += android_install unversioned_soname unversioned_libname
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/clang.conf)
include(../common/android-base-head.conf)
load(device_config)
# In early configure setup; nothing useful to be done here.
isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
NDK_ROOT = $$(ANDROID_NDK_ROOT)
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
BASENAME = $$basename(REVISION)
greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
}
}
ALL_ANDROID_ABIS = arm64-v8a armeabi-v7a x86_64 x86
CONFIG += $$ANDROID_PLATFORM
QMAKE_PCH_OUTPUT_EXT = .gch
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE
NDK_LLVM_PATH = $$NDK_ROOT/toolchains/llvm/prebuilt/$$NDK_HOST
QMAKE_CC = $$NDK_LLVM_PATH/bin/clang
QMAKE_CXX = $$NDK_LLVM_PATH/bin/clang++
QMAKE_LINK = $$QMAKE_CXX
# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md
QMAKE_CFLAGS_OPTIMIZE = -Oz
QMAKE_CFLAGS_OPTIMIZE_FULL = -Oz
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, x86): \
QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign
else: equals(ANDROID_TARGET_ARCH, x86_64): \
QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
QMAKE_CFLAGS_WARN_ON = -Wall -W
QMAKE_CFLAGS_WARN_OFF =
QMAKE_CFLAGS_SHLIB = -fPIC
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
QMAKE_CFLAGS_NEON = -mfpu=neon
QMAKE_CFLAGS += -fno-limit-debug-info
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS
ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/$$NDK_TOOLS_PREFIX/libc++_shared.so
QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_OPENGL =
QMAKE_INCDIR_POST =
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL =
QMAKE_LIBDIR_OPENGL =
ANDROID_USE_LLVM = true
QMAKE_CFLAGS_OPTIMIZE_SIZE = -Oz
QMAKE_LIBDIR_POST =
QMAKE_LFLAGS =
QMAKE_LIBS_PRIVATE =
ANDROID_CXX_STL_LIBS =
armeabi-v7a.sdk = armeabi-v7a
armeabi-v7a.target = armeabi-v7a
armeabi-v7a.dir_affix = armeabi-v7a
armeabi-v7a.CONFIG = armeabi-v7a
armeabi-v7a.deployment_identifier = armeabi-v7a
include(../common/android-base-tail.conf)
arm64-v8a.sdk = arm64-v8a
arm64-v8a.target = arm64-v8a
arm64-v8a.dir_affix = arm64-v8a
arm64-v8a.CONFIG = arm64-v8a
arm64-v8a.deployment_identifier = arm64-v8a
x86.sdk = x86
x86.target = x86
x86.dir_affix = x86
x86.CONFIG = x86
x86.deployment_identifier = x86
x86_64.sdk = x86_64
x86_64.target = x86_64
x86_64.dir_affix = x86_64
x86_64.CONFIG = x86_64
x86_64.deployment_identifier = x86_64
load(qt_config)

View File

@ -1,40 +0,0 @@
# qmake configuration for building with android-g++
MAKEFILE_GENERATOR = UNIX
QMAKE_PLATFORM = android
QMAKE_COMPILER = gcc
CONFIG += android_install unversioned_soname unversioned_libname plugin_with_soname android_deployment_settings
include(../common/linux.conf)
include(../common/gcc-base-unix.conf)
include(../common/android-base-head.conf)
QMAKE_CC = $${CROSS_COMPILE}gcc
QMAKE_CXX = $${CROSS_COMPILE}g++
QMAKE_LINK = $$QMAKE_CXX
QMAKE_CFLAGS = -D__ANDROID_API__=$$replace(ANDROID_PLATFORM, "android-", "")
ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/libs/$$ANDROID_TARGET_ARCH
ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libgnustl_shared.so
ANDROID_CXX_STL_LIBS = -lgnustl_shared -lgcc
ANDROID_USE_LLVM = false
exists($$NDK_ROOT/sysroot/usr/include): \
QMAKE_CFLAGS += --sysroot=$$NDK_ROOT/sysroot \
-isystem $$NDK_ROOT/sysroot/usr/include/$$NDK_TOOLS_PREFIX
else: QMAKE_CFLAGS += --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
QMAKE_CFLAGS += -isystem $$NDK_ROOT/sources/cxx-stl/gnu-libstdc++/$$NDK_TOOLCHAIN_VERSION/include \
-isystem $$ANDROID_SOURCES_CXX_STL_LIBDIR/include
equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
LIBGCC_PATH_FULL = $$system("$$QMAKE_CXX -mthumb-interwork -print-libgcc-file-name")
else: \
LIBGCC_PATH_FULL = $$system("$$QMAKE_CXX -print-libgcc-file-name")
ANDROID_SOURCES_CXX_STL_LIBDIR += $$dirname(LIBGCC_PATH_FULL)
QMAKE_LIBDIR_POST = $$ANDROID_SOURCES_CXX_STL_LIBDIR
QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH
equals(ANDROID_TARGET_ARCH, x86_64) QMAKE_LFLAGS += -L$$ANDROID_PLATFORM_ROOT_PATH/usr/lib64
include(../common/android-base-tail.conf)

View File

@ -1,177 +0,0 @@
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef QPLATFORMDEFS_H
#define QPLATFORMDEFS_H
// Get Qt defines/settings
#include "qglobal.h"
// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
// 1) need to reset default environment if _BSD_SOURCE is defined
// 2) need to specify POSIX thread interfaces explicitly in glibc 2.0
// 3) it seems older glibc need this to include the X/Open stuff
#include <unistd.h>
// We are hot - unistd.h should have turned on the specific APIs we requested
#include <features.h>
#include <pthread.h>
#include <dirent.h>
#include <fcntl.h>
#include <grp.h>
#include <pwd.h>
#include <signal.h>
#include <dlfcn.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/wait.h>
#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif
#ifdef QT_LARGEFILE_SUPPORT
#define QT_STATBUF struct stat64
#define QT_STATBUF4TSTAT struct stat64
#define QT_STAT ::stat64
#define QT_FSTAT ::fstat64
#define QT_LSTAT ::lstat64
#define QT_OPEN ::open64
#define QT_TRUNCATE ::truncate64
#define QT_FTRUNCATE ::ftruncate64
#define QT_LSEEK ::lseek64
#else
#define QT_STATBUF struct stat
#define QT_STATBUF4TSTAT struct stat
#define QT_STAT ::stat
#define QT_FSTAT ::fstat
#define QT_LSTAT ::lstat
#define QT_OPEN ::open
#define QT_TRUNCATE ::truncate
#define QT_FTRUNCATE ::ftruncate
#define QT_LSEEK ::lseek
#endif
#ifdef QT_LARGEFILE_SUPPORT
#define QT_FOPEN ::fopen64
#define QT_FSEEK ::fseeko64
#define QT_FTELL ::ftello64
#define QT_FGETPOS ::fgetpos64
#define QT_FSETPOS ::fsetpos64
#define QT_MMAP ::mmap64
#define QT_FPOS_T fpos64_t
#define QT_OFF_T off64_t
#else
#define QT_FOPEN ::fopen
#define QT_FSEEK ::fseek
#define QT_FTELL ::ftell
#define QT_FGETPOS ::fgetpos
#define QT_FSETPOS ::fsetpos
#define QT_MMAP ::mmap
#define QT_FPOS_T fpos_t
#define QT_OFF_T long
#endif
#define QT_STAT_REG S_IFREG
#define QT_STAT_DIR S_IFDIR
#define QT_STAT_MASK S_IFMT
#define QT_STAT_LNK S_IFLNK
#define QT_SOCKET_CONNECT ::connect
#define QT_SOCKET_BIND ::bind
#define QT_FILENO fileno
#define QT_CLOSE ::close
#define QT_READ ::read
#define QT_WRITE ::write
#define QT_ACCESS ::access
#define QT_GETCWD ::getcwd
#define QT_CHDIR ::chdir
#define QT_MKDIR ::mkdir
#define QT_RMDIR ::rmdir
#define QT_OPEN_LARGEFILE O_LARGEFILE
#define QT_OPEN_RDONLY O_RDONLY
#define QT_OPEN_WRONLY O_WRONLY
#define QT_OPEN_RDWR O_RDWR
#define QT_OPEN_CREAT O_CREAT
#define QT_OPEN_TRUNC O_TRUNC
#define QT_OPEN_APPEND O_APPEND
#define QT_OPEN_EXCL O_EXCL
// Directory iteration
#define QT_DIR DIR
#define QT_OPENDIR ::opendir
#define QT_CLOSEDIR ::closedir
#if defined(QT_LARGEFILE_SUPPORT) \
&& defined(QT_USE_XOPEN_LFS_EXTENSIONS) \
&& !defined(QT_NO_READDIR64)
#define QT_DIRENT struct dirent64
#define QT_READDIR ::readdir64
#define QT_READDIR_R ::readdir64_r
#else
#define QT_DIRENT struct dirent
#define QT_READDIR ::readdir
#define QT_READDIR_R ::readdir_r
#endif
#define QT_SOCKET_CONNECT ::connect
#define QT_SOCKET_BIND ::bind
#define QT_SIGNAL_RETTYPE void
#define QT_SIGNAL_ARGS int
#define QT_SIGNAL_IGNORE SIG_IGN
#define QT_SOCKLEN_T socklen_t
#if defined(_XOPEN_SOURCE) && (_XOPEN_SOURCE >= 500)
#define QT_SNPRINTF ::snprintf
#define QT_VSNPRINTF ::vsnprintf
#endif
#endif // QPLATFORMDEFS_H

View File

@ -1,71 +0,0 @@
load(device_config)
# In early configure setup; nothing useful to be done here.
isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
NDK_ROOT = $$(ANDROID_NDK_ROOT)
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
ANDROID_PLATFORM = $$(ANDROID_NDK_PLATFORM)
isEmpty(ANDROID_PLATFORM): ANDROID_PLATFORM = $$DEFAULT_ANDROID_PLATFORM
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
isEmpty(NDK_TOOLCHAIN_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
}
NDK_TOOLS_PREFIX = $$(ANDROID_NDK_TOOLS_PREFIX)
isEmpty(NDK_TOOLS_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLS_PREFIX = i686-linux-android
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLS_PREFIX = x86_64-linux-android
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLS_PREFIX = aarch64-linux-android
else: NDK_TOOLS_PREFIX = arm-linux-androideabi
}
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
equals(ANDROID_TARGET_ARCH, x86): ANDROID_ARCHITECTURE = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): ANDROID_ARCHITECTURE = x86_64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): ANDROID_ARCHITECTURE = arm64
else: ANDROID_ARCHITECTURE = arm
!equals(NDK_TOOLCHAIN_VERSION, 4.4.3): ANDROID_CXXSTL_SUFFIX = -$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN = $$NDK_TOOLCHAIN_PREFIX-$$NDK_TOOLCHAIN_VERSION
NDK_TOOLCHAIN_PATH = $$NDK_ROOT/toolchains/$$NDK_TOOLCHAIN/prebuilt/$$NDK_HOST
ANDROID_SDK_ROOT = $$(ANDROID_SDK_ROOT)
isEmpty(ANDROID_SDK_ROOT): ANDROID_SDK_ROOT = $$DEFAULT_ANDROID_SDK_ROOT
ANDROID_SDK_BUILD_TOOLS_REVISION = $$(ANDROID_BUILD_TOOLS_REVISION)
isEmpty(ANDROID_SDK_BUILD_TOOLS_REVISION) {
SDK_BUILD_TOOLS_REVISIONS = $$files($$ANDROID_SDK_ROOT/build-tools/*)
for (REVISION, SDK_BUILD_TOOLS_REVISIONS) {
BASENAME = $$basename(REVISION)
greaterThan(BASENAME, $$ANDROID_SDK_BUILD_TOOLS_REVISION): ANDROID_SDK_BUILD_TOOLS_REVISION = $$BASENAME
}
}
CONFIG += $$ANDROID_PLATFORM
ANDROID_PLATFORM_ROOT_PATH = $$NDK_ROOT/platforms/$$ANDROID_PLATFORM/arch-$$ANDROID_ARCHITECTURE/
CROSS_COMPILE = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-
QMAKE_PCH_OUTPUT_EXT = .gch
QMAKE_CFLAGS_PRECOMPILE = -x c-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CFLAGS_USE_PRECOMPILE = -include ${QMAKE_PCH_OUTPUT_BASE}
QMAKE_CXXFLAGS_PRECOMPILE = -x c++-header -c ${QMAKE_PCH_INPUT} -o ${QMAKE_PCH_OUTPUT}
QMAKE_CXXFLAGS_USE_PRECOMPILE = $$QMAKE_CFLAGS_USE_PRECOMPILE

View File

@ -1,82 +0,0 @@
# In early configure setup; nothing useful to be done here.
isEmpty(DEFAULT_ANDROID_NDK_ROOT): return()
# -fstack-protector-strong offers good protection against stack smashing attacks.
# It is (currently) enabled only on Android because we know for sure that Andoroid compilers supports it
QMAKE_CFLAGS += -fstack-protector-strong -DANDROID
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS += -march=armv7-a -mfloat-abi=softfp -mfpu=vfp
else: equals(ANDROID_TARGET_ARCH, armeabi): \
QMAKE_CFLAGS += -march=armv5te -mtune=xscale -msoft-float
QMAKE_CFLAGS_WARN_ON = -Wall -W
QMAKE_CFLAGS_WARN_OFF =
equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
CONFIG += optimize_size
QMAKE_CFLAGS_DEBUG = -g -marm -O0
QMAKE_CFLAGS_RELEASE += -mthumb
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
}
QMAKE_CFLAGS_SHLIB = -fPIC
QMAKE_CFLAGS_YACC = -Wno-unused -Wno-parentheses
QMAKE_CFLAGS_THREAD = -D_REENTRANT
QMAKE_CFLAGS_HIDESYMS = -fvisibility=hidden
QMAKE_CFLAGS_NEON = -mfpu=neon
QMAKE_CFLAGS_GNUC99 = -std=gnu99
QMAKE_CFLAGS_GNUC11 = -std=gnu11
QMAKE_CXXFLAGS_CXX11 = -std=c++11
QMAKE_CXXFLAGS_CXX14 = -std=c++14
QMAKE_CXXFLAGS_CXX1Z = -std=c++1z
QMAKE_CXXFLAGS_GNUCXX11 = -std=gnu++11
QMAKE_CXXFLAGS_GNUCXX14 = -std=gnu++14
QMAKE_CXXFLAGS_GNUCXX1Z = -std=gnu++1z
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE += $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO += $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS_DEBUG += $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_CXXFLAGS_HIDESYMS = $$QMAKE_CFLAGS_HIDESYMS -fvisibility-inlines-hidden
# modifications to linux.conf
QMAKE_AR = $${CROSS_COMPILE}ar cqs
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
QMAKE_STRIP =
#$${CROSS_COMPILE}strip
QMAKE_RANLIB = $${CROSS_COMPILE}ranlib
QMAKE_INCDIR_POST =
QMAKE_INCDIR_X11 =
QMAKE_LIBDIR_X11 =
QMAKE_INCDIR_OPENGL =
QMAKE_LIBDIR_OPENGL =
QMAKE_LINK_SHLIB = $$QMAKE_LINK
QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared
QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB
QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined
QMAKE_LFLAGS_RPATH = -Wl,-rpath=
QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link=
QMAKE_LIBS_PRIVATE = $$ANDROID_CXX_STL_LIBS -llog -lz -lm -ldl -lc
QMAKE_LIBS_X11 =
QMAKE_LIBS_THREAD =
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL =
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
!exists($$NDK_ROOT): error("You need to set the ANDROID_NDK_ROOT environment variable to point to your Android NDK.")
load(qt_config)

View File

@ -16,17 +16,22 @@ APK_PATH = $$shell_path($$OUT_PWD/android-build/$${TARGET}.apk)
}
QMAKE_EXTRA_TARGETS *= apk apk_install_target
contains(TEMPLATE, ".*app") {
!android_app {
!contains(TARGET, ".so"): TARGET = lib$${TARGET}.so
QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET)
build_pass {
contains(TEMPLATE, ".*app") {
!android_app {
!contains(TARGET, ".so") {
single_arch:TARGET = lib$${TARGET}.so
else:TARGET = lib$${TARGET}_$${QT_ARCH}.so
}
QMAKE_LFLAGS += -Wl,-soname,$$shell_quote($$TARGET)
android_install {
target.path=/libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
android_install {
target.path=/libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
}
}
} else: contains(TEMPLATE, "lib"):!static:!QTDIR_build:android_install {
target.path = /libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
}
} else: contains(TEMPLATE, "lib"):!static:!QTDIR_build:android_install {
target.path = /libs/$$ANDROID_TARGET_ARCH/
INSTALLS *= target
}

View File

@ -17,32 +17,21 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded {
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
FILE_CONTENT += " \"ndk\": $$emitString($$NDK_ROOT),"
equals(ANDROID_USE_LLVM, true) {
FILE_CONTENT += " \"toolchain-prefix\": \"llvm\","
FILE_CONTENT += " \"tool-prefix\": \"llvm\","
} else {
NDK_TOOLCHAIN_PREFIX = $$(ANDROID_NDK_TOOLCHAIN_PREFIX)
isEmpty(NDK_TOOLCHAIN_PREFIX) {
equals(ANDROID_TARGET_ARCH, x86): NDK_TOOLCHAIN_PREFIX = x86
else: equals(ANDROID_TARGET_ARCH, x86_64): NDK_TOOLCHAIN_PREFIX = x86_64
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
}
FILE_CONTENT += " \"toolchain-prefix\": $$emitString($$NDK_TOOLCHAIN_PREFIX),"
FILE_CONTENT += " \"tool-prefix\": $$emitString($$NDK_TOOLS_PREFIX),"
}
NDK_TOOLCHAIN_VERSION = $$(ANDROID_NDK_TOOLCHAIN_VERSION)
isEmpty(NDK_TOOLCHAIN_VERSION): NDK_TOOLCHAIN_VERSION = $$DEFAULT_ANDROID_NDK_TOOLCHAIN_VERSION
FILE_CONTENT += " \"toolchain-version\": $$emitString($$NDK_TOOLCHAIN_VERSION),"
FILE_CONTENT += " \"toolchain-prefix\": \"llvm\","
FILE_CONTENT += " \"tool-prefix\": \"llvm\","
NDK_HOST = $$(ANDROID_NDK_HOST)
isEmpty(NDK_HOST): NDK_HOST = $$DEFAULT_ANDROID_NDK_HOST
FILE_CONTENT += " \"ndk-host\": $$emitString($$NDK_HOST),"
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
FILE_CONTENT += " \"target-architecture\": $$emitString($$ANDROID_TARGET_ARCH),"
for (arch, ANDROID_ABIS) {
equals(arch, x86): libs_arch = i686-linux-android
else: equals(arch, x86_64): libs_arch = x86_64-linux-android
else: equals(arch, arm64-v8a): libs_arch = aarch64-linux-android
else: libs_arch = arm-linux-androideabi
ARCHS += "$$emitString($$arch):$$emitString($$libs_arch)"
}
FILE_CONTENT += " \"architectures\": {$$join(ARCHS,", ")},"
# Explicitly set qt dependencies of application for deployment
!isEmpty(ANDROID_DEPLOYMENT_DEPENDENCIES): \
@ -74,9 +63,8 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded {
QML_ROOT_PATH = $$_PRO_FILE_PWD_
FILE_CONTENT += " \"qml-root-path\": $$emitString($$QML_ROOT_PATH),"
FILE_CONTENT += " \"stdcpp-path\": $$emitString($$ANDROID_STDCPP_PATH),"
FILE_CONTENT += " \"useLLVM\": $$ANDROID_USE_LLVM,"
FILE_CONTENT += " \"application-binary\": $$emitString($$absolute_path($$DESTDIR, $$OUT_PWD)/$$TARGET)"
FILE_CONTENT += ""
FILE_CONTENT += " \"application-binary\": $$emitString($$TARGET)"
FILE_CONTENT += "}"
isEmpty(ANDROID_DEPLOYMENT_SETTINGS_FILE): ANDROID_DEPLOYMENT_SETTINGS_FILE = $$OUT_PWD/android-$$TARGET-deployment-settings.json

View File

@ -0,0 +1,76 @@
load(default_pre)
build_pass:armeabi-v7a {
QT_ARCH = armeabi-v7a
} else:build_pass:arm64-v8a {
QT_ARCH = arm64-v8a
} else:build_pass:x86 {
QT_ARCH = x86
} else:build_pass:x86_64 {
QT_ARCH = x86_64
} else {
# default architecture
QT_ARCH = arm64-v8a
}
DEFAULT_ANDROID_TARGET_ARCH=$${QT_ARCH}
ANDROID_TARGET_ARCH = $$(ANDROID_TARGET_ARCH)
isEmpty(ANDROID_TARGET_ARCH): ANDROID_TARGET_ARCH = $$DEFAULT_ANDROID_TARGET_ARCH
# Follow https://android.googlesource.com/platform/ndk/+/ndk-release-r20/docs/BuildSystemMaintainers.md
equals(ANDROID_TARGET_ARCH, armeabi-v7a): \
QMAKE_CFLAGS = -target armv7a-linux-androideabi$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, arm64-v8a): \
QMAKE_CFLAGS = -target aarch64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
else: equals(ANDROID_TARGET_ARCH, x86): \
QMAKE_CFLAGS = -target i686-linux-android$$replace(ANDROID_PLATFORM, "android-", "") -mstackrealign
else: equals(ANDROID_TARGET_ARCH, x86_64): \
QMAKE_CFLAGS = -target x86_64-linux-android$$replace(ANDROID_PLATFORM, "android-", "")
QMAKE_CFLAGS += -fno-limit-debug-info
QMAKE_LINK = $$QMAKE_CXX $$QMAKE_CFLAGS
ANDROID_STDCPP_PATH = $$NDK_LLVM_PATH/sysroot/usr/lib/
# -fstack-protector-strong offers good protection against stack smashing attacks.
# It is (currently) enabled only on Android because we know for sure that Android compilers supports it
QMAKE_CFLAGS += -fPIC -fstack-protector-strong -DANDROID
equals(ANDROID_TARGET_ARCH, armeabi-v7a) | equals(ANDROID_TARGET_ARCH, armeabi) {
CONFIG += optimize_size
QMAKE_CFLAGS_DEBUG = -g -marm -O0
QMAKE_CFLAGS_RELEASE += -mthumb
QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO += -mthumb
}
QMAKE_CXXFLAGS_RELEASE_WITH_DEBUGINFO = $$QMAKE_CFLAGS_RELEASE_WITH_DEBUGINFO
QMAKE_CXXFLAGS = $$QMAKE_CFLAGS
QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON
QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF
QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE
QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG
QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB
QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC
QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD
QMAKE_LIBS_EGL = -lEGL
QMAKE_LIBS_OPENGL_ES2 = -lGLESv2
# modifications to linux.conf
QMAKE_AR = $${CROSS_COMPILE}ar cqs
QMAKE_OBJCOPY = $${CROSS_COMPILE}objcopy
QMAKE_NM = $${CROSS_COMPILE}nm -P
QMAKE_STRIP =
#$${CROSS_COMPILE}strip
QMAKE_RANLIB = $${CROSS_COMPILE}ranlib
QMAKE_LINK_SHLIB = $$QMAKE_LINK
QMAKE_LFLAGS =
QMAKE_LIBS_PRIVATE = -llog -lz -lm -ldl -lc

View File

@ -0,0 +1,10 @@
load(resolve_config)
!host_build:!single_arch:!java:android {
isEmpty(ANDROID_ABIS): ANDROID_ABIS = $$ALL_ANDROID_ABIS
ALL_ABIS = $$join(ANDROID_ABIS, _and_)
CONFIG += $$ALL_ABIS build_all
addExclusiveBuildsProper($$ALL_ABIS, $$ANDROID_ABIS)
unset(ALL_ABIS)
}

View File

@ -1,4 +1,6 @@
load(qt_functions)
contains(TEMPLATE, subdirs) {
for(build, QMAKE_EXCLUSIVE_BUILDS) {
prepareRecursiveTarget($$build)

View File

@ -22,7 +22,11 @@ for(ever) {
!defined(QMAKE_LIBS_$$nu, var): \
error("Library '$$lower($$replace(nu, _, -))' is not defined.")
debug: \
android {
ABI_LIBS = $$eval(QMAKE_LIBS_$${nu}_$${QT_ARCH})
isEmpty(ABI_LIBS): ABI_LIBS = $$eval(QMAKE_LIBS_$${nu})
LIBS$${suffix} += $$ABI_LIBS
} else: debug: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_DEBUG) $$eval(QMAKE_LIBS_$$nu)
else: \
LIBS$${suffix} += $$eval(QMAKE_LIBS_$${nu}_RELEASE) $$eval(QMAKE_LIBS_$$nu)

View File

@ -16,7 +16,7 @@
ANDROID_DEPENDS_DIR = $$MODULE_BASE_OUTDIR/lib/
DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
!build_pass {
build_pass:!isEmpty(QT_ARCH): {
!isEmpty(MODULE_PLUGIN_TYPES) {
for(PLUGIN_TYPE, MODULE_PLUGIN_TYPES) {
ANDROID_BUNDLED_FILES += "plugins/$$PLUGIN_TYPE"
@ -46,6 +46,8 @@ DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
EXTENDS = $$section(LIB_FILE, ":", 1, 1)
!isEmpty(EXTENDS): EXTENDS = "extends=\"$$EXTENDS\""
LIB_FILE = $$section(LIB_FILE, ":", 0, 0)
LIB_FILE = $$replace(LIB_FILE,".so", "_$${QT_ARCH}.so")
!isEmpty(EXTENDS): EXTENDS = $$replace(EXTENDS,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<lib file=\"$$LIB_FILE\" $$EXTENDS />"
}
}
@ -54,12 +56,14 @@ DEPENDENCY_FILE = $$ANDROID_DEPENDS_DIR$$TARGET-android-dependencies.xml
for(REPLACEMENT, ANDROID_LIB_DEPENDENCY_REPLACEMENTS) {
REPLACEMENT_FILE = $$section(REPLACEMENT, ":", 0, 0)
LIB_FILE = $$section(REPLACEMENT, ":", 1, 1)
REPLACEMENT_FILE = $$replace(REPLACEMENT_FILE,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<lib file=\"$$LIB_FILE\" replaces=\"$$REPLACEMENT_FILE\" />"
}
}
!isEmpty(ANDROID_BUNDLED_FILES) {
for (BUNDLED_FILE, ANDROID_BUNDLED_FILES) {
BUNDLED_FILE = $$replace(BUNDLED_FILE,".so", "_$${QT_ARCH}.so")
FILE_CONTENT += "<bundled file=\"$$BUNDLED_FILE\" />"
}
}

View File

@ -560,7 +560,7 @@ defineTest(qtConfResolveLibs) {
} else {
paths += $$lp
}
} else: contains(l, "^-l.*") {
} else: !android: contains(l, "^-l.*") {
lib = $$replace(l, "^-l", )
lcan =
integrity:contains(lib, "^.*\\.a") {

View File

@ -1,7 +1,8 @@
defineReplace(qtPlatformTargetSuffix) {
suffix =
CONFIG(debug, debug|release) {
android: return($${suffix}_$${QT_ARCH})
else: CONFIG(debug, debug|release) {
!debug_and_release|build_pass {
mac: return($${suffix}_debug)
win32: return($${suffix}d)

View File

@ -29,19 +29,19 @@ DLLDESTDIR = $$MODULE_BASE_OUTDIR/bin
THE_TARGET = $$qt5LibraryTarget($$TARGET)
!build_pass {
MODULE = $$replace(TARGET, ^qt, )
MODULE ~= s,-,_,
MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
ucmodule = $$upper($$MODULE)
MODULE = $$replace(TARGET, ^qt, )
MODULE ~= s,-,_,
MODULE_PRI = $$MODULE_QMAKE_OUTDIR/mkspecs/modules/qt_ext_$${MODULE}.pri
ucmodule = $$upper($$MODULE)
win32|CONFIG(static, static|shared) {
prefix = $$QMAKE_PREFIX_STATICLIB
suffix = $$QMAKE_EXTENSION_STATICLIB
} else {
prefix = $$QMAKE_PREFIX_SHLIB
suffix = $$QMAKE_EXTENSION_SHLIB
}
win32|CONFIG(static, static|shared) {
prefix = $$QMAKE_PREFIX_STATICLIB
suffix = $$QMAKE_EXTENSION_STATICLIB
} else {
prefix = $$QMAKE_PREFIX_SHLIB
suffix = $$QMAKE_EXTENSION_SHLIB
}
!build_pass {
CC_USES =
LD_USES =
for (use, QMAKE_USE) {
@ -58,7 +58,9 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
"QMAKE_DEPENDS_$${ucmodule}_LD =$$join(LD_USES, " ", " ")" \
"QMAKE_INCDIR_$${ucmodule} = $$val_escape(MODULE_INCLUDEPATH)" \
"QMAKE_DEFINES_$${ucmodule} = $$val_escape(MODULE_DEFINES)"
debug_and_release {
android {
MODULE_PRI_CONT += "QMAKE_LIBS_$${ucmodule} ="
} else: debug_and_release {
win32: \
MODULE_DEBUG_LIBS = $$DESTDIR/$$prefix$${TARGET}d.$$suffix
else: darwin: \
@ -76,6 +78,11 @@ THE_TARGET = $$qt5LibraryTarget($$TARGET)
"QMAKE_LIBS_$${ucmodule} = $$val_escape(MODULE_LIBS)"
}
write_file($$MODULE_PRI, MODULE_PRI_CONT)|error()
} else: android {
ABI_TARGET = $$qt5LibraryTarget($$TARGET)
ABI_MODULE_LIBS = $$DESTDIR/$$prefix$${ABI_TARGET}.$$suffix
MODULE_PRI_CONT = "QMAKE_LIBS_$${ucmodule}_$${QT_ARCH} = $$val_escape(ABI_MODULE_LIBS)"
write_file($$MODULE_PRI, MODULE_PRI_CONT, append)|error()
}
TARGET = $$THE_TARGET

View File

@ -51,13 +51,12 @@ defineReplace(qtGetExportsForModule) {
return($$result)
}
defineReplace(qtExportLibsForModule) {
defineReplace(qtExportDepsForModule) {
result =
for (lib, QT.$${1}.libraries) {
NAME = $$upper($$lib)
vars = \
QMAKE_DEPENDS_$${NAME}_CC QMAKE_DEPENDS_$${NAME}_LD \
QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE \
QMAKE_DEFINES_$$NAME QMAKE_INCDIR_$$NAME
for (var, vars) {
expvar = $$var
@ -71,6 +70,24 @@ defineReplace(qtExportLibsForModule) {
return($$result)
}
defineReplace(qtExportLibsForModule) {
result =
for (lib, QT.$${1}.libraries) {
NAME = $$upper($$lib)
vars = \
QMAKE_LIBS_$$NAME QMAKE_LIBS_$${NAME}_DEBUG QMAKE_LIBS_$${NAME}_RELEASE
for (var, vars) {
expvar = $$var
expvar ~= s/^QMAKE_/QMAKE_EXPORT_/
defined($$expvar, var):equals($$expvar, -): next()
!defined($$expvar, var): expvar = $$var
defined($$expvar, var): \
result += "$$var$${2} = $$val_escape($$expvar)"
}
}
return($$result)
}
!build_pass {
# Create a module .pri file
@ -160,6 +177,7 @@ defineReplace(qtExportLibsForModule) {
"QT.$${MODULE}_private.module_config =$$join(module_build_type, " ", " ")" \
$$qtGetFeaturesForModule($${MODULE}_private) \
"" \
$$qtExportDepsForModule($${MODULE}_private) \
$$qtExportLibsForModule($${MODULE}_private)
write_file($$MODULE_PRIVATE_PRI, MODULE_PRIVATE_PRI_CONT)|error()
}
@ -220,7 +238,10 @@ defineReplace(qtExportLibsForModule) {
}
cache(QT_MODULES, transient)
} # !build_pass
} else:android:!no_private_module:!internal_module {
MODULE_PRIVATE_PRI_CONT = $$qtExportLibsForModule($${MODULE}_private, _$${QT_ARCH})
write_file($$MODULE_PRIVATE_PRI, MODULE_PRIVATE_PRI_CONT, append)|error()
}
# Schedule the regular .pri file for installation
CONFIG += qt_install_module

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,6 +1,7 @@
TARGET = QtAndroid
CONFIG += java
DESTDIR = $$[QT_INSTALL_PREFIX/get]/jar
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/

View File

@ -1,3 +1,5 @@
CONFIG += single_arch
CONFIG -= qt android_install
javaresources.files = \

View File

@ -1,5 +1,5 @@
/*
Copyright (c) 2016, BogDan Vatra <bogdan@kde.org>
Copyright (c) 2019, BogDan Vatra <bogdan@kde.org>
Contact: http://www.qt.io/licensing/
Commercial License Usage
@ -63,9 +63,12 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import dalvik.system.DexClassLoader;
@ -85,7 +88,6 @@ public abstract class QtLoader {
public static final String ENVIRONMENT_VARIABLES_KEY = "environment.variables";
public static final String APPLICATION_PARAMETERS_KEY = "application.parameters";
public static final String BUNDLED_LIBRARIES_KEY = "bundled.libraries";
public static final String QT_LIBS_RESOURCE_ID_KEY = "android.app.qt_libs_resource_id";
public static final String BUNDLED_IN_LIB_RESOURCE_ID_KEY = "android.app.bundled_in_lib_resource_id";
public static final String BUNDLED_IN_ASSETS_RESOURCE_ID_KEY = "android.app.bundled_in_assets_resource_id";
public static final String MAIN_LIBRARY_KEY = "main.library";
@ -153,7 +155,7 @@ public abstract class QtLoader {
// this repository is used to push a new release, and should be used to test your application.
// * unstable - unstable repository, DO NOT use this repository in production,
// this repository is used to push Qt snapshots.
public String[] m_qtLibs = null; // required qt libs
public ArrayList<String> m_qtLibs = null; // required qt libs
public int m_displayDensity = -1;
private ContextWrapper m_context;
protected ComponentInfo m_contextInfo;
@ -191,6 +193,36 @@ public abstract class QtLoader {
}
// Implement in subclass
private final List<String> supportedAbis = Arrays.asList(Build.SUPPORTED_ABIS);
private String preferredAbi = null;
private ArrayList<String> prefferedAbiLibs(String []libs)
{
HashMap<String, ArrayList<String>> abisLibs = new HashMap<>();
for (String lib : libs) {
String[] archLib = lib.split(";", 2);
if (preferredAbi != null && !archLib[0].equals(preferredAbi))
continue;
if (!abisLibs.containsKey(archLib[0]))
abisLibs.put(archLib[0], new ArrayList<String>());
abisLibs.get(archLib[0]).add(archLib[1]);
}
if (preferredAbi != null) {
if (abisLibs.containsKey(preferredAbi)) {
return abisLibs.get(preferredAbi);
}
return new ArrayList<String>();
}
for (String abi: supportedAbis) {
if (abisLibs.containsKey(abi)) {
preferredAbi = abi;
return abisLibs.get(abi);
}
}
return new ArrayList<String>();
}
// this function is used to load and start the loader
private void loadApplication(Bundle loaderParams)
@ -218,12 +250,14 @@ public abstract class QtLoader {
// add all bundled Qt libs to loader params
ArrayList<String> libs = new ArrayList<String>();
if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id"))
libs.addAll(Arrays.asList(m_context.getResources().getStringArray(m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id"))));
if (m_contextInfo.metaData.containsKey("android.app.bundled_libs_resource_id")) {
int resourceId = m_contextInfo.metaData.getInt("android.app.bundled_libs_resource_id");
libs.addAll(prefferedAbiLibs(m_context.getResources().getStringArray(resourceId)));
}
String libName = null;
if (m_contextInfo.metaData.containsKey("android.app.lib_name")) {
libName = m_contextInfo.metaData.getString("android.app.lib_name");
libName = m_contextInfo.metaData.getString("android.app.lib_name") + "_" + preferredAbi;
loaderParams.putString(MAIN_LIBRARY_KEY, libName); //main library contains main() function
}
@ -278,7 +312,7 @@ public abstract class QtLoader {
try {
if (m_service != null) {
Bundle parameters = new Bundle();
parameters.putStringArray(REQUIRED_MODULES_KEY, m_qtLibs);
parameters.putStringArray(REQUIRED_MODULES_KEY, (String[]) m_qtLibs.toArray());
parameters.putString(APPLICATION_TITLE_KEY, getTitle());
parameters.putInt(MINIMUM_MINISTRO_API_KEY, MINISTRO_API_LEVEL);
parameters.putInt(MINIMUM_QT_VERSION_KEY, QT_VERSION);
@ -464,7 +498,8 @@ public abstract class QtLoader {
// why can't we load the plugins directly from libs ?!?!
String key = BUNDLED_IN_LIB_RESOURCE_ID_KEY;
if (m_contextInfo.metaData.containsKey(key)) {
String[] list = m_context.getResources().getStringArray(m_contextInfo.metaData.getInt(key));
int resourceId = m_contextInfo.metaData.getInt(key);
ArrayList<String> list = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
for (String bundledImportBinary : list) {
String[] split = bundledImportBinary.split(":");
@ -603,7 +638,7 @@ public abstract class QtLoader {
if (m_contextInfo.metaData.containsKey("android.app.qt_libs_resource_id")) {
int resourceId = m_contextInfo.metaData.getInt("android.app.qt_libs_resource_id");
m_qtLibs = m_context.getResources().getStringArray(resourceId);
m_qtLibs = prefferedAbiLibs(m_context.getResources().getStringArray(resourceId));
}
if (m_contextInfo.metaData.containsKey("android.app.use_local_qt_libs")
@ -617,6 +652,7 @@ public abstract class QtLoader {
apkDeployFromSystem = true;
String libsDir = null;
String bundledLibsDir = null;
if (apkDeployFromSystem) {
String systemLibsPrefix = SYSTEM_LIB_PATH;
if (m_contextInfo.metaData.containsKey("android.app.system_libs_prefix")) {
@ -633,8 +669,11 @@ public abstract class QtLoader {
} else {
String nativeLibraryPrefix = m_context.getApplicationInfo().nativeLibraryDir + "/";
File nativeLibraryDir = new File(nativeLibraryPrefix);
if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0)
if (nativeLibraryDir.exists() && nativeLibraryDir.isDirectory() && nativeLibraryDir.list().length > 0) {
libsDir = nativeLibraryPrefix;
bundledLibsDir = nativeLibraryPrefix;
}
}
if (apkDeployFromSystem && libsDir == null)
@ -643,8 +682,8 @@ public abstract class QtLoader {
if (m_qtLibs != null) {
String libPrefix = libsDir + "lib";
for (int i = 0; i < m_qtLibs.length; i++)
libraryList.add(libPrefix + m_qtLibs[i] + ".so");
for (String lib : m_qtLibs)
libraryList.add(libPrefix + lib + ".so");
}
if (m_contextInfo.metaData.containsKey("android.app.bundle_local_qt_libs")
@ -654,22 +693,26 @@ public abstract class QtLoader {
String pluginsPrefix = dataPath + "qt-reserved-files/";
if (libsDir == null)
throw new Exception("");
throw new Exception("Invalid libsDir");
cleanOldCacheIfNecessary(dataPath, pluginsPrefix);
extractBundledPluginsAndImports(pluginsPrefix, libsDir);
if (m_contextInfo.metaData.containsKey(BUNDLED_IN_LIB_RESOURCE_ID_KEY)) {
String[] extraLibs = m_contextInfo.metaData.getString("android.app.load_local_libs").split(":");
for (String lib : extraLibs) {
if (!lib.isEmpty())
libraryList.add(pluginsPrefix + lib);
int resourceId = m_contextInfo.metaData.getInt("android.app.load_local_libs_resource_id");
for (String libs : prefferedAbiLibs(m_context.getResources().getStringArray(resourceId))) {
for (String lib : libs.split(":")) {
if (!lib.isEmpty())
libraryList.add(libsDir + lib);
}
}
}
ENVIRONMENT_VARIABLES += "\tQML2_IMPORT_PATH=" + pluginsPrefix + "/qml"
+ "\tQML_IMPORT_PATH=" + pluginsPrefix + "/imports"
+ "\tQT_PLUGIN_PATH=" + pluginsPrefix + "/plugins";
if (bundledLibsDir != null)
ENVIRONMENT_VARIABLES += "\tQT_BUNDLED_LIBS_PATH=" + bundledLibsDir;
}
Bundle loaderParams = new Bundle();

View File

@ -12,7 +12,7 @@
<supports-screens android:largeScreens="true" android:normalScreens="true" android:anyDensity="true" android:smallScreens="true"/>
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --">
<application android:hardwareAccelerated="true" android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="-- %%INSERT_APP_NAME%% --" android:extractNativeLibs="true">
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation|mcc|mnc|density"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="-- %%INSERT_APP_NAME%% --"
@ -36,10 +36,11 @@
<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_libs_resource_id" android:resource="@array/load_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 -->

View File

@ -5,7 +5,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
classpath 'com.android.tools.build:gradle:3.5.0'
}
}

View File

@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
<item>https://download.qt.io/ministro/android/qt5/qt-5.9</item>
<item>https://download.qt.io/ministro/android/qt5/qt-5.14</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
@ -12,12 +12,17 @@
</array>
<array name="qt_libs">
<!-- %%INSERT_QT_LIBS%% -->
<!-- %%INSERT_QT_LIBS%% -->
</array>
<array name="bundled_in_lib">
<!-- %%INSERT_BUNDLED_IN_LIB%% -->
</array>
<array name="load_local_libs">
<!-- %%INSERT_LOCAL_LIBS%% -->
</array>
<array name="bundled_in_assets">
<!-- %%INSERT_BUNDLED_IN_ASSETS%% -->
</array>

View File

@ -1,3 +1,5 @@
CONFIG += single_arch
CONFIG -= qt android_install
templates.files = \

View File

@ -12,6 +12,7 @@ CONFIG += qt_tracepoints
CONFIG += $$MODULE_CONFIG
DEFINES += $$MODULE_DEFINES
android: DEFINES += LIBS_SUFFIX='\\"_$${QT_ARCH}.so\\"'
DEFINES += QT_NO_USING_NAMESPACE QT_NO_FOREACH
msvc:equals(QT_ARCH, i386): QMAKE_LFLAGS += /BASE:0x67000000

View File

@ -100,6 +100,9 @@ QStringList QLibraryPrivate::suffixes_sys(const QString& fullVersion)
suffixes << QLatin1String(".so.%1").arg(fullVersion);
} else {
suffixes << QLatin1String(".so");
# ifdef Q_OS_ANDROID
suffixes << QStringLiteral(LIBS_SUFFIX);
# endif
}
#endif
# ifdef Q_OS_MAC
@ -226,7 +229,14 @@ bool QLibraryPrivate::load_sys()
} else {
attempt = path + prefixes.at(prefix) + name + suffixes.at(suffix);
}
pHnd = dlopen(QFile::encodeName(attempt), dlFlags);
#ifdef Q_OS_ANDROID
if (!pHnd) {
auto attemptFromBundle = attempt;
pHnd = dlopen(QFile::encodeName(attemptFromBundle.replace(QLatin1Char('/'), QLatin1Char('_'))), dlFlags);
}
#endif
if (!pHnd && fileName.startsWith(QLatin1Char('/')) && QFile::exists(attempt)) {
// We only want to continue if dlopen failed due to that the shared library did not exist.

View File

@ -82,7 +82,18 @@ qtConfig(png) {
}
# SIMD
SSSE3_SOURCES += image/qimage_ssse3.cpp
NEON_SOURCES += image/qimage_neon.cpp
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
!android {
SSSE3_SOURCES += image/qimage_ssse3.cpp
NEON_SOURCES += image/qimage_neon.cpp
MIPS_DSPR2_SOURCES += image/qimage_mips_dspr2.cpp
MIPS_DSPR2_ASM += image/qimage_mips_dspr2_asm.S
} else {
# see https://developer.android.com/ndk/guides/abis
arm64-v8a {
SOURCES += image/qimage_neon.cpp
}
x86 | x86_64 {
DEFINES += QT_COMPILER_SUPPORTS_SSE2 QT_COMPILER_SUPPORTS_SSE3 QT_COMPILER_SUPPORTS_SSSE3
SOURCES += image/qimage_ssse3.cpp
}
}

View File

@ -135,23 +135,41 @@ gcc:equals(QT_GCC_MAJOR_VERSION, 5) {
NO_PCH_SOURCES += painting/qdrawhelper.cpp
}
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
!android {
SSE2_SOURCES += painting/qdrawhelper_sse2.cpp
SSSE3_SOURCES += painting/qdrawhelper_ssse3.cpp
SSE4_1_SOURCES += painting/qdrawhelper_sse4.cpp \
painting/qimagescale_sse4.cpp
ARCH_HASWELL_SOURCES += painting/qdrawhelper_avx2.cpp
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
NEON_SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
NEON_HEADERS += painting/qdrawhelper_neon_p.h
}
!uikit:!win32:contains(QT_ARCH, "arm"): CONFIG += no_clang_integrated_as
!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
!android:!uikit:!win32:!integrity:!contains(QT_ARCH, "arm64") {
NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S
DEFINES += ENABLE_PIXMAN_DRAWHELPERS
}
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
MIPS_DSP_ASM += painting/qdrawhelper_mips_dsp_asm.S
MIPS_DSPR2_ASM += painting/qdrawhelper_mips_dspr2_asm.S
!android {
MIPS_DSP_SOURCES += painting/qdrawhelper_mips_dsp.cpp
MIPS_DSP_HEADERS += painting/qdrawhelper_mips_dsp_p.h painting/qt_mips_asm_dsp_p.h
MIPS_DSP_ASM += painting/qdrawhelper_mips_dsp_asm.S
MIPS_DSPR2_ASM += painting/qdrawhelper_mips_dspr2_asm.S
} else {
# see https://developer.android.com/ndk/guides/abis
x86 | x86_64 {
DEFINES += QT_COMPILER_SUPPORTS_SSE2 QT_COMPILER_SUPPORTS_SSE3 QT_COMPILER_SUPPORTS_SSSE3
SOURCES += painting/qdrawhelper_sse2.cpp painting/qdrawhelper_ssse3.cpp
}
x86_64 {
DEFINES += QT_COMPILER_SUPPORTS_SSE4_1 QT_COMPILER_SUPPORTS_SSE4_2
SOURCES += painting/qdrawhelper_sse4.cpp painting/qimagescale_sse4.cpp
}
arm64-v8a {
SOURCES += painting/qdrawhelper_neon.cpp painting/qimagescale_neon.cpp
HEADERS += painting/qdrawhelper_neon_p.h
}
}
include($$PWD/../../3rdparty/zlib_dependency.pri)

View File

@ -1,3 +1,5 @@
CONFIG += single_arch
TARGET = QtAndroidBearer
load(qt_build_paths)

File diff suppressed because it is too large Load Diff