0

Problem: I want to use Android build system (gradle version 3) with Qt project, but this version of gradle (compared to old version 2) would change location of generated output apk file to be under $buildDir/outputs/apk/debug instead of $buildDir/outputs/apk (added debug folder), but when Qt Android kit tries to install app to Android device it only looks in old location, and fails to locate the apk file. I checked with Android Studio and its same which indicates gradle 3 is working normal

old location: $build_folder/android-build\build\outputs\apk\my.apk New location: $build_folder/android-build\build\outputs\apk\debug\my.apk

Error (Compile):

adb: error: cannot stat 'D:/Qt/FireBase/build-client01-Android_for_armeabi_v7a_GCC_4_9_Qt_5_11_0_for_Android_armv73-Release/android-build//build/outputs/apk/android-build-debug.apk': No such file or directory

This problem occurs only when I make changes to default build.gradle generated by Qt to set gradle to version 3, the default generated file have classpath set to old version 2.3.3,

old: classpath 'com.android.tools.build:gradle:2.3.3' new : classpath 'com.android.tools.build:gradle:3.1.0

There are other changes I made, that also require change in gradle-wrapper.properties, here are updated files:

build.gradle

buildscript {
    repositories {
        jcenter()
        maven {
            url "https://maven.google.com"
        }
    }

    dependencies {
        //classpath 'com.android.tools.build:gradle:2.3.3'
        classpath 'com.google.gms:google-services:4.0.1' // google-services plugin
        classpath 'com.android.tools.build:gradle:3.1.0'
    }
}

allprojects {
    repositories {
        jcenter()
        //google() // Google's Maven repository
        maven {
            url "https://maven.google.com"
        }
    }
}

apply plugin: 'com.android.application'


dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])

}

android {
    /*******************************************************
     * The following variables:
     * - androidBuildToolsVersion,
     * - androidCompileSdkVersion
     * - qt5AndroidDir - holds the path to qt android files
     *                   needed to build any Qt application
     *                   on Android.
     *
     * are defined in gradle.properties file. This file is
     * updated by QtCreator and androiddeployqt tools.
     * Changing them manually might break the compilation!
     *******************************************************/

    compileSdkVersion androidCompileSdkVersion.toInteger()

    buildToolsVersion androidBuildToolsVersion

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
            aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
            res.srcDirs = [qt5AndroidDir + '/res', 'res']
            resources.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
       }
    }

    lintOptions {
        abortOnError false
    }
}

dependencies {
  // ...


    //libfirebase_auth.a
    //libfirebase_app.a
    implementation 'com.google.firebase:firebase-core:16.0.1'
    implementation 'com.google.firebase:firebase-auth:16.0.2'
    implementation 'com.google.android.gms:play-services-base:15.0.1'

  // Getting a "Could not find" error? Make sure you have
  // added the Google maven respository to your root build.gradle
}
apply plugin: 'com.google.gms.google-services'

gradle-wrapper.properties

#Mon Feb 20 10:43:22 EST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
Mohammad Kanan
  • 4,452
  • 10
  • 23
  • 47

2 Answers2

2

I use this on my build.gradle :

android {
...
    applicationVariants.all { variant ->
        variant.outputs.all {
            outputFileName = "../" + outputFileName
        }
    }
}
Apin
  • 2,558
  • 2
  • 21
  • 36
  • thank you, this works and indeed better, but still when I run it, the `debug` folder is created (thats ok) but still the file `output.json` is left in `debug` folder. I feel there is still a missing ring from Qt side as it searches for `apk` file in `apk` folder – Mohammad Kanan Jul 28 '18 at 10:46
  • what is output.json? I don't have it on my project – Apin Jul 28 '18 at 13:23
  • I am not familair with it, It just started appearing along my gradle version change! its a single line `[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"../android-build-debug.apk","fullName":"debug","baseName":"debug"},"path":"..\\android-build-debug.apk","properties":{}}]` – Mohammad Kanan Jul 28 '18 at 13:28
1

I still don't know where and how to instruct Qt to look into new output structure, but as a workaround for now , I added configuration to build.gradle to make a copy of the generated apk back to ~/apk where Qt looks for!

// make a copy of APK from "$buildDir/outputs/apk/debug" back to "$buildDir/outputs/apk"
def archiveBuildTypes = ["release", "debug"];
applicationVariants.all { variant ->
    variant.outputs.all { output ->
        if (variant.buildType.name in archiveBuildTypes) {
            def taskSuffix = variant.name.capitalize()
            def assembleTaskName = "assemble${taskSuffix}"
            if (tasks.findByName(assembleTaskName)) {
                def copyAPKFolderTask = tasks.create(name: "archive${taskSuffix}", type: org.gradle.api.tasks.Copy) {
                    description "copy APK to old folder"
                    def sourceFolder = "$buildDir/outputs/apk/$output.baseName"
                    def destinationFolder = "$buildDir/outputs/apk"
                    print "Copy apk from: $sourceFolder into $destinationFolder\n"
                    from(sourceFolder)
                    into destinationFolder
                    eachFile { file ->
                        file.path = file.name // so we have a "flat" copy
                    }
                    includeEmptyDirs = false
                }
                tasks[assembleTaskName].finalizedBy = [copyAPKFolderTask]
            }
        }
    }
}

Update: gradle 3.1.x and higher require at least androidBuildToolsVersion 27, while Qt currently supports no higher than androidBuildToolsVersion 26, So practically may be its safer to fall back to gradle 3.0.x which supports build tools 26 It's also even possible to fall back to gradle 2.3.3 (use compile instead of implementation for FireBase and any required modules:
compile 'com.google.firebase:firebase-core:16.0.1'
...
Mohammad Kanan
  • 4,452
  • 10
  • 23
  • 47