Why bother
Building your application for the desktop platform may sound like a waste of time at first glance, but it has several advantages that, in my opinion, outweighs the additional cost :
- debug experience. Debugging in the phone works, but is not optimal. Debugging code that runs of your computer, however, is usually a far better experience
- faster “build and test” workflow. Compiling and deploying the app on phone, or
on emulator, takes around thirty seconds, building the rpm, deploying. And that’s excluding additional compilation time. That’s a looooong time, compared to nearly instant run on desktop - better separation of logic / interface. Because you will have to develop two interfaces, you will put more logic where it belongs (in
C++
) - unit testing. Much simpler to run locally than on a remote device
- qml live bench allows quickly deploy any change in qml. Once the app is working
for desktop, writing the qml files is easy and quick to test - as a bonus, you get a working desktop app !
Prerequisites
- a linux computer with sailfish sdk installed
- a Qt development environment (for debian based distro,
apt install qttools5-dev
). I recommend against using a recent version of Qt if possible, because the version on SFOS is quite old -
cmake
(this should be possible as well usingqmake
, but i don’t know how) - Basic knowledge of
C++
and application development
Step-by-step
Creating the project
The first step consists of creating an empty project. This can be done using qtcreator,
or using the sfdk
tool:
# go to your project base directory, create an empty directory for it
mkdir Tutorial
cd Tutorial
~/SailfishOS/bin/sfdk init -b cmake Tutorial -t qtquick2app
This creates a CMakeLists.txt
file in the current directory, with a demo application.
This file is currently not suitable for desktop compilation. Let’s fix that a bit.
Adapting the CMakeLists file
The first thing is to check whether we are building for SFOS, or for desktop. We could
use a variable, but it’s better to do it automagically. The cmake file contains the
following line:
pkg_search_module(SAILFISH sailfishapp)
This means we can test if we are building for SFOS by testing the SAILFISH_FOUND
variable (see cmake documentation for details on this). So, let’s use this and
complete things a bit:
if (${SAILFISH_FOUND})
set(BUILD_FOR_SAILFISH ON)
message("Build for sailfish os")
add_compile_definitions(SAILFISH_BUILD)
set(AppName "harbour-tutorial") # we wish to publish on harbour
set(QML_RESOURCES_FILE)
set(Qt5Test_FOUND OFF) # no unit tests for sailfish
else()
set(BUILD_FOR_SAILFISH OFF)
message("Building for desktop")
find_package(Qt5 COMPONENTS QuickControls2 REQUIRED) # we want qtquickcontrols for desktop interface
set(CMAKE_AUTORCC ON) # we'll use a qrc file for qml
set(QML_RESOURCES_FILE qml_desktop/qml.qrc)
set(AppName "Tutorial")
enable_testing() # we want to enable unit testing
find_package(Qt5Test)
endif()
And modify our target to include the qrc file :
add_executable(Tutorial·src/Tutorial.cpp ${QML_RESOURCE_FILE})
This setup two different type of compilation, and a definition that we can use in
our C++
code to check the target we are building for (SAILFISH_BUILD
).
We now need to create a qrc file, and include our desktop qml files. See any QtQuick Controls
tutorial for this.
Adapting the main
We need to adapt the main file as well, because currently it will not compile for
a desktop platform, since the sailfish headers are missing. We need to replace:
#include <sailfishapp.h>
by
#if defined(SAILFISH_BUILD)
#include <sailfishapp.h>
#else
#include <QQmlApplicationEngine>
#endif
#include <QGuiApplication>
#include <QQmlContext>
#include <QQuickView>
#include <QtQml>
Which include required qml headers (not all may be required, depending on your app,
but for most app this set will be the minimum).
We need to fix the main()
function as well. Replace:
return SailfishApp::main(argc, argv);
by
#if defined(SAILFISH_BUILD)
return SailfishApp::main(argc, argv)
#else
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/Tutorial.qml"));
engine.load(url);
return QCoreApplication::exec();
#endif
Compile and run
Using Qt creator, enable a desktop kit, and compile and run your app. Enjoy fast compile and launch times, and no frustration by waiting for the deploy step.
Develop your app, prototype some desktop interface with QtQuick Controls. Test it. Once you know your C++
code is working, start developing the SFOS interface in qml, using qml live bench (and enjoy fast updates too).