The Mer Wiki now uses your Mer user account and password (create account on https://bugs.merproject.org/)


Nemo/Qt5Porting

From Mer Wiki
< Nemo(Difference between revisions)
Jump to: navigation, search
(Approach)
(Packaging setup)
 
(174 intermediate revisions by 13 users not shown)
Line 1: Line 1:
 
= Introduction =
 
= Introduction =
  
Nemo needs to be ready for Qt 5. This page attempts to document some information on how we're approaching that, as well as common hurdles and approaches.
+
Nemo needs to be ready for Qt 5. This page attempts to document some information on how we're addressing that, as well as common hurdles and approaches.
  
 
= Approach =
 
= Approach =
  
With the advent of webhooks, we are now able to easily build software we maintain on OBS just with git interaction. Luckily, it also gives us the capability to build a single source repository in multiple places, possibly with different spec files. We're taking advantage of this to (where possible) to ports in-place by adding qt5 packaging, and hacking the build system and code to handle that conditionally where possible.
+
With the advent of webhooks, we are now able to easily build software we maintain on OBS just with git interaction. Luckily, it also gives us the capability to build a single source repository in multiple places, possibly with different spec files. We're taking advantage of this to (where possible) do ports in-place by adding qt5 packaging, and hacking the build system and code to handle that conditionally where possible.
  
 
NB: this document does not attempt to handle porting of software we do not maintain. Yet.
 
NB: this document does not attempt to handle porting of software we do not maintain. Yet.
Line 18: Line 18:
 
* Split your work into multiple small commits rather than one gigantic "Port to Qt 5" commit, unless the changes are tiny.
 
* Split your work into multiple small commits rather than one gigantic "Port to Qt 5" commit, unless the changes are tiny.
  
= Initial setup =
+
= Packaging setup =
  
Make sure the project has been set up for git packaging:
+
Make sure the project has been set up for git packaging (a good read: [[Nemo/Development#Setting_up_a_webhook_to_github|Setting up a webhook to github]]):
  
 
* Check it has a webhook in https://webhook.merproject.org/webhook/
 
* Check it has a webhook in https://webhook.merproject.org/webhook/
Line 31: Line 31:
 
Then:
 
Then:
  
* Add a new set of packaging following the name convention as follows: libfoo-qt => libfoo-qt5, libfoo => libfoo5
+
* Add a new set of packaging following the name convention as follows: libfoo-qt => libfoo-qt5, libfoo => libfoo-qt5
 
* Add dependencies to minimal needed Qt 5 modules (e.g. Qt5Core, Qt5Xml, etc in PkgConfigBR)
 
* Add dependencies to minimal needed Qt 5 modules (e.g. Qt5Core, Qt5Xml, etc in PkgConfigBR)
 
* Add a new webhook for it, building to package name following the above naming convention
 
* Add a new webhook for it, building to package name following the above naming convention
Line 43: Line 43:
 
* Binaries
 
* Binaries
 
* .pc files
 
* .pc files
* .prf files
 
 
* ... basically anything that gets installed.
 
* ... basically anything that gets installed.
 +
 +
For header files, you should send them to different directories. For instance, /usr/include/mlite, /usr/include/mlite5.
 +
 +
Note that you don't need to duplicate or rename:
 +
* QML imports or change their name
 +
* prf files
 +
 +
They are installed to a different location in Qt 4 and Qt 5.
  
 
Use constructs like the following to handle conditionals:
 
Use constructs like the following to handle conditionals:
Line 64: Line 71:
 
# include <QDeclarativeExtensionPlugin>
 
# include <QDeclarativeExtensionPlugin>
 
#endif</pre>
 
#endif</pre>
 +
 +
Q_INTERFACES() is a little tricky.  In order to allow this to be handled in both Qt 4 and Qt 5 a version macro is needed which can be handled by the very limited preprocessor in Qt 4 moc:
 +
 +
<pre>equals(QT_MAJOR_VERSION, 5): DEFINES += QT_VERSION_5</pre>
 +
 +
This then allows creation of code that works for both Qt 4 and 5 (which has a better preprocessor in moc):
 +
 +
<pre>#include <QtGlobal>
 +
#if QT_VERSION_5
 +
#include <QtQml>
 +
#include <QQmlParserStatus>
 +
#define QDeclarativeParserStatus QQmlParserStatus
 +
#else
 +
#include <qdeclarative.h>
 +
#include <QDeclarativeParserStatus>
 +
#endif
 +
 +
class MyObject : public QObject, public QDeclarativeParserStatus
 +
{
 +
    Q_OBJECT
 +
    Q_INTERFACES(QDeclarativeParserStatus)
 +
...
 +
}</pre>
  
 
= Porting Code =
 
= Porting Code =
Line 69: Line 99:
 
This doesn't exist in Qt 5. Qt 5's locale for C strings is always UTF-8. You'll need to reencode the strings if they aren't in UTF-8, or ifdef the locale forcing if they are, like so:
 
This doesn't exist in Qt 5. Qt 5's locale for C strings is always UTF-8. You'll need to reencode the strings if they aren't in UTF-8, or ifdef the locale forcing if they are, like so:
  
<pre>+#if QT_VERSION < QT_CHECK_VERSION(5, 0, 0)
+
<pre>+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
 
     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
 
     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
 
+#endif</pre>
 
+#endif</pre>
 +
 +
== toAscii / fromAscii ==
 +
These are gone. You probably want toLatin1 / fromLatin1. If you were using a custom C codec (see above) then you're probably screwed and will need to use QTextCodec yourself.
  
 
== QApplication ==
 
== QApplication ==
 
You should avoid using this. It lives in QtWidgets. Use QGuiApplication from QtGui instead, or - even better - QCoreApplication from QtCore.
 
You should avoid using this. It lives in QtWidgets. Use QGuiApplication from QtGui instead, or - even better - QCoreApplication from QtCore.
  
= Ports in progress =
+
= Qt 5 porting documentation =
  
* libmlocale (w00t)
+
Qt 5 Porting Guide
 +
http://qt-project.org/doc/qt-5.0/qtdoc/portingguide.html
  
= Things that have been ported =
+
The Transition from Qt 4.x to Qt 5
 +
http://qt-project.org/wiki/Transition_from_Qt_4.x_to_Qt5
  
 +
KDAB Porting from Qt 4 to Qt 5 article
 +
http://www.kdab.com/porting-from-qt-4-to-qt-5
 +
 +
Qt API changes
 +
http://qt.gitorious.org/qt/qtbase/blobs/HEAD/dist/changes-5.0.0
 +
 +
= Porting whiteboard =
 +
== SDK issues ==
 +
Note that Mer SDK cannot parallel install Qt 4 and Qt 5 yet. Next mer release fixes that.
 +
 +
Note that we need to use %qmake5 (spec) for Qt 5 packaging. Spectacle has been patched to allow qmake5 as builder in yaml, and will be released soon: https://gitorious.org/meego-developer-tools/spectacle/
 +
 +
== nemo-qml-plugins ==
 +
This is going to be split into multiple packages that we can then independently split instead of the current gigantic monster.
 +
 +
== contextkit ==
 +
We hope to not port this, and use statefs instead.
 +
 +
== kcalcore ==
 +
We need to investigate upstream kcalcore vs the MeeGo fork and decide which to use.
 +
 +
== libjollasignonuiservice ==
 +
 +
The library requires X11 for web view embedding unless SIGNON_UI_NO_EMBED_WEBVIEW is defined. Investigate how to achieve the same or is it even needed. Can we use SIGNON_UI_NO_EMBED_WEBVIEW for now?
 +
 +
== Things that are not yet/currently being ported ==
 +
 +
* signon-plugin-oauth2
 +
* mthemedaemon
 +
* meego-handset-camera
 +
* tracker
 +
* qmlnotes
 +
* tumbler (Note: only one plugin in the tumbler package uses Qt; it should ideally be split out to another package)
 +
 +
== Ports in progress ==
 +
 +
Add stuff you're working on to stop someone else picking it.
 +
 +
* nemo-qml-plugins (w00t)
 +
* timed (PMG)
 +
* lipstick (vesuri) - split into Qt4 and Qt5 paths, allows lipstick-jolla-home to run on Wayland. Some packaging improvements TBD.
 +
* qmlpinquery (lpotter)
 +
* libcommhistory (special)
 +
 +
== Things that have been ported ==
 +
 +
Move stuff that is already finished here.
 +
 +
* libcontentaction (w00t)
 
* libmlite (w00t)
 
* libmlite (w00t)
 
* libngf-qt (w00t)
 
* libngf-qt (w00t)
 +
* libmlocale (w00t)
 +
* libprofile-qt (vesuri)
 +
* libaccounts-qt (vesuri)
 +
* libbluez-qt (mjones)
 +
* quillmetadata (mjones)
 +
* libsignon (vesuri)
 +
* eventfeed (vesuri)
 +
* nemo-qml-plugin-time (mjones)
 +
* nemo-qml-plugin-alarms (mjones)
 +
* nemo-qml-plugin-utilities (mjones)
 +
* sensorfw (lpotter)
 +
* libconnman-qt (lpotter)
 +
* qofono (lpotter)
 +
* qmsystem (vesuri)
 +
* libresourceqt (mjones)
 +
* kcalcore (mjones)
 +
* mkcal (mjones)
 +
* connectionagent (lpotter)
 +
* qmf (VDVsx)
 +
* libqtsparql (mvogt)
 +
* nemo-transferengine (vesuri)
 +
* nemo-qml-plugin-contextkit (dez)
 +
* mapplauncherd (special)
 +
* nemo-qml-plugin-configuration (mjones)
 +
* nemo-qml-plugin-dbus (mjones)
 +
* nemo-qml-plugin-accounts (mjones)
 +
* nemo-qml-plugin-signon (mjones)
 +
* nemo-qml-plugin-calendar (mjones)
 +
* nemo-qml-plugin-social (mjones)
 +
* nemo-qml-plugin-email (VDVsx)
 +
* qtcontacts-sqlite (mvogt)
 +
* maliit-framework/plugins (pvuorela)
 +
* nemo-qml-plugin-grilo (denexter)
 +
* nemo-qml-plugin-thumbnailer (denexter)
 +
* nemo-qml-plugin-contacts (mvogt)
 +
* contactsd (mvogt)
 +
* ssu (aard; qt5 only)
 +
* commhistory-daemon (mvogt)
 +
* nemo-qml-plugin-notifications (mjones)
 +
* quillimagefilters (mvogt)
 +
* nemo-qml-plugin-messages-internal (special)
 +
* voicecall (special)
 +
* qt-components (w00t)
 +
* fingerterm (using QtQuick1) (Aard)
 +
* buteo-mtp (Qt5 only) (Aard)
 +
* buteo-syncml (Aard)
 +
* buteo-sync-plugins (Aard)
 +
* buteo-syncfw (Aard)
 +
 +
== Things that shouldn't be ported ==
 +
 +
* qtcontacts-tracker (to be replaced with qtcontacts-sqlite)
 +
* libqtsparql-tracker-extensions (qtcontacts-tracker dependency only)
 +
* libcubi (qtcontacts-tracker dependency only)
 +
* libcubi-tracker-ontologies (qtcontacts-tracker dependency only)
 +
* libqttracker (no dependencies)
 +
* libmeegotouch
 +
* contextkit (hopefully replaced by statefs)
 +
* meegotouch-compositor

Latest revision as of 12:25, 2 August 2013

Contents

[edit] Introduction

Nemo needs to be ready for Qt 5. This page attempts to document some information on how we're addressing that, as well as common hurdles and approaches.

[edit] Approach

With the advent of webhooks, we are now able to easily build software we maintain on OBS just with git interaction. Luckily, it also gives us the capability to build a single source repository in multiple places, possibly with different spec files. We're taking advantage of this to (where possible) do ports in-place by adding qt5 packaging, and hacking the build system and code to handle that conditionally where possible.

NB: this document does not attempt to handle porting of software we do not maintain. Yet.

Rules of thumb/tips:

  • Keep the ports in-place where possible! Same source tree and branch as the qt4 version. If this isn't possible, talk to someone (i.e. w00t) about why to make sure it isn't, and let's figure out an alternative strategy.
  • Keep the ports minimal: use ifdefs and defines to minimize the pain in fairly central places (see below for some examples). This avoids you accidentally breaking something and keeps the maintenance cost minimal.
  • While you're porting, examine opportunities to minimize dependencies. Some code pulls in all sorts of crazy crap (an example: libmlocale pulled *everything in Qt* into the QT variable, even though it used basically none of it.)
  • Avoid linking to QtWidgets. It's heavy, and we want to not have it.
  • Avoid scope creep: port one thing at a time. When you get to an error, grep around for other instances, and fix them. Resist the urge to fix things that are not part of the port. File bugs or come back to it later.
  • Split your work into multiple small commits rather than one gigantic "Port to Qt 5" commit, unless the changes are tiny.

[edit] Packaging setup

Make sure the project has been set up for git packaging (a good read: Setting up a webhook to github):

If these steps aren't OK, then fix it. If you don't know how, talk to w00t.

Then:

  • Add a new set of packaging following the name convention as follows: libfoo-qt => libfoo-qt5, libfoo => libfoo-qt5
  • Add dependencies to minimal needed Qt 5 modules (e.g. Qt5Core, Qt5Xml, etc in PkgConfigBR)
  • Add a new webhook for it, building to package name following the above naming convention
  • Start hacking using mb to build the new packaging

[edit] Build System

Qt 4 and 5 packages *must* be parallel-installable, both for images, and for SDK purposes. This means that you'll need to rename:

  • Libraries
  • Binaries
  • .pc files
  • ... basically anything that gets installed.

For header files, you should send them to different directories. For instance, /usr/include/mlite, /usr/include/mlite5.

Note that you don't need to duplicate or rename:

  • QML imports or change their name
  • prf files

They are installed to a different location in Qt 4 and Qt 5.

Use constructs like the following to handle conditionals:

equals(QT_MAJOR_VERSION, 4): TARGET = foo
equals(QT_MAJOR_VERSION, 5): TARGET = foo5

Use QT_VERSION and QT_VERSION_CHECK in code, like this:

#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
# include <QtQml>
# include <QQmlEngine>
# include <QQmlExtensionPlugin>
# define QDeclarativeEngine QQmlEngine
# define QDeclarativeExtensionPlugin QQmlExtensionPlugin
#else
# include <QtDeclarative>
# include <QDeclarativeEngine>
# include <QDeclarativeExtensionPlugin>
#endif

Q_INTERFACES() is a little tricky. In order to allow this to be handled in both Qt 4 and Qt 5 a version macro is needed which can be handled by the very limited preprocessor in Qt 4 moc:

equals(QT_MAJOR_VERSION, 5): DEFINES += QT_VERSION_5

This then allows creation of code that works for both Qt 4 and 5 (which has a better preprocessor in moc):

#include <QtGlobal>
#if QT_VERSION_5
#include <QtQml>
#include <QQmlParserStatus>
#define QDeclarativeParserStatus QQmlParserStatus
#else
#include <qdeclarative.h>
#include <QDeclarativeParserStatus>
#endif

class MyObject : public QObject, public QDeclarativeParserStatus
{
    Q_OBJECT
    Q_INTERFACES(QDeclarativeParserStatus)
...
}

[edit] Porting Code

[edit] setCodecForCStrings / codecForCStrings

This doesn't exist in Qt 5. Qt 5's locale for C strings is always UTF-8. You'll need to reencode the strings if they aren't in UTF-8, or ifdef the locale forcing if they are, like so:

+#if QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
     QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+#endif

[edit] toAscii / fromAscii

These are gone. You probably want toLatin1 / fromLatin1. If you were using a custom C codec (see above) then you're probably screwed and will need to use QTextCodec yourself.

[edit] QApplication

You should avoid using this. It lives in QtWidgets. Use QGuiApplication from QtGui instead, or - even better - QCoreApplication from QtCore.

[edit] Qt 5 porting documentation

Qt 5 Porting Guide http://qt-project.org/doc/qt-5.0/qtdoc/portingguide.html

The Transition from Qt 4.x to Qt 5 http://qt-project.org/wiki/Transition_from_Qt_4.x_to_Qt5

KDAB Porting from Qt 4 to Qt 5 article http://www.kdab.com/porting-from-qt-4-to-qt-5

Qt API changes http://qt.gitorious.org/qt/qtbase/blobs/HEAD/dist/changes-5.0.0

[edit] Porting whiteboard

[edit] SDK issues

Note that Mer SDK cannot parallel install Qt 4 and Qt 5 yet. Next mer release fixes that.

Note that we need to use %qmake5 (spec) for Qt 5 packaging. Spectacle has been patched to allow qmake5 as builder in yaml, and will be released soon: https://gitorious.org/meego-developer-tools/spectacle/

[edit] nemo-qml-plugins

This is going to be split into multiple packages that we can then independently split instead of the current gigantic monster.

[edit] contextkit

We hope to not port this, and use statefs instead.

[edit] kcalcore

We need to investigate upstream kcalcore vs the MeeGo fork and decide which to use.

[edit] libjollasignonuiservice

The library requires X11 for web view embedding unless SIGNON_UI_NO_EMBED_WEBVIEW is defined. Investigate how to achieve the same or is it even needed. Can we use SIGNON_UI_NO_EMBED_WEBVIEW for now?

[edit] Things that are not yet/currently being ported

  • signon-plugin-oauth2
  • mthemedaemon
  • meego-handset-camera
  • tracker
  • qmlnotes
  • tumbler (Note: only one plugin in the tumbler package uses Qt; it should ideally be split out to another package)

[edit] Ports in progress

Add stuff you're working on to stop someone else picking it.

  • nemo-qml-plugins (w00t)
  • timed (PMG)
  • lipstick (vesuri) - split into Qt4 and Qt5 paths, allows lipstick-jolla-home to run on Wayland. Some packaging improvements TBD.
  • qmlpinquery (lpotter)
  • libcommhistory (special)

[edit] Things that have been ported

Move stuff that is already finished here.

  • libcontentaction (w00t)
  • libmlite (w00t)
  • libngf-qt (w00t)
  • libmlocale (w00t)
  • libprofile-qt (vesuri)
  • libaccounts-qt (vesuri)
  • libbluez-qt (mjones)
  • quillmetadata (mjones)
  • libsignon (vesuri)
  • eventfeed (vesuri)
  • nemo-qml-plugin-time (mjones)
  • nemo-qml-plugin-alarms (mjones)
  • nemo-qml-plugin-utilities (mjones)
  • sensorfw (lpotter)
  • libconnman-qt (lpotter)
  • qofono (lpotter)
  • qmsystem (vesuri)
  • libresourceqt (mjones)
  • kcalcore (mjones)
  • mkcal (mjones)
  • connectionagent (lpotter)
  • qmf (VDVsx)
  • libqtsparql (mvogt)
  • nemo-transferengine (vesuri)
  • nemo-qml-plugin-contextkit (dez)
  • mapplauncherd (special)
  • nemo-qml-plugin-configuration (mjones)
  • nemo-qml-plugin-dbus (mjones)
  • nemo-qml-plugin-accounts (mjones)
  • nemo-qml-plugin-signon (mjones)
  • nemo-qml-plugin-calendar (mjones)
  • nemo-qml-plugin-social (mjones)
  • nemo-qml-plugin-email (VDVsx)
  • qtcontacts-sqlite (mvogt)
  • maliit-framework/plugins (pvuorela)
  • nemo-qml-plugin-grilo (denexter)
  • nemo-qml-plugin-thumbnailer (denexter)
  • nemo-qml-plugin-contacts (mvogt)
  • contactsd (mvogt)
  • ssu (aard; qt5 only)
  • commhistory-daemon (mvogt)
  • nemo-qml-plugin-notifications (mjones)
  • quillimagefilters (mvogt)
  • nemo-qml-plugin-messages-internal (special)
  • voicecall (special)
  • qt-components (w00t)
  • fingerterm (using QtQuick1) (Aard)
  • buteo-mtp (Qt5 only) (Aard)
  • buteo-syncml (Aard)
  • buteo-sync-plugins (Aard)
  • buteo-syncfw (Aard)

[edit] Things that shouldn't be ported

  • qtcontacts-tracker (to be replaced with qtcontacts-sqlite)
  • libqtsparql-tracker-extensions (qtcontacts-tracker dependency only)
  • libcubi (qtcontacts-tracker dependency only)
  • libcubi-tracker-ontologies (qtcontacts-tracker dependency only)
  • libqttracker (no dependencies)
  • libmeegotouch
  • contextkit (hopefully replaced by statefs)
  • meegotouch-compositor
Personal tools