0

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?

Roman Ozhegov
  • 231
  • 3
  • 15
  • You should paste your project file here (or link to the project if it is available on the internet), so we know what you tried to do exactly. – Christian Kandeler Jul 17 '18 at 15:50
  • Christian, at the moment I do a lot of things wrong. I'm just starting to work with QBS and android. I would like to get any example ("Hello world") in order to use it later for work. I know that you belong to the group of developers of this project (QBS) and would like to get a simple example that I could build for the android with QBS. I pray to share it. – Roman Ozhegov Jul 17 '18 at 15:59
  • There really isn't much to a Hello World project on the qbs side: You use the normal Android project structure (Java sources, assets, resources, manifest file etc) and point your qbs project to it. For instance, this is a qbs project file for one of the sample projects in the Android SDK: https://github.com/qbs/qbs/blob/master/tests/auto/blackbox/testdata-android/no-native/no-native.qbs. Then build it with a profile that you set up with the setup-android tool (https://doc.qt.io/qbs/cli-setup-android.html). – Christian Kandeler Jul 18 '18 at 08:13
  • Please see on Update to the question – Roman Ozhegov Jul 18 '18 at 10:21

3 Answers3

1

qmake has some built-in magic when building for Android, like using resources provided by Qt (including a manifest template) and running the android-deployqt tool. None of this is currently done by qbs.

  • This is very bad answer. Ok, I think I need made self some module for preparing android apk with Qbs with androiddeployqt.exe. In this case for what need AndroidApk Item in Qbs – Roman Ozhegov Jul 18 '18 at 14:23
0

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;
            }
        }
    }
}
Roman Ozhegov
  • 231
  • 3
  • 15
0

QBS 1.13, released on February this year (2019) makes deploying an Android application as simple as with qmake. In practice, you don't need to do anything special. For example, I took the contactlist application from the Qt examples and added this QBS file:

import qbs 1.0

Project {
    QtGuiApplication {
        name: "contactlist"
        install: true

        files: [
            "contactmodel.h",
            "contactmodel.cpp",
            "main.cpp",
        ]

        Group {
            files: [
                "*.qml",
                "designer/Backend/*.qml",
                "designer/Backend/qmldir",
            ]
            fileTags: ["qt.core.resource_data"]
        }

        Depends { name: "Qt.quick" }
    }
}

As you can see, there's nothing specific to Android here. The only trick I'm using is to assign the tag qt.core.resource_data to the QML files in order to have them compiled as resource files — but it's not even required.

With qbs run the application will be run in your connected Android device.

mardy
  • 164
  • 6