aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main/groovy/org/qtproject/qt/gradleplugin/QtBuildTask.groovy71
-rw-r--r--src/main/groovy/org/qtproject/qt/gradleplugin/Utils.groovy36
-rw-r--r--src/test/groovy/org/qtproject/qt/gradleplugin/QtBuildTaskTest.groovy2
3 files changed, 78 insertions, 31 deletions
diff --git a/src/main/groovy/org/qtproject/qt/gradleplugin/QtBuildTask.groovy b/src/main/groovy/org/qtproject/qt/gradleplugin/QtBuildTask.groovy
index 53a257e..882cc14 100644
--- a/src/main/groovy/org/qtproject/qt/gradleplugin/QtBuildTask.groovy
+++ b/src/main/groovy/org/qtproject/qt/gradleplugin/QtBuildTask.groovy
@@ -36,6 +36,8 @@ class QtBuildTask extends DefaultTask {
private final String NDK_PATH_CMAKE_ARG = "ANDROID_NDK_ROOT"
private final String SDK_PATH_CMAKE_ARG = "ANDROID_SDK_ROOT"
private final String MAKE_PROGRAM_CMAKE_ARG = "CMAKE_MAKE_PROGRAM"
+ private final String BUILD_ALL_ABIS_ARG = "QT_ANDROID_BUILD_ALL_ABIS"
+ private final String ANDROID_ABIS_ARG = "QT_ANDROID_ABIS"
private String pluginVersion = "NA"
@@ -81,11 +83,8 @@ class QtBuildTask extends DefaultTask {
include: ["${targetName}.aar"]))
}
- // Declared as @Internal so gradle will ignore this path when checking if the task is
- // up-to-date or not.
- @Internal
- def getQtCMakeWrapperPath() {
- def qtCMakeWrapperPath = "$qtKitDir/bin/qt-cmake"
+ def getQtCMakeWrapperPath(File qtAbiPath) {
+ def qtCMakeWrapperPath = "$qtAbiPath/bin/qt-cmake"
if (isWindows())
qtCMakeWrapperPath += '.bat'
return qtCMakeWrapperPath
@@ -204,7 +203,7 @@ class QtBuildTask extends DefaultTask {
// @TODO: QTTA-297 Instead of taking the first ABI found take one that,
// matches with the running device/emulator.
def listAndroidABIsAndSelectFirst() {
- def firstMatch = new File(qtPath).listFiles().find { file ->
+ def firstMatch = new File(qtPath).listFiles().sort().find { file ->
file.name ==~ Utils.androidAbiDirNameFormat()
}
@@ -213,8 +212,18 @@ class QtBuildTask extends DefaultTask {
return new File(firstMatch.path)
}
- def resolveCoreJson() {
- def qtCoreJsonPath = "$qtKitDir/modules/Core.json"
+ def findFirstMatchingAbiDirectory(ArrayList androidABIs) {
+ def firstMatch = new File(qtPath).listFiles().find { file ->
+ file.name in androidABIs
+ }
+
+ if (!firstMatch)
+ Utils.logAndThrowException("No Qt for Android kit from $androidABIs found from: $qtPath")
+ return new File(firstMatch.path)
+ }
+
+ def resolveCoreJson(File qtAbiPath) {
+ def qtCoreJsonPath = "$qtAbiPath/modules/Core.json"
if (!new File(qtCoreJsonPath).exists())
Utils.logAndThrowException("No Core.json file found under $qtCoreJsonPath.")
@@ -250,14 +259,41 @@ class QtBuildTask extends DefaultTask {
}
def configCommand() {
- def buildMultiABI = !qtKitDir
- if (!qtKitDir)
- qtKitDir = listAndroidABIsAndSelectFirst()
- def qtCoreJSon = resolveCoreJson()
+ def buildAllAbis = extractValueFromCMakeArgs(BUILD_ALL_ABIS_ARG)
+ def androidAbis = extractValueFromCMakeArgs(ANDROID_ABIS_ARG)
+ def qtAbiPath = ""
+
+ // if qt.abiPath is set, build a single ABI build and ignore other ABI arguments
+ if (qtKitDir) {
+ qtAbiPath = new File(qtKitDir)
+ for (argument in [BUILD_ALL_ABIS_ARG, ANDROID_ABIS_ARG]) {
+ if (extraCMakeArguments.any { it.contains(argument) } ) {
+ System.err.println("Warning: Setting qt.abiPath means $argument will be ignored.")
+ extraCMakeArguments.removeAll { it.contains(argument) }
+ }
+ }
+
+ } else if (Utils.parseCMakeBoolean(buildAllAbis) == true) {
+ qtAbiPath = listAndroidABIsAndSelectFirst()
+
+ // if QT_ANDROID_ABIS is defined, build a multi-ABI build with those ABIs
+ } else if (androidAbis) {
+ androidAbis = androidAbis.replace("-", "_").split(";").collect{"android_$it".toString()}
+ qtAbiPath = findFirstMatchingAbiDirectory(androidAbis)
+
+ } else if (Utils.parseCMakeBoolean(buildAllAbis) == false) {
+ Utils.logAndThrowException(
+ "Setting $BUILD_ALL_ABIS_ARG=$buildAllAbis without defining $ANDROID_ABIS_ARG " +
+ "or qt.abiPath would result in a single ABI build with the first one in alphabetical " +
+ "order. This is probably not what is wanted."
+ )
- def architecture = getCoreJsonArchitecture(qtCoreJSon)
- def currentABI = Utils.abiFromArchitecture(architecture)
+ // the "standard" all-ABIs build
+ } else {
+ qtAbiPath = listAndroidABIsAndSelectFirst()
+ }
+ def qtCoreJSon = resolveCoreJson(qtAbiPath)
def platform = getCoreJsonPlatform(qtCoreJSon)
if (platform.toString().toLowerCase() != 'android') {
Utils.logAndThrowException(
@@ -265,7 +301,7 @@ class QtBuildTask extends DefaultTask {
"The kit's path: $qtKitDir")
}
- def qtCMakeWrapperPath = getQtCMakeWrapperPath()
+ def qtCMakeWrapperPath = getQtCMakeWrapperPath(qtAbiPath)
def cmd = [
qtCMakeWrapperPath,
@@ -274,10 +310,11 @@ class QtBuildTask extends DefaultTask {
'-G', 'Ninja',
'-DQT_ANDROID_GENERATE_JAVA_QTQUICKVIEW_CONTENTS=ON',
'-DQT_USE_TARGET_ANDROID_BUILD_DIR=ON',
- "-DANDROID_ABI=$currentABI",
- "-DQT_ANDROID_BUILD_ALL_ABIS=${buildMultiABI ? 'ON': 'OFF'}"
]
+ if (!buildAllAbis && !androidAbis && !qtKitDir)
+ cmd += "-DQT_ANDROID_BUILD_ALL_ABIS=ON"
+
def ninjaPathFromExtraCMakeArgs = extractValueFromCMakeArgs(MAKE_PROGRAM_CMAKE_ARG)
if (!ninjaPathFromExtraCMakeArgs)
resolveNinjaPath()
diff --git a/src/main/groovy/org/qtproject/qt/gradleplugin/Utils.groovy b/src/main/groovy/org/qtproject/qt/gradleplugin/Utils.groovy
index d1b2bdb..3eea60f 100644
--- a/src/main/groovy/org/qtproject/qt/gradleplugin/Utils.groovy
+++ b/src/main/groovy/org/qtproject/qt/gradleplugin/Utils.groovy
@@ -8,20 +8,8 @@ import org.gradle.api.Project
@Singleton
class Utils {
- static String ANDROID_ABI_X86_64 = "x86_64"
- static String ANDROID_ABI_X86 = "x86"
-
- static def abis = [
- 'arm64': 'arm64-v8a', 'arm': 'armeabi-v7a',
- 'x86_64': ANDROID_ABI_X86_64, 'i386': ANDROID_ABI_X86
- ]
-
static String androidAbiDirNameFormat() {
- return "android_(arm64_v8a|armv7|$ANDROID_ABI_X86_64|$ANDROID_ABI_X86)"
- }
-
- static String abiFromArchitecture(String architecture) {
- return abis.find { it.key == architecture }?.value
+ return "android_(arm64_v8a|armv7|x86_64|x86)"
}
static def getAndroidBuildTargetName(File buildDir) {
@@ -51,4 +39,26 @@ class Utils {
file = project.rootProject.file(path)
return file
}
+
+ // CMake truthy values are 1, ON, TRUE, Y and non-zero numbers including floats
+ static parseCMakeBoolean(String value) {
+ if (value == "") {
+ return null
+ }
+
+ try {
+ def returnValue = value.toFloat()
+ return returnValue != 0.0
+ }
+ catch(java.lang.NumberFormatException ignored) {
+ // Not a number, proceed to string processing
+ }
+
+ // toBoolean() returns true for "true", "y" or "1" (ignoring the case)
+ // we need to handle the rest
+ return value.toUpperCase()
+ .replace("ON", "TRUE")
+ .replace("YES", "TRUE")
+ .toBoolean()
+ }
}
diff --git a/src/test/groovy/org/qtproject/qt/gradleplugin/QtBuildTaskTest.groovy b/src/test/groovy/org/qtproject/qt/gradleplugin/QtBuildTaskTest.groovy
index 8be3242..a96701a 100644
--- a/src/test/groovy/org/qtproject/qt/gradleplugin/QtBuildTaskTest.groovy
+++ b/src/test/groovy/org/qtproject/qt/gradleplugin/QtBuildTaskTest.groovy
@@ -134,7 +134,7 @@ class QtBuildTaskTest extends Specification {
def mockQtCMakeFile = createQtCMakeFileMock(buildTask)
when: "getQtCMakeWrapperPath is called"
- def cmakeDir = buildTask.getQtCMakeWrapperPath()
+ def cmakeDir = buildTask.getQtCMakeWrapperPath(new File(buildTask.qtKitDir))
then: "qt-cmake file is found at the appropriate path"
assert new File(cmakeDir).exists()