KISS

Keep It Simple Stupid

Making Symbian project's deployment faster

| comments

Some time ago I was working on a project for Symbian OS. Qt framework was used as the base. Unfortunately, the deployment time was very big, approximately 10 minutes to copy and install the 10MB app on a Symbian device. Doing that every time you change something and want to test it is a complete waste of time. Therefore, a hack had to be invented.

My hack consists of three parts:

Part 1

In the project’s .pro file there is the DEPLOYMENTFOLDERS variable that specifies which files from your project need to be included in the final .sis package. You need to comment it out so that the package will become much lighter. In my case, the size dropped from 10 MB to 1 MB, which significantly sped up the deployment time to about a minute.

Part 2

So, no more resources in the package. But how is the app supposed to work with them then? Firstly, copy the required resources to the memory card via a file manager. Let’s assume they are in e:/App/ directory.

Secondly, I’ve created a dedicated file for one important function that abstracts the rest of the program from where the resources actually are. Here’s the source:

respath.h
1
2
3
4
5
6
7
8
9
10
11
12
#ifndef RESPATH_H
#define RESPATH_H

#include <QString>

/*
  Returns the full path to the specified resource.
  relPath should use '/' as dir separators.
*/
QString resPath(const QString &relPath);

#endif // RESPATH_H
respath.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "respath.h"

#include <QDir>
#include <QtDebug>

/* NB! This variable specifies the path to app resources.

    When creating a build, it is set to QDir::currentPath() and
    DEPLOYMENTFOLDERS variable should be on in the .pro file.

    But to test the app on the device, due to the very slow
    process of copying and installing the package, set it to an
    arbitrary directory on it and copy the resources
    yourself. The list of required resources is defined
    by DEPLOYMENTFOLDERS variable in the .pro file. Also,
    don't forget to comment that variable so that sis file
    will not contain the resources.
*/
QString RES_PATH;
const QString TESTING_RES_PATH = "e:/App/"; // look for a related comment below

QString resPath(const QString &relPath)
{
    if (RES_PATH.isNull())
    {
        RES_PATH = QDir::currentPath() + '/';
        QDir dir(RES_PATH);
        // fix for Qt simulator on Mac OS
        if (dir.dirName() == "MacOS") { dir.setPath(RES_PATH + "/../Resources"); RES_PATH = dir.absolutePath() + '/'; }

        // fix for device when DEPLOYMENTFOLDERS is commented
// NB! TESTING_RES_PATH: Uncomment the following line to set it
//        else if (RES_PATH.contains(":/Private/")) RES_PATH = TESTING_RES_PATH;

        qDebug() << "RES_PATH=" << RES_PATH;
    }

    return QDir::toNativeSeparators(RES_PATH + relPath);
}

Part 3

And the last part, whenever the program needs to work with a resource file use the resPath() function. Say, to open a database:

Using resPath() method to open a database
1
2
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName(resPath("database_name.sqlite"));

To sum up, having done all the steps, to turn on the hack: 1. comment the DEPLOYMENTFOLDERS directive in the .pro file; and 2. uncomment the line after the // NB! comment in respath.cpp. You’re all set.

It’s now much more comfortable and faster to test the app on a device. If you know any simpler or just different solution, please let me know.

Comments