diff options
-rw-r--r-- | mkspecs/android-clang/qmake.conf | 2 | ||||
-rw-r--r-- | mkspecs/android-g++/qmake.conf | 1 | ||||
-rw-r--r-- | mkspecs/features/android/android_deployment_settings.prf | 26 | ||||
-rw-r--r-- | src/tools/androiddeployqt/main.cpp | 97 |
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; |