androidqtqbs

Qt QBS and android


I'm trying to find a simple tutorial: how to make a simple application for android using gbps. The following links were found:

  1. Stack oferflow. The answer to this question has not been received, although the version of the cbs has already been updated to 1.11 and the support of android is included.
  2. AndroidApk Item in QBS Documentation. In this case I get warning: '../Application/src/main/AndroidManifest.xml' does not exist.

I unfortunately could not find any new information. I ask for help.

Update: For Qmake I just create standard widget project like this one:

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = androidtest
TEMPLATE = app

DEFINES += QT_DEPRECATED_WARNINGS

SOURCES += \
        main.cpp \
        mainwindow.cpp

HEADERS += \
        mainwindow.h

FORMS += \
        mainwindow.ui

CONFIG += mobility
MOBILITY = 

And this is works and builds fine. QtCreator automatically create all necessary files and than run app on my phone

In Qbs I try to make same application. For this reason I have QBS-file:

import qbs

Project {
    CppApplication {
        name: "helloworld"

        Depends {
            name: "Qt"
            submodules: [
                "core",
                "widgets"
            ]
        }

        Depends { name: "Android.ndk" }
        Android.ndk.appStl: "gnustl_shared"

        Group {
            name: "src"
            files: [
                "main*.*"

            ]
        }
    }

    AndroidApk {
        name: "helloworld_android"
        Depends {name: "helloworld" }
        packageName: "com.example.android.helloworld"
    }
}

At the end I have Done with HelloWorld product (libhelloworld.so). But first error of "helloworld_android" is a fail at android manifest. This file is undefined. What I should do next?


Solution

  • Ok, I think I made it. It's not a good solution but this is work. Resulting APK you can find in "\install-root\$productName$\build\outputs\apk\$productName$-debug.apk

    import qbs
    import qbs.TextFile
    import qbs.Process
    import qbs.File
    
    Project {
        //Main Application
        CppApplication {
            name: "helloworld";
    
            Depends {
                name: "Qt"
                submodules: [
                    "core",
                    "widgets"
                ]
            }
    
            Depends { name: "Android.ndk" }
            Android.ndk.appStl: "gnustl_shared"
    
            Group {
                name: "src"
                files: [
                    "main*.*"
                ]
            }
            Group {
                qbs.install: true
                fileTagsFilter: "dynamiclibrary"
                qbs.installPrefix : product.name+"/libs/"+Android.ndk.abi+"/"
            }
        }
    
        //Preparation
        Product {
            name: "Prepared2Deploy"
            type: "prepared2deploy"
            Depends { name: "helloworld" }
            Depends { name: "Qt.core" }
            Depends { name: "Android.ndk" }
            Depends { name: "Android.sdk" }
            Rule {
                inputsFromDependencies: "installable"
                Artifact {
                    filePath: input.fileName+".json"
                    fileTags: "prepared2deploy"
                }
                prepare: {
                    var cmd = new JavaScriptCommand();
                    cmd.description = "prepare for androidDeployQt";
                    cmd.highlight = "install";
                    cmd.sourceCode = function() {
                        var outputFile = new TextFile(output.filePath, TextFile.WriteOnly);
                        outputFile.writeLine("{");
                        outputFile.writeLine("     \"qt\": \"" + product.Qt.core.binPath.replace(/\/bin$/,"") + "\",");
                        outputFile.writeLine("     \"sdk\": \"" + product.Android.sdk.sdkDir + "\",");
                        outputFile.writeLine("     \"sdkBuildToolsRevision\": \"" + product.Android.sdk.buildToolsVersion + "\",");
                        var ndkDir = product.Android.ndk.ndkDir.replace(/\\/g,"/"); //why sdk ndk get wrong slashes?
                        outputFile.writeLine("     \"ndk\": \""+ndkDir+"\",");
                        var toolchain =  product.cpp.toolchainPrefix.replace(/-$/,"");
                        outputFile.writeLine("     \"toolchain-prefix\": \"" + toolchain + "\",");
                        outputFile.writeLine("     \"tool-prefix\": \"" + toolchain + "\",");
                        outputFile.writeLine("     \"toolchain-version\": \"4.9\",");   //how I can get it ???
                        outputFile.writeLine("     \"ndk-host\": \"windows-x86_64\","); //how I can get it ???
                        var abi = product.Android.ndk.abi
                        outputFile.writeLine("     \"target-architecture\": \""+abi+"\",");
                        outputFile.writeLine("     \"stdcpp-path\": \""+ndkDir+"/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + //how I can get it ???
                                             abi+"/lib"+product.Android.ndk.appStl+".so\",");
                        outputFile.writeLine("     \"application-binary\": \""+ input.filePath+"\"");
                        outputFile.writeLine("}");
                        outputFile.close();
                    }
                    return cmd;
                }
            }
        }
        //Deployer
        Product {
            name: "AndroidDeployQt"
            Depends { name: "helloworld" }
            id: androidDeployQt
            type: "androidDeployQt"
            Depends {name: "Qt.core" }
    
            Rule {
                inputsFromDependencies: "prepared2deploy"
                alwaysRun: true
                Artifact {
                    filePath: "log.txt"
                    fileTags: "androidDeployQt"
                }
                prepare: {
                    var cmd = new JavaScriptCommand();
                    cmd.description = "androidDeployQt";
                    cmd.highlight = "install";
                    cmd.sourceCode = function() {
                        var logFile = new TextFile(output.filePath, TextFile.WriteOnly);
                        logFile.writeLine(input.fileName);
                        var productName = input.fileName.replace(/.so.json$/,"").replace(/^(lib)/,"");
                        var androidDeployProcess = new Process();
                        var exitCode = androidDeployProcess.exec(product.Qt.core.binPath+"/androiddeployqt.exe",
                                                                 [
                                                                     "--input", input.filePath,
                                                                     "--output", project.buildDirectory+"/install-root/"+productName,
                                                                     "--android-platform", "android-25", //???
                                                                     "--gradle"
                                                                 ])
                        if (exitCode) {
                            console.error("Error at androidDeployProcess. Error code: "+exitCode);
                            console.error(androidDeployProcess.readStdErr());
                            console.error("FULL_LOG: ");
                            console.error(androidDeployProcess.readStdOut());
                        }
                        logFile.close();
                    }
                    return cmd;
                }
            }
        }
    }