summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJake Petroules <jake.petroules@petroules.com>2015-07-14 22:10:33 -0700
committerJake Petroules <jake.petroules@petroules.com>2015-07-22 13:23:36 +0000
commita3cb59b277698ba92cdfde0ccc215e93b96ae92f (patch)
treea58afa3f52ade66657afeab4092d11d2011c7a15
parent47f9b7c85a3e8033d618af73d18317fa68fcbc55 (diff)
downloadqbs-a3cb59b277698ba92cdfde0ccc215e93b96ae92f.tar.gz
Move more Android NDK logic out of the profiles.
Change-Id: Ie7c61fde802921b48d588b2760f798431fab81bf Reviewed-by: Christian Kandeler <christian.kandeler@theqtcompany.com>
-rw-r--r--doc/reference/modules/android-ndk-module.qdoc9
-rw-r--r--share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs65
-rw-r--r--share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs54
-rw-r--r--share/qbs/imports/qbs/base/Application.qbs2
-rw-r--r--share/qbs/imports/qbs/base/Library.qbs2
-rw-r--r--share/qbs/modules/Android/ndk/ndk.qbs79
-rw-r--r--share/qbs/modules/Android/ndk/utils.js106
-rw-r--r--share/qbs/modules/Android/sdk/sdk.qbs18
-rw-r--r--src/app/qbs-setup-android/android-setup.cpp338
-rw-r--r--tests/auto/blackbox/testdata/android/multiple-apks-per-project/product1/product1.qbs2
-rw-r--r--tests/auto/blackbox/testdata/android/teapot/teapot.qbs2
11 files changed, 321 insertions, 356 deletions
diff --git a/doc/reference/modules/android-ndk-module.qdoc b/doc/reference/modules/android-ndk-module.qdoc
index 54187f86a..4d34c9ed9 100644
--- a/doc/reference/modules/android-ndk-module.qdoc
+++ b/doc/reference/modules/android-ndk-module.qdoc
@@ -81,6 +81,7 @@
\li 1.4
\li undefined
\li The ABI name as it appears under "lib/" in the application package.
+ Corresponds to APP_ABI in Android.mk.
\row
\li appStl
\li string
@@ -90,11 +91,11 @@
"gabi++_shared", "stlport_static", "stlport_shared", "gnustl_static", "gnustl_shared",
"c++_static", "c++_shared".
\row
- \li buildProfile
- \li string
- \li 1.4
+ \li hardFloat
+ \li bool
+ \li 1.4.2
\li undefined
- \li The name of the build profile, e.g. "armeabi-v7a-hard".
+ \li Whether to use the hard floating point variant of the armeabi-v7a ABI.
\row
\li enableExceptions
\li bool
diff --git a/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs
new file mode 100644
index 000000000..29e954891
--- /dev/null
+++ b/share/qbs/imports/qbs/Probes/AndroidNdkProbe.qbs
@@ -0,0 +1,65 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Jake Petroules.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of the Qt Build Suite.
+**
+** 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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs
+import qbs.File
+import qbs.FileInfo
+
+PathProbe {
+ // Inputs
+ property stringList hostOS: qbs.hostOS
+
+ environmentPaths: qbs.getEnv("ANDROID_NDK_ROOT")
+
+ // Outputs
+ property var hostArch
+
+ configure: {
+ var i, j;
+ for (i in environmentPaths) {
+ var platforms = [];
+ if (hostOS.contains("windows"))
+ platforms.push("windows-x86_64", "windows");
+ if (hostOS.contains("darwin"))
+ platforms.push("darwin-x86_64", "darwin-x86");
+ if (hostOS.contains("linux"))
+ platforms.push("linux-x86_64", "linux-x86");
+ for (j in platforms) {
+ if (File.exists(FileInfo.joinPaths(environmentPaths[i], "prebuilt",
+ platforms[j]))) {
+ path = environmentPaths[i];
+ hostArch = platforms[j];
+ found = true;
+ return;
+ }
+ }
+ }
+ }
+}
diff --git a/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs
new file mode 100644
index 000000000..cd796a6f8
--- /dev/null
+++ b/share/qbs/imports/qbs/Probes/AndroidSdkProbe.qbs
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 Jake Petroules.
+** Contact: http://www.qt.io/licensing
+**
+** This file is part of the Qt Build Suite.
+**
+** 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 http://www.qt.io/terms-conditions. For further information
+** use the contact form at http://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 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, The Qt Company gives you certain additional
+** rights. These rights are described in The Qt Company LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+****************************************************************************/
+
+import qbs
+import qbs.File
+import qbs.FileInfo
+
+PathProbe {
+ environmentPaths: qbs.getEnv("ANDROID_HOME")
+
+ // Outputs
+ property string buildToolsVersion
+ property string platform
+
+ configure: {
+ var i;
+ for (i in environmentPaths) {
+ if (File.exists(FileInfo.joinPaths(environmentPaths[i], "tools", "android"))) {
+ path = environmentPaths[i];
+ buildToolsVersion = undefined; // not yet implemented
+ platform = undefined; // not yet implemented
+ found = true;
+ return;
+ }
+ }
+ }
+}
diff --git a/share/qbs/imports/qbs/base/Application.qbs b/share/qbs/imports/qbs/base/Application.qbs
index 92023b8ed..d998b1305 100644
--- a/share/qbs/imports/qbs/base/Application.qbs
+++ b/share/qbs/imports/qbs/base/Application.qbs
@@ -36,7 +36,7 @@ Product {
}
property bool isForAndroid: qbs.targetOS.contains("android")
- property stringList architectures: isForAndroid ? ["armeabi"] : undefined
+ property stringList architectures: isForAndroid ? ["armv5"] : undefined
Depends { name: "Android.ndk"; condition: isForAndroid }
Depends { name: "bundle" }
diff --git a/share/qbs/imports/qbs/base/Library.qbs b/share/qbs/imports/qbs/base/Library.qbs
index fef974530..fb392a4e1 100644
--- a/share/qbs/imports/qbs/base/Library.qbs
+++ b/share/qbs/imports/qbs/base/Library.qbs
@@ -36,7 +36,7 @@ Product {
}
property bool isForAndroid: qbs.targetOS.contains("android")
- property stringList architectures: isForAndroid ? ["armeabi"] : undefined
+ property stringList architectures: isForAndroid ? ["armv5"] : undefined
Depends { name: "Android.ndk"; condition: isForAndroid }
Depends { name: "bundle" }
diff --git a/share/qbs/modules/Android/ndk/ndk.qbs b/share/qbs/modules/Android/ndk/ndk.qbs
index 78c13e0b5..e8cf26ae3 100644
--- a/share/qbs/modules/Android/ndk/ndk.qbs
+++ b/share/qbs/modules/Android/ndk/ndk.qbs
@@ -32,6 +32,7 @@ import qbs
import qbs.File
import qbs.FileInfo
import qbs.ModUtils
+import qbs.Probes
import qbs.TextFile
import "utils.js" as NdkUtils
@@ -39,7 +40,17 @@ import "utils.js" as NdkUtils
Module {
Depends { name: "cpp" }
- property string abi // Corresponds to the subdir under "lib/" in the apk file.
+ Probes.AndroidNdkProbe {
+ id: ndkProbe
+ environmentPaths: [ndkDir].concat(base)
+ }
+
+ readonly property string abi: NdkUtils.androidAbi(qbs.architecture)
+ PropertyOptions {
+ name: "abi"
+ description: "Corresponds to the 'APP_ABI' variable in an Android.mk file."
+ allowedValues: ["arm64-v8a", "armeabi", "armeabi-v7a", "mips", "mips64", "x86", "x86_64"]
+ }
property string appStl: "system"
PropertyOptions {
@@ -57,19 +68,35 @@ Module {
description: "Corresponds to the 'NDK_TOOLCHAIN_VERSION' variable in an Android.mk file."
}
- property string hostArch // E.g. darwin-x86_64
- property string toolchainDirPrefix // E.g. arm-linux-androideabi-
- property string buildProfile // E.g. "armeabi-v7a-hard"
+ property string hostArch: ndkProbe.hostArch
+ property string toolchainDirPrefix: NdkUtils.toolchainDirPrefix(qbs.toolchain, abi)
property bool enableExceptions: appStl !== "system"
property bool enableRtti: appStl !== "system"
- property string ndkDir
+ property bool hardFloat
+ property string ndkDir: ndkProbe.path
property string platform: "android-9"
// Internal properties.
- property stringList compilerFlagsDebug: []
- property stringList compilerFlagsRelease: []
+ property int platformVersion: {
+ if (platform) {
+ var match = platform.match(/^android-([0-9]+)$/);
+ if (match !== null) {
+ return parseInt(match[1], 10);
+ }
+ }
+ }
+
+ property stringList abis: {
+ var list = ["armeabi", "armeabi-v7a"];
+ if (platformVersion >= 9)
+ list.push("mips", "x86");
+ if (platformVersion >= 21)
+ list.push("arm64-v8a", "mips64", "x86_64");
+ return list;
+ }
+
property stringList defines: ["ANDROID"]
- property bool hardFp
+ property string buildProfile: (abi === "armeabi-v7a" && hardFloat) ? (abi + "-hard") : abi
property string cxxStlBaseDir: FileInfo.joinPaths(ndkDir, "sources/cxx-stl")
property string gabiBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "gabi++")
property string stlPortBaseDir: FileInfo.joinPaths(cxxStlBaseDir, "stlport")
@@ -116,17 +143,28 @@ Module {
}
cpp.toolchainInstallPath: FileInfo.joinPaths(ndkDir, "toolchains",
- toolchainDirPrefix + toolchainVersion,
+ toolchainDirPrefix +
+ NdkUtils.toolchainVersionNumber(toolchainVersion),
"prebuilt", hostArch, "bin")
- cpp.commonCompilerFlags: {
- var flags = qbs.buildVariant === "debug"
- ? compilerFlagsDebug : compilerFlagsRelease;
- if (armMode)
- flags.push("-m" + armMode);
- return flags;
+ cpp.toolchainPrefix: NdkUtils.toolchainPrefix(qbs.toolchain, abi)
+
+ qbs.toolchain: {
+ var tc = [];
+ if (toolchainVersion && toolchainVersion.startsWith("clang"))
+ tc.push("clang");
+ return tc.concat(["gcc"]);
}
+ qbs.optimization: ["armeabi", "armeabi-v7a"].contains(abi) ? "small" : base
+
+ cpp.compilerName: qbs.toolchain.contains("clang") ? "clang++" : "g++"
+ cpp.linkerName: qbs.toolchain.contains("clang") ? "clang++" : "g++"
+
+ cpp.commonCompilerFlags: NdkUtils.commonCompilerFlags(qbs.buildVariant, abi, hardFloat, armMode)
+
+ cpp.linkerFlags: NdkUtils.commonLinkerFlags(abi, hardFloat)
+
cpp.cxxFlags: {
var flags = [];
if (enableExceptions)
@@ -143,7 +181,7 @@ Module {
cpp.libraryPaths: {
var prefix = FileInfo.joinPaths(cpp.sysroot, "usr");
var paths = [];
- if (buildProfile === "mips64" || buildProfile === "x86_64") // no lib64 for arm64-v8a
+ if (abi === "mips64" || abi === "x86_64") // no lib64 for arm64-v8a
paths.push(FileInfo.joinPaths(prefix, "lib64"));
paths.push(FileInfo.joinPaths(prefix, "lib"));
return paths;
@@ -151,7 +189,7 @@ Module {
cpp.dynamicLibraries: {
var libs = ["c"];
- if (!hardFp)
+ if (!hardFloat)
libs.push("m");
if (sharedStlFilePath)
libs.push(sharedStlFilePath);
@@ -159,7 +197,7 @@ Module {
}
cpp.staticLibraries: {
var libs = ["gcc"];
- if (hardFp)
+ if (hardFloat)
libs.push("m_hard");
if (staticStlFilePath)
libs.push(staticStlFilePath);
@@ -185,7 +223,7 @@ Module {
}
cpp.defines: {
var list = defines;
- if (hardFp)
+ if (hardFloat)
list.push("_NDK_MATH_NO_SOFTFP=1");
return list;
}
@@ -245,11 +283,10 @@ Module {
infoFile.close();
}
}
- var stripBinary = product.moduleProperty("cpp", "toolchainPathPrefix") + "strip";
var stripArgs = ["--strip-unneeded", outputs["android.nativelibrary"][0].filePath];
if (stlFilePath)
stripArgs.push(stlFilePath);
- var stripCmd = new Command(stripBinary, stripArgs);
+ var stripCmd = new Command(product.moduleProperty("cpp", "stripPath"), stripArgs);
stripCmd.description = "Stripping unneeded symbols from "
+ outputs["android.nativelibrary"][0].fileName;
return [copyCmd, stripCmd];
diff --git a/share/qbs/modules/Android/ndk/utils.js b/share/qbs/modules/Android/ndk/utils.js
index 9e81b82ff..a293b1ae0 100644
--- a/share/qbs/modules/Android/ndk/utils.js
+++ b/share/qbs/modules/Android/ndk/utils.js
@@ -28,11 +28,113 @@
**
****************************************************************************/
-function abiNameToDirName(abiName)
-{
+function abiNameToDirName(abiName) {
if (abiName.startsWith("armeabi"))
return "arm";
if (abiName.startsWith("arm64"))
return "arm64";
return abiName;
}
+
+function androidAbi(arch) {
+ if (arch === "x86" || arch === "x86_64")
+ return arch;
+ return {
+ "arm64": "arm64-v8a",
+ "armv5": "armeabi",
+ "armv7": "armeabi-v7a",
+ "mipsel": "mips",
+ "mips64el": "mips64"
+ }[arch];
+}
+
+function toolchainVersionNumber(version) {
+ var prefix = "clang";
+ if (version && version.startsWith(prefix))
+ return version.substr(prefix.length);
+ return version;
+}
+
+function toolchainDirPrefix(toolchain, abi) {
+ if (toolchain && toolchain.contains("clang"))
+ return "llvm-";
+ if (["x86", "x86_64"].contains(abi))
+ return abi + "-";
+ return toolchainPrefix(toolchain, abi);
+}
+
+function toolchainPrefix(toolchain, abi) {
+ if (toolchain && toolchain.contains("clang"))
+ return undefined;
+ return {
+ "arm64-v8a": "aarch64-linux-android-",
+ "armeabi": "arm-linux-androideabi-",
+ "armeabi-v7a": "arm-linux-androideabi-", // same prefix as above
+ "mips": "mipsel-linux-android-",
+ "mips64": "mips64el-linux-android-",
+ "x86": "i686-linux-android-",
+ "x86_64": "x86_64-linux-android-"
+ }[abi];
+}
+
+function commonCompilerFlags(buildVariant, abi, hardFloat, armMode) {
+ var flags = ["-ffunction-sections", "-funwind-tables", "-no-canonical-prefixes",
+ "-Wa,--noexecstack", "-Werror=format-security"];
+
+ if (buildVariant === "debug")
+ flags.push("-fno-omit-frame-pointer", "-fno-strict-aliasing");
+ if (buildVariant === "release")
+ flags.push("-fomit-frame-pointer");
+
+ if (abi === "arm64-v8a") {
+ flags.push("-fpic", "-fstack-protector", "-funswitch-loops", "-finline-limit=300");
+ if (buildVariant === "release")
+ flags.push("-fstrict-aliasing");
+ }
+
+ if (abi === "armeabi" || abi === "armeabi-v7a") {
+ flags.push("-fpic", "-fstack-protector", "-finline-limit=64");
+
+ if (abi === "armeabi")
+ flags.push("-march=armv5te", "-mtune=xscale", "-msoft-float");
+
+ if (abi === "armeabi-v7a") {
+ flags.push("-march=armv7-a", "-mfpu=vfpv3-d16");
+ flags.push(hardFloat ? "-mhard-float" : "-mfloat-abi=softfp");
+ }
+
+ if (buildVariant === "release")
+ flags.push("-fno-strict-aliasing");
+ }
+
+ if (abi === "mips" || abi === "mips64") {
+ 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 (abi === "x86" || abi === "x86_64") {
+ flags.push("-fstack-protector", "-funswitch-loops", "-finline-limit=300");
+ if (buildVariant === "release")
+ flags.push("-fstrict-aliasing");
+ }
+
+ if (armMode)
+ flags.push("-m" + armMode);
+
+ return flags;
+}
+
+function commonLinkerFlags(abi, hardFloat) {
+ var flags = ["-no-canonical-prefixes", "-Wl,-z,noexecstack", "-Wl,-z,relro", "-Wl,-z,now"];
+
+ if (abi === "armeabi-v7a") {
+ flags.push("-march=armv7-a", "-Wl,--fix-cortex-a8");
+ if (hardFloat)
+ flags.push("-Wl,-no-warn-mismatch");
+ }
+
+ return flags;
+}
diff --git a/share/qbs/modules/Android/sdk/sdk.qbs b/share/qbs/modules/Android/sdk/sdk.qbs
index 4c1c4fd64..863e566f6 100644
--- a/share/qbs/modules/Android/sdk/sdk.qbs
+++ b/share/qbs/modules/Android/sdk/sdk.qbs
@@ -37,14 +37,24 @@ import qbs.TextFile
import "utils.js" as SdkUtils
Module {
- property path sdkDir
- property path ndkDir
- property string buildToolsVersion
+ Probes.AndroidSdkProbe {
+ id: sdkProbe
+ environmentPaths: [sdkDir].concat(base)
+ }
+
+ Probes.AndroidNdkProbe {
+ id: ndkProbe
+ environmentPaths: [ndkDir].concat(base)
+ }
+
+ property path sdkDir: sdkProbe.path
+ property path ndkDir: ndkProbe.path
+ property string buildToolsVersion: sdkProbe.buildToolsVersion
property var buildToolsVersionParts: buildToolsVersion ? buildToolsVersion.split('.').map(function(item) { return parseInt(item, 10); }) : []
property int buildToolsVersionMajor: buildToolsVersionParts[0]
property int buildToolsVersionMinor: buildToolsVersionParts[1]
property int buildToolsVersionPatch: buildToolsVersionParts[2]
- property string platform
+ property string platform: sdkProbe.platform
// Internal properties.
property int platformVersion: {
diff --git a/src/app/qbs-setup-android/android-setup.cpp b/src/app/qbs-setup-android/android-setup.cpp
index 9eb7927bb..60b6d4aaa 100644
--- a/src/app/qbs-setup-android/android-setup.cpp
+++ b/src/app/qbs-setup-android/android-setup.cpp
@@ -111,288 +111,22 @@ static QString detectPlatform(const QString &sdkDir)
return newestPlatform;
}
-// Independent of architecture, build variant and language.
-static QStringList commonCompilerFlags()
+static QStringList expectedArchs()
{
- return QStringList() << qls("-ffunction-sections") << qls("-funwind-tables")
- << qls("-no-canonical-prefixes") << qls("-Wa,--noexecstack")
- << qls("-Werror=format-security");
+ return QStringList({
+ QStringLiteral("arm64"),
+ QStringLiteral("armv5"),
+ QStringLiteral("armv7"),
+ QStringLiteral("mipsel"),
+ QStringLiteral("mips64el"),
+ QStringLiteral("x86"),
+ QStringLiteral("x86_64")});
}
-// Independent of architecture and language
-static QStringList commonCompilerFlagsDebug()
-{
- return commonCompilerFlags() << qls("-fno-omit-frame-pointer") << qls("-fno-strict-aliasing")
- << qls("-O0");
-}
-
-// Independent of architecture and language
-static QStringList commonCompilerFlagsRelease()
-{
- return commonCompilerFlags() << qls("-fomit-frame-pointer");
-}
-
-static QStringList arm64FlagsDebug()
-{
- return commonCompilerFlagsDebug() << qls("-fpic") << qls("-fstack-protector")
- << qls("-funswitch-loops") << qls("-finline-limit=300");
-}
-
-static QStringList arm64FlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fpic") << qls("-fstack-protector") << qls("-O2")
- << qls("-fstrict-aliasing") << qls("-funswitch-loops") << qls("-finline-limit=300");
-}
-
-static QStringList armeabiFlagsDebug()
-{
- return commonCompilerFlagsDebug() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv5te") << qls("-mtune=xscale") << qls("-msoft-float")
- << qls("-finline-limit=64");
-}
-
-static QStringList armeabiFlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv5te") << qls("-mtune=xscale") << qls("-msoft-float") << qls("-Os")
- << qls("-fno-strict-aliasing") << qls("-finline-limit=64");
-}
-
-static QStringList armeabiV7aFlagsDebug()
-{
- return commonCompilerFlagsDebug() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv7-a") << qls("-mfpu=vfpv3-d16") << qls("-mfloat-abi=softfp")
- << qls("-finline-limit=64");
-}
-
-static QStringList armeabiV7aFlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv7-a") << qls("-mfpu=vfpv3-d16") << qls("-mfloat-abi=softfp")
- << qls("-Os") << qls("-fno-strict-aliasing") << qls("-finline-limit=64");
-}
-static QStringList armeabiV7aHardFlagsDebug()
+static QString subProfileName(const QString &mainProfileName, const QString &arch)
{
- return commonCompilerFlagsDebug() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv7-a") << qls("-mfpu=vfpv3-d16") << qls("-mhard-float")
- << qls("-finline-limit=64");
-}
-
-static QStringList armeabiV7aHardFlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fpic") << qls("-fstack-protector")
- << qls("-march=armv7-a") << qls("-mfpu=vfpv3-d16") << qls("-mhard-float") << qls("-Os")
- << qls("-fno-strict-aliasing") << qls("-finline-limit=64");
-}
-
-static QStringList mipsFlagsDebug()
-{
- return commonCompilerFlagsDebug() << qls("-fpic") << qls("-finline-functions")
- << qls("-fmessage-length=0") << qls("-fno-inline-functions-called-once")
- << qls("-fgcse-after-reload") << qls("-frerun-cse-after-loop")
- << qls("-frename-registers");
-}
-
-static QStringList mipsFlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fpic") << qls("-fno-strict-aliasing")
- << qls("-finline-functions") << qls("-fmessage-length=0")
- << qls("-fno-inline-functions-called-once") << qls("-fgcse-after-reload")
- << qls("-frerun-cse-after-loop") << qls("-frename-registers") << qls("-O2")
- << qls("-funswitch-loops") << qls("-finline-limit=300");
-}
-
-static QStringList x86FlagsDebug()
-{
- return commonCompilerFlagsDebug() << qls("-fstack-protector") << qls("-funswitch-loops")
- << qls("-finline-limit=300");
-}
-
-static QStringList x86FlagsRelease()
-{
- return commonCompilerFlagsRelease() << qls("-fstack-protector") << qls("-O2")
- << qls("-fstrict-aliasing") << qls("-funswitch-loops") << qls("-finline-limit=300");
-}
-
-static QStringList commonLinkerFlags()
-{
- return QStringList() << qls("-no-canonical-prefixes") << qls("-Wl,-z,noexecstack")
- << qls("-Wl,-z,relro") << qls("-Wl,-z,now");
-}
-
-static QStringList armeabiV7aLinkerFlags()
-{
- return commonLinkerFlags() << qls("-march=armv7-a") << qls("-Wl,--fix-cortex-a8");
-}
-
-static QStringList armeabiV7aHardLinkerFlags()
-{
- return armeabiV7aLinkerFlags() << qls("-Wl,-no-warn-mismatch");
-}
-
-class BuildProfile {
-public:
- BuildProfile() : linkerFlags(commonLinkerFlags()), hardFp(false) {}
-
- QString profileSuffix;
- QString abi;
- QString qbsArchName;
- QString toolchainDirPrefix;
- QString toolchainPrefix;
- QStringList compilerFlagsDebug;
- QStringList compilerFlagsRelease;
- QStringList linkerFlags;
- bool hardFp;
-};
-
-uint qHash(const BuildProfile &arch) { return qHash(arch.profileSuffix); }
-bool operator==(const BuildProfile &a1, const BuildProfile &a2) {
- return a1.profileSuffix == a2.profileSuffix;
-}
-typedef QHash<QString, BuildProfile> BuildProfileMap;
-
-// As of r10c. Let's hope they don't change it gratuitously.
-static BuildProfileMap createArchMap()
-{
- BuildProfileMap map;
-
- BuildProfile aarch64;
- aarch64.abi = qls("arm64-v8a");
- aarch64.profileSuffix = aarch64.abi;
- aarch64.qbsArchName = qls("arm64");
- aarch64.toolchainDirPrefix = qls("aarch64-linux-android-");
- aarch64.toolchainPrefix = qls("aarch64-linux-android-");
- aarch64.compilerFlagsDebug = arm64FlagsDebug();
- aarch64.compilerFlagsRelease = arm64FlagsRelease();
- map.insert(aarch64.profileSuffix, aarch64);
-
- BuildProfile armeabi;
- armeabi.abi = qls("armeabi");
- armeabi.profileSuffix = armeabi.abi;
- armeabi.qbsArchName = qls("arm");
- armeabi.toolchainDirPrefix = qls("arm-linux-androideabi-");
- armeabi.toolchainPrefix = qls("arm-linux-androideabi-");
- armeabi.compilerFlagsDebug = armeabiFlagsDebug();
- armeabi.compilerFlagsRelease = armeabiFlagsRelease();
- map.insert(armeabi.profileSuffix, armeabi);
-
- BuildProfile armeabiV7a = armeabi;
- armeabiV7a.abi = qls("armeabi-v7a");
- armeabiV7a.profileSuffix = armeabiV7a.abi;
- armeabiV7a.compilerFlagsDebug = armeabiV7aFlagsDebug();
- armeabiV7a.compilerFlagsRelease = armeabiV7aFlagsRelease();
- armeabiV7a.linkerFlags = armeabiV7aLinkerFlags();
- map.insert(armeabiV7a.profileSuffix, armeabiV7a);
-
- BuildProfile armeabiV7aHard = armeabiV7a;
- armeabiV7aHard.profileSuffix = qls("armeabi-v7a-hard"); // Same abi as above.
- armeabiV7aHard.compilerFlagsDebug = armeabiV7aHardFlagsDebug();
- armeabiV7aHard.compilerFlagsRelease = armeabiV7aHardFlagsRelease();
- armeabiV7aHard.linkerFlags = armeabiV7aHardLinkerFlags();
- armeabiV7aHard.hardFp = true;
- map.insert(armeabiV7aHard.profileSuffix, armeabiV7aHard);
-
- BuildProfile mips;
- mips.abi = qls("mips");
- mips.profileSuffix = mips.abi;
- mips.qbsArchName = qls("mipsel");
- mips.toolchainDirPrefix = qls("mipsel-linux-android-");
- mips.toolchainPrefix = qls("mipsel-linux-android-");
- mips.compilerFlagsDebug = mipsFlagsDebug();
- mips.compilerFlagsRelease = mipsFlagsRelease();
- map.insert(mips.profileSuffix, mips);
-
- BuildProfile mips64;
- mips64.abi = qls("mips64");
- mips64.profileSuffix = mips64.abi;
- mips64.qbsArchName = qls("mips64el");
- mips64.toolchainDirPrefix = qls("mips64el-linux-android-");
- mips64.toolchainPrefix = qls("mips64el-linux-android-");
- mips64.compilerFlagsDebug = mipsFlagsDebug();
- mips64.compilerFlagsRelease = mipsFlagsRelease();
- map.insert(mips64.profileSuffix, mips64);
-
- BuildProfile x86;
- x86.abi = qls("x86");
- x86.profileSuffix = x86.abi;
- x86.qbsArchName = x86.abi;
- x86.toolchainDirPrefix = qls("x86-");
- x86.toolchainPrefix = qls("i686-linux-android-");
- x86.compilerFlagsDebug = x86FlagsDebug();
- x86.compilerFlagsRelease = x86FlagsRelease();
- map.insert(x86.profileSuffix, x86);
-
- BuildProfile x86_64;
- x86_64.abi = qls("x86_64");
- x86_64.profileSuffix = x86_64.abi;
- x86_64.qbsArchName = x86_64.abi;
- x86_64.toolchainDirPrefix = qls("x86_64-");
- x86_64.toolchainPrefix = qls("x86_64-linux-android-");
- x86_64.compilerFlagsDebug = x86FlagsDebug();
- x86_64.compilerFlagsRelease = x86FlagsRelease();
- map.insert(x86_64.profileSuffix, x86_64);
-
- return map;
-}
-
-
-static QString subProfileName(const QString &mainProfileName, const BuildProfile &arch)
-{
- return mainProfileName + QLatin1Char('_') + arch.profileSuffix;
-}
-
-static QString detectToolchainHostArch(const QString &ndkDirPath)
-{
- QStringList candidates;
- if (Internal::HostOsInfo::isWindowsHost()) {
-#ifdef Q_PROCESSOR_X86_64
- candidates << qls("windows-x86_64");
-#endif
-#ifdef Q_PROCESSOR_X86
- candidates << qls("windows"); // no -x86 suffix for Windows 32-bit
-#endif
- }
- if (Internal::HostOsInfo::isOsxHost()) {
-#ifdef Q_PROCESSOR_X86_64
- candidates << qls("darwin-x86_64");
-#endif
-#ifdef Q_PROCESSOR_X86
- candidates << qls("darwin-x86");
-#endif
- }
- if (Internal::HostOsInfo::isLinuxHost()) {
-#ifdef Q_PROCESSOR_X86_64
- candidates << qls("linux-x86_64");
-#endif
-#ifdef Q_PROCESSOR_X86
- candidates << qls("linux-x86");
-#endif
- }
-
- if (candidates.isEmpty()) {
- throw ErrorInfo(Tr::tr("Unsupported host platform for Android NDK."));
- }
-
- QStringList checkedPaths;
- QString hostArch;
- Q_FOREACH (const QString &candidate, candidates) {
- const QDir tcDir(ndkDirPath + qls("/prebuilt/") + candidate);
- if (QDir(tcDir).exists() && hostArch.isEmpty()) {
- hostArch = candidate;
- }
-
- checkedPaths << qls("'")
- + QDir::toNativeSeparators(QDir::cleanPath(tcDir.absolutePath()))
- + qls("'");
- }
-
- if (hostArch.isEmpty()) {
- throw ErrorInfo(Tr::tr("None of the following paths are present:\n%1")
- .arg(checkedPaths.join(qls("\n"))));
- }
-
- return hostArch;
+ return mainProfileName + QLatin1Char('_') + arch;
}
void setupSdk(qbs::Settings *settings, const QString &profileName, const QString &sdkDirPath)
@@ -403,6 +137,7 @@ void setupSdk(qbs::Settings *settings, const QString &profileName, const QString
}
Profile profile(profileName, settings);
+ profile.removeProfile();
profile.setValue(qls("Android.sdk.sdkDir"), QDir::cleanPath(sdkDirPath));
profile.setValue(qls("Android.sdk.buildToolsVersion"),
detectBuildToolsVersion(sdkDirPath));
@@ -420,54 +155,15 @@ void setupNdk(qbs::Settings *settings, const QString &profileName, const QString
throw ErrorInfo(Tr::tr("NDK directory '%1' does not exist.")
.arg(QDir::toNativeSeparators(ndkDirPath)));
}
- QDir stlLibsDir(ndkDirPath + qls("/sources/cxx-stl/stlport/libs"));
- if (!stlLibsDir.exists()) {
- throw ErrorInfo(Tr::tr("Expected directory '%1' to be present, but it is not.")
- .arg(QDir::toNativeSeparators(stlLibsDir.path())));
- }
- const QStringList archList = stlLibsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
- if (archList.isEmpty()) {
- throw ErrorInfo(Tr::tr("Failed to detect the architectures supported by the NDK, because "
- "directory '%1' is empty.").arg(QDir::toNativeSeparators(stlLibsDir.path())));
- }
-
- const BuildProfileMap archMap = createArchMap();
- QList<BuildProfile> architectures;
- foreach (const QString &archName, archList) {
- const BuildProfileMap::ConstIterator it = archMap.find(archName);
- if (it == archMap.constEnd()) {
- qDebug("Ignoring unknown architecture '%s'.", qPrintable(archName));
- continue;
- }
- architectures << it.value();
- }
-
- for (BuildProfileMap::ConstIterator it = archMap.constBegin();
- it != archMap.constEnd(); ++it) {
- Profile(subProfileName(profileName, it.value()), settings).removeProfile();
- }
Profile mainProfile(profileName, settings);
+ mainProfile.setValue(qls("Android.ndk.ndkDir"), QDir::cleanPath(ndkDirPath));
mainProfile.setValue(qls("Android.sdk.ndkDir"), QDir::cleanPath(ndkDirPath));
- foreach (const BuildProfile &arch, architectures) {
+ foreach (const QString &arch, expectedArchs()) {
Profile p(subProfileName(profileName, arch), settings);
- p.setValue(qls("Android.ndk.abi"), arch.abi);
- p.setValue(qls("Android.ndk.buildProfile"), arch.profileSuffix);
- p.setValue(qls("Android.ndk.compilerFlagsDebug"), arch.compilerFlagsDebug);
- p.setValue(qls("Android.ndk.compilerFlagsRelease"), arch.compilerFlagsRelease);
- p.setValue(qls("Android.ndk.hardFp"), arch.hardFp);
- p.setValue(qls("Android.ndk.hostArch"), detectToolchainHostArch(ndkDirPath));
- p.setValue(qls("Android.ndk.ndkDir"), QDir::cleanPath(ndkDirPath));
- p.setValue(qls("Android.ndk.toolchainDirPrefix"), arch.toolchainDirPrefix);
- p.setValue(qls("cpp.compilerName"), qls("gcc"));
- p.setValue(qls("cpp.debugInformation"), true);
- p.setValue(qls("cpp.linkerFlags"), arch.linkerFlags);
- p.setValue(qls("cpp.linkerName"), qls("g++"));
- p.setValue(qls("cpp.toolchainPrefix"), arch.toolchainPrefix);
- p.setValue(qls("qbs.architecture"), arch.qbsArchName);
- p.setValue(qls("qbs.targetOS"), QStringList() << qls("android") << qls("linux")
- << qls("unix"));
- p.setValue(qls("qbs.toolchain"), QStringList(qls("gcc")));
+ p.removeProfile();
+ p.setBaseProfile(mainProfile.name());
+ p.setValue(qls("qbs.architecture"), arch);
}
}
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 e0bf91cea..9dde6e174 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
@@ -5,7 +5,7 @@ Project {
name: "p1lib1"
files: ["src/main/jni/lib1.cpp"]
Android.ndk.appStl: "stlport_shared"
- architectures: ["mips", "x86"]
+ architectures: ["mipsel", "x86"]
cpp.useRPaths: false
}
diff --git a/tests/auto/blackbox/testdata/android/teapot/teapot.qbs b/tests/auto/blackbox/testdata/android/teapot/teapot.qbs
index 6096c1597..6701eaa49 100644
--- a/tests/auto/blackbox/testdata/android/teapot/teapot.qbs
+++ b/tests/auto/blackbox/testdata/android/teapot/teapot.qbs
@@ -1,7 +1,7 @@
import qbs
Project {
- property stringList architectures: ["arm64-v8a", "armeabi-v7a-hard", "x86_64", "mips"]
+ property stringList architectures: ["arm64", "armv7", "x86_64", "mipsel"]
StaticLibrary {
architectures: project.architectures
name: "native-glue"