diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-10 17:11:31 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2018-10-11 14:34:14 +0000 |
commit | 61ddc0685e0edc35b5fc39fdebacf08c64dbc991 (patch) | |
tree | 875f53f57e84b71040dac323812dc7cfdda85f49 | |
parent | 0934610293ca3e240cf392b99e4b3a9bf1a2570e (diff) |
Android support: Adapt to changes in newer revisions
Revision 17 dropped some architectures, revision 18 removed GCC.
We also missed some earlier changes to clang-related paths.
Change-Id: Ie2fa1891f7f4de28e18ea6caadce9eac964bb523
Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
9 files changed, 89 insertions, 31 deletions
diff --git a/doc/reference/modules/android-ndk-module.qdoc b/doc/reference/modules/android-ndk-module.qdoc index 23c70eec7..529f2fb4d 100644 --- a/doc/reference/modules/android-ndk-module.qdoc +++ b/doc/reference/modules/android-ndk-module.qdoc @@ -94,12 +94,12 @@ \list \li \c "c++_shared" \li \c "c++_static" - \li \c "gabi++_shared" - \li \c "gabi++_static" - \li \c "gnustl_shared" - \li \c "gnustl_static" - \li \c "stlport_shared" - \li \c "stlport_static" + \li \c "gabi++_shared" (until r17) + \li \c "gabi++_static" (until r17) + \li \c "gnustl_shared" (until r17) + \li \c "gnustl_static" (until r17) + \li \c "stlport_shared" (until r17) + \li \c "stlport_static" (until r17) \li \c "system" \endlist diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js index 4940f3ea1..7d1f7d6d0 100644 --- a/share/qbs/modules/Android/ndk/utils.js +++ b/share/qbs/modules/Android/ndk/utils.js @@ -61,7 +61,7 @@ function androidAbi(arch) { } } -function commonCompilerFlags(buildVariant, abi, armMode) { +function commonCompilerFlags(toolchain, buildVariant, abi, armMode) { var flags = ["-ffunction-sections", "-funwind-tables", "-Wa,--noexecstack", "-Werror=format-security"]; @@ -71,13 +71,17 @@ function commonCompilerFlags(buildVariant, abi, armMode) { flags.push("-fomit-frame-pointer"); if (abi === "arm64-v8a") { - flags.push("-fpic", "-fstack-protector", "-funswitch-loops", "-finline-limit=300"); + flags.push("-fpic", "-fstack-protector") + if (!toolchain.contains("clang")) + flags.push("-finline-limit=300", "-funswitch-loops"); if (buildVariant === "release") flags.push("-fstrict-aliasing"); } if (abi === "armeabi" || abi === "armeabi-v7a") { - flags.push("-fpic", "-fstack-protector", "-finline-limit=64"); + flags.push("-fpic", "-fstack-protector"); + if (!toolchain.contains("clang")) + flags.push("-finline-limit=64"); if (abi === "armeabi") flags.push("-mtune=xscale", "-msoft-float"); @@ -95,12 +99,17 @@ function commonCompilerFlags(buildVariant, abi, armMode) { flags.push("-fpic", "-finline-functions", "-fmessage-length=0", "-fno-inline-functions-called-once", "-fgcse-after-reload", "-frerun-cse-after-loop", "-frename-registers"); - if (buildVariant === "release") - flags.push("-funswitch-loops", "-finline-limit=300", "-fno-strict-aliasing"); + if (buildVariant === "release") { + flags.push("-fno-strict-aliasing"); + if (!toolchain.contains("clang")) + flags.push("-funswitch-loops", "-finline-limit=300"); + } } if (abi === "x86" || abi === "x86_64") { - flags.push("-fstack-protector", "-funswitch-loops", "-finline-limit=300"); + flags.push("-fstack-protector"); + if (!toolchain.contains("clang")) + flags.push("-funswitch-loops", "-finline-limit=300"); if (buildVariant === "release") flags.push("-fstrict-aliasing"); } @@ -114,3 +123,9 @@ function commonCompilerFlags(buildVariant, abi, armMode) { function commonLinkerFlags(abi) { return ["-z", "noexecstack", "-z", "relro", "-z", "now"]; } + +function getBinutilsPath(ndk, toolchainPrefix) { + if (["x86", "x86_64"].contains(ndk.abi)) + return ndk.abi + "-" + ndk.toolchainVersionNumber; + return toolchainPrefix + ndk.toolchainVersionNumber; +} diff --git a/share/qbs/modules/cpp/android-gcc.qbs b/share/qbs/modules/cpp/android-gcc.qbs index 057e77476..b5dc367ee 100644 --- a/share/qbs/modules/cpp/android-gcc.qbs +++ b/share/qbs/modules/cpp/android-gcc.qbs @@ -33,7 +33,9 @@ import qbs.File import qbs.FileInfo import qbs.ModUtils import qbs.TextFile +import qbs.Utilities import "../../modules/Android/ndk/utils.js" as NdkUtils +import 'gcc.js' as Gcc LinuxGCC { Depends { name: "Android.ndk" } @@ -44,11 +46,11 @@ LinuxGCC { rpaths: [rpathOrigin] property string toolchainDir: { - if (qbs.toolchain && qbs.toolchain.contains("clang")) - return "llvm-" + Android.ndk.toolchainVersionNumber; - if (["x86", "x86_64"].contains(Android.ndk.abi)) - return Android.ndk.abi + "-" + Android.ndk.toolchainVersionNumber; - return toolchainPrefix + Android.ndk.toolchainVersionNumber; + if (qbs.toolchain && qbs.toolchain.contains("clang")) { + return Utilities.versionCompare(Android.ndk.version, "10") <= 0 + ? "llvm-" + Android.ndk.toolchainVersionNumber : "llvm"; + } + return NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-") } property string cxxStlBaseDir: FileInfo.joinPaths(Android.ndk.ndkDir, "sources", "cxx-stl") @@ -118,8 +120,8 @@ LinuxGCC { enableExceptions: Android.ndk.appStl !== "system" enableRtti: Android.ndk.appStl !== "system" - commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.buildVariant, Android.ndk.abi, - Android.ndk.armMode) + commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.toolchain, qbs.buildVariant, + Android.ndk.abi, Android.ndk.armMode) linkerFlags: NdkUtils.commonLinkerFlags(Android.ndk.abi) @@ -163,7 +165,10 @@ LinuxGCC { includes.push(FileInfo.joinPaths(gnuStlBaseDir, "libs", Android.ndk.abi, "include")); includes.push(FileInfo.joinPaths(gnuStlBaseDir, "include", "backward")); } else if (Android.ndk.appStl.startsWith("c++_")) { - includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include")); + if (Utilities.versionCompare(Android.ndk.version, "13") >= 0) + includes.push(FileInfo.joinPaths(llvmStlBaseDir, "include")); + else + includes.push(FileInfo.joinPaths(llvmStlBaseDir, "libcxx", "include")); includes.push(FileInfo.joinPaths(llvmStlBaseDir + "abi", "libcxxabi", "include")); } return includes; @@ -176,6 +181,12 @@ LinuxGCC { } return list; } + binutilsPath: FileInfo.joinPaths(Android.ndk.ndkDir, "toolchains", + NdkUtils.getBinutilsPath(Android.ndk, toolchainTriple + "-"), + "prebuilt", Android.ndk.hostArch, "bin"); + binutilsPathPrefix: Gcc.pathPrefix(binutilsPath, toolchainTriple + "-") + driverFlags: qbs.toolchain.contains("clang") + ? ["-gcc-toolchain", FileInfo.path(binutilsPath)].concat(base || []) : base syslibroot: FileInfo.joinPaths(Android.ndk.ndkDir, "platforms", Android.ndk.platform, "arch-" + NdkUtils.abiNameToDirName(Android.ndk.abi)) diff --git a/src/app/qbs-setup-android/android-setup.cpp b/src/app/qbs-setup-android/android-setup.cpp index eb5ba92dd..d32cdbc05 100644 --- a/src/app/qbs-setup-android/android-setup.cpp +++ b/src/app/qbs-setup-android/android-setup.cpp @@ -46,6 +46,7 @@ #include <tools/settings.h> #include <tools/version.h> +#include <QtCore/qbytearraylist.h> #include <QtCore/qcoreapplication.h> #include <QtCore/qdir.h> #include <QtCore/qdiriterator.h> @@ -65,10 +66,7 @@ static QStringList expectedArchs() { return QStringList() << QStringLiteral("arm64") - << QStringLiteral("armv5te") << QStringLiteral("armv7a") - << QStringLiteral("mips") - << QStringLiteral("mips64") << QStringLiteral("x86") << QStringLiteral("x86_64"); } @@ -181,6 +179,29 @@ static QString maximumPlatform(const QString &platform1, const QString &platform return prefix + QString::number(std::max(value1, value2)); } +static QString getToolchainType(const QString &ndkDirPath) +{ + QFile sourceProperties(ndkDirPath + qls("/source.properties")); + if (!sourceProperties.open(QIODevice::ReadOnly)) + return QLatin1String("gcc"); // <= r10 + while (!sourceProperties.atEnd()) { + const QByteArray curLine = sourceProperties.readLine().simplified(); + static const QByteArray prefix = "Pkg.Revision = "; + if (!curLine.startsWith(prefix)) + continue; + qbs::Version ndkVersion = qbs::Version::fromString( + QString::fromLatin1(curLine.mid(prefix.size()))); + if (!ndkVersion.isValid()) { + qWarning("Unexpected format of NDK revision string in '%s'", + qPrintable(sourceProperties.fileName())); + return QLatin1String("clang"); + } + return qls(ndkVersion.majorVersion() >= 18 ? "clang" : "gcc"); + } + qWarning("No revision entry found in '%s'", qPrintable(sourceProperties.fileName())); + return QLatin1String("clang"); +} + static void setupNdk(qbs::Settings *settings, const QString &profileName, const QString &ndkDirPath, const QString &qtSdkDirPath) { @@ -194,7 +215,7 @@ static void setupNdk(qbs::Settings *settings, const QString &profileName, const mainProfile.setValue(qls("Android.ndk.ndkDir"), QDir::cleanPath(ndkDirPath)); mainProfile.setValue(qls("Android.sdk.ndkDir"), QDir::cleanPath(ndkDirPath)); } - mainProfile.setValue(qls("qbs.toolchain"), QStringList() << qls("gcc")); + mainProfile.setValue(qls("qbs.toolchainType"), getToolchainType(ndkDirPath)); const QStringList archs = expectedArchs(); const QtInfoPerArch infoPerArch = getQtAndroidInfo(qtSdkDirPath); const QStringList archsForProfile = infoPerArch.empty() diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs index 63256af54..eb63d4c20 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product1/product1.qbs @@ -7,8 +7,9 @@ Project { name: "p1lib1" files: ["src/main/jni/lib1.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" - qbs.architectures: !qbs.architecture ? ["mips", "x86"] : undefined + qbs.architectures: !qbs.architecture ? ["armv7a", "x86"] : undefined cpp.useRPaths: false } @@ -18,6 +19,7 @@ Project { name: "p1lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } diff --git a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs index a4f94f671..9b7f3eb54 100644 --- a/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-apks-per-project/product2/product2.qbs @@ -15,6 +15,7 @@ Project { name: "p2lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" } diff --git a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs index 499a5111b..6dd4e6bdb 100644 --- a/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs +++ b/tests/auto/blackbox/testdata-android/multiple-libs-per-apk/multiple-libs-per-apk.qbs @@ -7,6 +7,7 @@ Project { name: "lib1" files: ["src/main/jni/lib1.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } @@ -17,6 +18,7 @@ Project { name: "lib2" files: ["src/main/jni/lib2.cpp"] qbs.targetPlatform: "android" + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "stlport_shared" cpp.useRPaths: false } diff --git a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs index 4a447b2cc..3e0210554 100644 --- a/tests/auto/blackbox/testdata-android/teapot/teapot.qbs +++ b/tests/auto/blackbox/testdata-android/teapot/teapot.qbs @@ -50,6 +50,7 @@ Project { files: ["*.cpp", "*.h"].concat( !File.exists(ndkHelperProbe.dir + "/gl3stub.cpp") ? ["gl3stub.c"] : []) } + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "gnustl_shared" cpp.cxxLanguageVersion: "c++11" @@ -115,6 +116,7 @@ Project { FileTagger { patterns: ["*.inl"]; fileTags: ["hpp"] } + Properties { condition: qbs.toolchain.contains("clang"); Android.ndk.appStl: "c++_shared" } Android.ndk.appStl: "gnustl_shared" cpp.cxxLanguageVersion: "c++11" cpp.dynamicLibraries: ["log", "android", "EGL", "GLESv2"] diff --git a/tests/auto/blackbox/tst_blackboxandroid.cpp b/tests/auto/blackbox/tst_blackboxandroid.cpp index 7ad008bdf..c0ffa5620 100644 --- a/tests/auto/blackbox/tst_blackboxandroid.cpp +++ b/tests/auto/blackbox/tst_blackboxandroid.cpp @@ -179,6 +179,10 @@ void TestBlackboxAndroid::android_data() .replace("armv5te", "armeabi") .replace("arm64", "arm64-v8a"); }); + const bool usesClang = p.value(QLatin1String("qbs.toolchainType")).toString() == "clang"; + const auto cxxLibPath = [usesClang](const QByteArray &oldcxxLib) { + return "lib/${ARCH}/" + (usesClang ? "libc++_shared.so" : oldcxxLib); + }; auto expandArchs = [] (const QByteArrayList &archs, const QByteArrayList &lst) { const QByteArray &archPlaceHolder = "${ARCH}"; @@ -208,7 +212,7 @@ void TestBlackboxAndroid::android_data() "assets/Shaders/ShaderPlain.fsh", "assets/Shaders/VS_ShaderPlain.vsh", "lib/${ARCH}/gdbserver", - "lib/${ARCH}/libgnustl_shared.so", + cxxLibPath("libgnustl_shared.so"), "lib/${ARCH}/libTeapotNativeActivity.so", "res/layout/widgets.xml"})); QTest::newRow("no native") @@ -238,21 +242,21 @@ void TestBlackboxAndroid::android_data() "lib/${ARCH}/gdbserver", "lib/${ARCH}/liblib1.so", "lib/${ARCH}/liblib2.so", - "lib/${ARCH}/libstlport_shared.so"})); + cxxLibPath("libstlport_shared.so")})); QByteArrayList expectedFiles1 = (commonFiles - + expandArchs(QByteArrayList{"mips", "x86"}, { + + expandArchs(QByteArrayList{"armeabi-v7a", "x86"}, { "lib/${ARCH}/gdbserver", "lib/${ARCH}/libp1lib1.so", - "lib/${ARCH}/libstlport_shared.so"}) + cxxLibPath("libstlport_shared.so")}) + expandArchs(QByteArrayList{archs}, { "lib/${ARCH}/gdbserver", "lib/${ARCH}/libp1lib2.so", - "lib/${ARCH}/libstlport_shared.so"})).toSet().toList(); + cxxLibPath("libstlport_shared.so")})).toSet().toList(); QByteArrayList expectedFiles2 = commonFiles + expandArchs(archs, { "lib/${ARCH}/gdbserver", "lib/${ARCH}/libp2lib1.so", "lib/${ARCH}/libp2lib2.so", - "lib/${ARCH}/libstlport_shared.so"}); + cxxLibPath("libstlport_shared.so")}); expectedFiles2.removeOne("resources.arsc"); QTest::newRow("multiple apks") << "multiple-apks-per-project" |