summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mkspecs/android-clang/qmake.conf2
-rw-r--r--mkspecs/android-g++/qmake.conf1
-rw-r--r--mkspecs/features/android/android_deployment_settings.prf26
-rw-r--r--src/tools/androiddeployqt/main.cpp97
4 files changed, 78 insertions, 48 deletions
diff --git a/mkspecs/android-clang/qmake.conf b/mkspecs/android-clang/qmake.conf
index 1f5e690329..a0a369bb44 100644
--- a/mkspecs/android-clang/qmake.conf
+++ b/mkspecs/android-clang/qmake.conf
@@ -41,6 +41,8 @@ ANDROID_SOURCES_CXX_STL_LIBDIR = $$NDK_ROOT/sources/cxx-stl/llvm-libc++/libs/$$A
ANDROID_STDCPP_PATH = $$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++_shared.so
+ANDROID_USE_LLVM = true
+
exists($$ANDROID_SOURCES_CXX_STL_LIBDIR/libc++.so): \
ANDROID_CXX_STL_LIBS = -lc++
else: \
diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf
index e72c802405..0cb3558f96 100644
--- a/mkspecs/android-g++/qmake.conf
+++ b/mkspecs/android-g++/qmake.conf
@@ -16,6 +16,7 @@ QMAKE_LINK = $$QMAKE_CXX
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 \
diff --git a/mkspecs/features/android/android_deployment_settings.prf b/mkspecs/features/android/android_deployment_settings.prf
index e6b2431f9a..0db3230ce7 100644
--- a/mkspecs/features/android/android_deployment_settings.prf
+++ b/mkspecs/features/android/android_deployment_settings.prf
@@ -17,17 +17,22 @@ contains(TEMPLATE, ".*app"):!build_pass:!android-embedded {
isEmpty(NDK_ROOT): NDK_ROOT = $$DEFAULT_ANDROID_NDK_ROOT
FILE_CONTENT += " \"ndk\": $$emitString($$NDK_ROOT),"
- 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, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android
- else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android
- else: equals(ANDROID_TARGET_ARCH, arm64-v8a): NDK_TOOLCHAIN_PREFIX = aarch64-linux-android
- else: NDK_TOOLCHAIN_PREFIX = arm-linux-androideabi
+ 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, mips): NDK_TOOLCHAIN_PREFIX = mipsel-linux-android
+ else: equals(ANDROID_TARGET_ARCH, mips64): NDK_TOOLCHAIN_PREFIX = mips64el-linux-android
+ 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),"
}
- 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
@@ -63,6 +68,7 @@ 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 += "}"
diff --git a/src/tools/androiddeployqt/main.cpp b/src/tools/androiddeployqt/main.cpp
index 11213872f3..587ae21e4f 100644
--- a/src/tools/androiddeployqt/main.cpp
+++ b/src/tools/androiddeployqt/main.cpp
@@ -157,6 +157,7 @@ struct Options
QString toolchainVersion;
QString toolchainPrefix;
QString toolPrefix;
+ bool useLLVM = false;
QString ndkHost;
// Package information
@@ -809,6 +810,11 @@ bool readInputFile(Options *options)
}
{
+ const QJsonValue value = jsonObject.value(QStringLiteral("useLLVM"));
+ options->useLLVM = value.toBool(false);
+ }
+
+ {
const QJsonValue toolchainPrefix = jsonObject.value(QStringLiteral("toolchain-prefix"));
if (toolchainPrefix.isUndefined()) {
fprintf(stderr, "No toolchain prefix defined in json file.\n");
@@ -827,7 +833,7 @@ bool readInputFile(Options *options)
}
}
- {
+ if (!options->useLLVM) {
const QJsonValue toolchainVersion = jsonObject.value(QStringLiteral("toolchain-version"));
if (toolchainVersion.isUndefined()) {
fprintf(stderr, "No toolchain version defined in json file.\n");
@@ -863,15 +869,17 @@ bool readInputFile(Options *options)
{
const QJsonValue stdcppPath = jsonObject.value(QStringLiteral("stdcpp-path"));
- if (!stdcppPath.isUndefined()) {
- options->stdCppPath = stdcppPath.toString();
- auto name = QFileInfo(options->stdCppPath).baseName();
- if (!name.startsWith(QLatin1String("lib"))) {
- fprintf(stderr, "Invalid STD C++ library name.\n");
- return false;
- }
- options->stdCppName = name.mid(3);
+ if (stdcppPath.isUndefined()) {
+ fprintf(stderr, "No stdcpp-path defined in json file.\n");
+ return false;
+ }
+ options->stdCppPath = stdcppPath.toString();
+ auto name = QFileInfo(options->stdCppPath).baseName();
+ if (!name.startsWith(QLatin1String("lib"))) {
+ fprintf(stderr, "Invalid STD C++ library name.\n");
+ return false;
}
+ options->stdCppName = name.mid(3);
}
{
@@ -1546,14 +1554,16 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
{
QString readElf = options.ndkPath
+ QLatin1String("/toolchains/")
- + options.toolchainPrefix
- + QLatin1Char('-')
- + options.toolchainVersion
- + QLatin1String("/prebuilt/")
+ + options.toolchainPrefix;
+
+ if (!options.useLLVM)
+ readElf += QLatin1Char('-') + options.toolchainVersion;
+
+ readElf += QLatin1String("/prebuilt/")
+ options.ndkHost
+ QLatin1String("/bin/")
- + options.toolPrefix
- + QLatin1String("-readelf");
+ + options.toolPrefix +
+ (options.useLLVM ? QLatin1String("-readobj") : QLatin1String("-readelf"));
#if defined(Q_OS_WIN32)
readElf += QLatin1String(".exe");
#endif
@@ -1563,27 +1573,40 @@ QStringList getQtLibsFromElf(const Options &options, const QString &fileName)
return QStringList();
}
- readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf)).arg(shellQuote(fileName));
+ if (options.useLLVM)
+ readElf = QString::fromLatin1("%1 -needed-libs %2").arg(shellQuote(readElf), shellQuote(fileName));
+ else
+ readElf = QString::fromLatin1("%1 -d -W %2").arg(shellQuote(readElf), shellQuote(fileName));
FILE *readElfCommand = openProcess(readElf);
- if (readElfCommand == 0) {
+ if (!readElfCommand) {
fprintf(stderr, "Cannot execute command %s", qPrintable(readElf));
return QStringList();
}
QStringList ret;
+ bool readLibs = false;
char buffer[512];
while (fgets(buffer, sizeof(buffer), readElfCommand) != 0) {
QByteArray line = QByteArray::fromRawData(buffer, qstrlen(buffer));
- if (line.contains("(NEEDED)") && line.contains("Shared library:") ) {
- const int pos = line.lastIndexOf('[') + 1;
- QString libraryName = QLatin1String("lib/") + QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
- if (QFile::exists(absoluteFilePath(&options, libraryName))) {
- ret += libraryName;
+ QString library;
+ if (options.useLLVM) {
+ line = line.trimmed();
+ if (!readLibs) {
+ readLibs = line.startsWith("NeededLibraries");
+ continue;
}
-
+ if (!line.startsWith("lib"))
+ continue;
+ library = QString::fromLatin1(line);
+ } else if (line.contains("(NEEDED)") && line.contains("Shared library:")) {
+ const int pos = line.lastIndexOf('[') + 1;
+ library = QString::fromLatin1(line.mid(pos, line.length() - pos - 2));
}
+ QString libraryName = QLatin1String("lib/") + library;
+ if (QFile::exists(absoluteFilePath(&options, libraryName)))
+ ret += libraryName;
}
pclose(readElfCommand);
@@ -1837,10 +1860,12 @@ bool stripFile(const Options &options, const QString &fileName)
{
QString strip = options.ndkPath
+ QLatin1String("/toolchains/")
- + options.toolchainPrefix
- + QLatin1Char('-')
- + options.toolchainVersion
- + QLatin1String("/prebuilt/")
+ + options.toolchainPrefix;
+
+ if (!options.useLLVM)
+ strip += QLatin1Char('-') + options.toolchainVersion;
+
+ strip += QLatin1String("/prebuilt/")
+ options.ndkHost
+ QLatin1String("/bin/")
+ options.toolPrefix
@@ -1854,7 +1879,10 @@ bool stripFile(const Options &options, const QString &fileName)
return false;
}
- strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip)).arg(shellQuote(fileName));
+ if (options.useLLVM)
+ strip = QString::fromLatin1("%1 -strip-all -strip-all-gnu %2").arg(shellQuote(strip), shellQuote(fileName));
+ else
+ strip = QString::fromLatin1("%1 %2").arg(shellQuote(strip), shellQuote(fileName));
FILE *stripCommand = openProcess(strip);
if (stripCommand == 0) {
@@ -2423,22 +2451,15 @@ bool copyStdCpp(Options *options)
if (options->verbose)
fprintf(stdout, "Copying STL library\n");
- QString filePath = !options->stdCppPath.isEmpty() ? options->stdCppPath
- : options->ndkPath
- + QLatin1String("/sources/cxx-stl/gnu-libstdc++/")
- + options->toolchainVersion
- + QLatin1String("/libs/")
- + options->architecture
- + QLatin1String("/libgnustl_shared.so");
- if (!QFile::exists(filePath)) {
- fprintf(stderr, "STL library does not exist at %s\n", qPrintable(filePath));
+ if (!QFile::exists(options->stdCppPath)) {
+ fprintf(stderr, "STL library does not exist at %s\n", qPrintable(options->stdCppPath));
return false;
}
const QString destinationDirectory = options->outputDirectory
+ QLatin1String("/libs/") + options->architecture;
- if (!copyFileIfNewer(filePath, destinationDirectory + QLatin1String("/lib")
+ if (!copyFileIfNewer(options->stdCppPath, destinationDirectory + QLatin1String("/lib")
+ options->stdCppName + QLatin1String(".so"),
options->verbose)) {
return false;