QtQuick: Why bother with QML?

December 21, 2011

This post is an introduction to the next several posts. If you’re bored with QtQuick introductions (since there are many)… then there’s probably nothing to see here.

Composite (and its ancestor Hydrogen) has always had a Qt UI. And when it comes to GUI, Qt is the toolkit that I prefer to use. Why Because I really don’t like UI development. I like to work on models, business logic, complex calculations, etc. I really get bored with sizing widgets and trying to figure out how to convince the font system to give you the real, actual, true bounding rectangle (and not the one that’s better for typesetting).

And then there’s the code. The options have always been something like:

  • Use a C API like GTK+ and write gobs of code and manually
    type all the gtk_widget_* namespaces for every class method.
  • Use a C++ API wripper like gtkmm (which never really gets
    rid of the smell of the C API).
  • Write gobs of Qt code to express your UI. Which means that
    small changes (like moving a widget from here to there) often
    require a lot of code changes.
  • Use a UI designer to create XML files that get processed into
    code. (I.e. Qt Designer or Glade.) While it’s easy, these
    files often have compatibility issues even across minor
    releases. They also are not very diff friendly (which is
    important to a backend-loving code monkey like me).
  • Write your UI in a scripting language like Tcl/Tk or Python
    (e.g. the PySide bindings). Here you trade-off flexibility
    for simplicity a lot of the time. (Think: custom widgets.)

These options all have one thing in common: they suck.

Along comes QtQuick, with the idea of expressing your UI in a scripting language called QML. QML is:

  • Like javascript and CSS: so it looks like code, and diff’s like code.
  • Declarative/Interpretive: so small changes just require that I refresh the QML file in question… not recompile (or even restart) my whole application.
  • Designer-friendly: if your project has an artist, they probably aren’t very good at C++. QML isn’t too difficult to parse… which makes them more productive.
  • Developer-friendly: as a C++ lover I’m not crazy about the syntax of QML… but I love that I can throw up a UI pretty quick. While the UI’s that I design look like butt… I don’t feel like I have invested a lot of code into something that needs to change (and change a lot) later in the project.
  • Architecture-friendly: It more or less enforces that you use a model/view architecture in your application. When the UI was code, it’s very tempting to pragmatically break the rules.
  • Prototype-friendly: You can add some logic into the QML via JavaScript, which means you can prototype the UI’s behavior without having to invest any C++ code.
  • Promising: The Qt framework is reorganizing itself around QML. It’s pretty fast now, but it promises to be blazing fast in Qt 5. (Even faster than using native widgets or QGraphicsView… and that’s an impressive accomplishment.)

However, it does come with a few drawbacks:

  • It’s oriented to embedded devices that have a fixed-size, full-screen “app” paradigm. Therefore, you’ll find that lots of sizes and relationships are set in fixed-size pixels. It’s not quite as nice as QLayout in C++. This means it’s still a little… primative in a desktop context.
  • The scripting language is kind of… strange. It is very weakly typed (e.g. inspecting the code you can’t be sure if a symbol is a property or a method or a signal or an element or a reference to a C++ class). This is really, really confusing.
  • The language uses a sort of “inner class” idiom like in Java.
  • It’s interpreted, so typos likemy_symbol/mySymbol will not be detected until run-time. (In fact, this is a drawback of Qt signals/slots as a whole.)
  • Concepts like QAction and QMenu are missing, and will probably never be added. They’ve been branded as obsolete, old thinking with respect to UI design. While I don’t necessarily disagree… the loss of them takes some getting used to.
  • It’s new, and the documentation is still developing. For example, none of the examples that I could find show any sort of in-depth C++/QML interaction. Most of the examples use JavaScript to implement the application logic.

All in all, I think that the good out-weighs the bad.

Since I don’t know how to use QML effectively, the following few blogs will share my journey and what I’ve learned. I’ll do so by writing a very simple calculator application.

That’s also the caveat: I’m writing this as I go… so I probably just said something dumb. ūüôā

In seeking to continue Composite¬†development, I needed a multi-touch environment. ¬†All along, I figured that MeeGo would be that environment. ¬†But the death of MeeGo means that this is no longer an attractive option. ¬†I could do it, but it would be a stagnant OS, forever stuck at release 1.2.0. ¬†I don’t want this for a development environment.

But as far as I know, MeeGo is still the only distro that gives you an out-of-the-box multi-touch experience.

Whatever distro I choose, I’ll need to fiddle with the Qt and Xorg packages on the system. ¬†This is best done by creating new packages to replace the system ones (just in case you mess everything up, you can just revert back the package). ¬†I chose Fedora because it tracks upstream projects very well, and also because I find RPM packaging much more enjoyable than DEB packaging.[2]

Here’s how I got a multi-touch-enabled Qt installed and working on Fedora 16. ¬†I installed the 64-bit OS on my IdeaPad, so replace “x86_64” with “x86” if you’re using the 32-bit version.

Prerequisites

If you don’t know how to install a Linux distro, fire off commands on a command line, or boot to single-user mode and fix a couple things — then this will probably be too much for you to take on. (E.g. if you just Googled “single-user mode” — STOP NOW! :-))

After installing Fedora 16, you need to set it up for building rpms. I didn’t keep good notes during this phase, so this is probably not complete:

    $ sudo yum groups install \
        "Development Tools" \
        "X Software Development"
    $ mkdir ~/rpmbuild
    $ cd ~/rpmbuild
    $ mkdir BUILD BUILDROOT SOURCES SPECS RPMS SRPMS

Building the MTEV driver

The X11 input driver “mtev” is an interim solution to get multi-touch onto Linux devices like the N900, WeTab, N950, N9, etc. When XInput 2.2 finally hits the main-stream with a matching evdev driver, it will be obsolete.[4]

First, grab the sources and install the mtdev library:

    $ cd ~/code
    $ git clone git://gitorious.org/gabrbedd/xorg-x11-drv-mtev.git
    $ sudo yum install mtdev-devel

Note that the tarball you need is already in the repository. Also, this has been modified to (a) compile with the 1.11 xserver and (b) it includes my right-click-emulation patch. If you don’t like it… choose the version you want with git.

Build it like this:

    $ cd ~/rpmbuild
    $ cp -f ~/code/xorg-x11-drv-mtev/* SOURCES/
    $ mv -f SOURCES/xorg-x11-drv-mtev.spec SPECS/
    $ rpmbuild -ba SPECS/xorg-x11-drv-mtev.spec 2>&1 | log-50

It only takes a few seconds to build. Then you can install it like this:

    $ sudo rpm -Uvh RPMS/x86_64/xorg-x11-drv-mtev-0.1.13-10.0.x86_64.rpm

Building Qt with Multi-Touch

On my IdeaPad, Qt takes about 9 or 10 hours to compile.  If you have a fast machine with F16, I recommend doing it there.

Start by checking out my source repository and grabbing the Qt sources that you need. ¬†(Note, if the URL’s are cut off in your browser… there are links near the end of the article. ¬†See “Resources.”)

    $ mkdir ~/code
    $ cd ~/code
    $ git clone git://gitorious.org/gabrbedd/fedora-pkg-qt.git
    $ cd fedora-pkg-qt
    $ git checkout topic/multitouch-00
    $ wget http://get.qt.nokia.com/qt/source/qt-everywhere-opensource-src-4.8.0.tar.gz
    $ wget http://pkgs.fedoraproject.org/repo/pkgs/qt4/hi128-app-qt4-logo.png/d9f511e4b51983b4e10eb58b320416d5/hi128-app-qt4-logo.png
    $ wget http://pkgs.fedoraproject.org/repo/pkgs/qt4/hi48-app-qt4-logo.png/6dcc0672ff9e60a6b83f95c5f42bec5b/hi48-app-qt4-logo.png">hi48-app-qt4-logo.png

Now you can build it like this:

    $ cd ~/rpmbuild
    $ cp -f ~/code/fedora-pkg-qt/* SOURCES/
    $ mv -i SOURCES/qt.spec SPECS/
    $ rpmbuild -ba SPECS/qt.spec 2>&1 | tee log-00

Chances are that rpmbuild will choke on you, saying that you’re missing several required packages. You will need to install those. For example if it says that it needs “pkgconfig(foo)”, you can install it like this:

    $ sudo yum install "pkgconfig(foo)"

When done, install the packages in RPMS/. You probably want to do this:

    $ cd RPMS/x86_64/
    $ sudo rpm -Uvh qt{,-x11,-examples,-devel,-demos}-4.8.0-1.1.fc16.x86_64.rpm

To see which Qt packages you already have on your system, do:

    $ rpm -qa | grep qt

You only need to replace the ones that have a “4.8.0” version.

Verifying that it works

Reboot your computer and verify that it works. Run:

    $ /usr/lib64/qt4/examples/touch/fingerpaint/fingerpaint

If you can use 2 fingers to draw, then you are good to go! ūüôā

Troubleshooting

X11 Fails to Start

If you reboot to a black screen, chances are that the MTEV driver is not kosher. Reboot to single-user mode and uninstall it.

    $ rpm -ev xorg-x11-drv-mtev

If you want to debug this… go right ahead. Chances are that its a failure in the driver’s PreInit() or something. However, I’m not going to be able to support you much with this.

No Multi-Touch

Do not be alarmed! Because this is driver is kind of a hack, you have to explicitly declare that the device should be managed by the mtev driver. xorg.conf.d files are installed for Cando, Sitronix, Hanvon, and ILI touchscreens. You might have a different one.

You can find out for sure by inspecting /var/log/Xorg.0.log. You should see something like:

[    26.125] (II) Using input driver 'mtev' for 'Cando Corporation Cando 10.1 Multi Touch Panel with Controller'

This was arranged by the /etc/X11/xorg.conf.d/60-cando-mtev.conf file, which looks like this:

Section "InputClass"
        Identifier              "Cando Multi Touch Panel"
        MatchVendor 		"Cando"
        MatchDevicePath 	"/dev/input/event*"
        Driver                  "mtev"
        Option                  "Ignore"                "off"
EndSection

Your touchscreen device will need a different Identifier and MatchVendor string. Inspect your /var/log/Xorg.0.log for clues.

Using Right-Click Emulation

Open up the terminal application. Put one finger down and hold it. Now tap the screen with a second finger. The context menu will pop up. This gesture is easier (at first) if you use two hands.

Resources

Here are links to (most of) the resources that we used above.

[1] The Xorg devs think this will end with the release of F17. ¬†XInput 2.2 is in the review process to be added to xserver 1.12. ¬†However, I’ve heard that Qt will not add official support for it, instead waiting for Wayland.

[2] I cut my teeth on DEB.  For MeeGo I had to learn RPM, and found that I liked it better.  Less time tracking down opaque debhelper issues and DEB styles.

[3] I don’t know where the original files were served up, these links are to a cached copy at Fedora. ¬†You can also get it from their qt SRPM.

[4] …presuming that someone actually breaks down and adds support to Qt. Otherwise, it’s still useful for Qt dev.

Q: So, MeeGo is using mutter like GNOME3, right?

A: Um… yes and no.

When engaging people outside of MeeGo, I find a lot of confusion over what is¬†MeeGo. ¬†And when you try¬†MeeGo, the confusion doesn’t actually get much clearer. ¬†Is MeeGo a new Linux distro? ¬†Is MeeGo a new desktop environment? ¬†Is it a suite of apps?[MeeGo Handset UX]

The trouble is that the answer to all of these is “yes and no.” ¬†Which doesn’t really help.

MeeGo is a new Linux distro.  MeeGo is not anything like Ubuntu or Fedora or Debian or even Damn Small Linux.  MeeGo is designed to be a really good starting point for people who want to make custom devices with custom graphical interfaces (i.e. phones, tablets, TV/set-top boxes, kiosks, etc.)

MeeGo is not a new desktop environment nor a bundle of apps. ¬†Inside the embedded device community, the graphical “desktop” is called the “User eXperience” (“UX” for short). ¬†MeeGo does¬†provide several reference UX’s. ¬†This includes the Netbook UX (which came from Moblin and uses Mutter), the IVI UX (which is a new thing based on Qt), and the (alpha-quality) Tablet UX (a new thing based on Qt). ¬†But the thing that’s hard to grasp is that these are just proof-of-concept UX’s. ¬†It is expected that device vendors will not use them, but replace the UX’s with their own custom UX.¬† And by “expected,” I mean… this is what you’re supposed¬†to do (by design).

This UX concept is hard for users to grasp… because articles and videos show a user interface and you think, “That’s MeeGo.” ¬†It was hard for me, personally, to grasp because the engineer in me thinks, “Why are we reinventing the wheel every time??” ¬†However, that’s the plan — and AFAIK the only OS of its kind that takes this approach.[1] ¬†It allows device vendors to do cool things with their device that help them stand out in the market place. ¬†(In contrast… do users really care if they get a Motorola Android phone or an HTC Android phone?? ¬†Probably not. ¬†They look/feel the same… so they buy based on price instead of features.)

And this is the reason why the MeeGo API (i.e. Qt) is so important… with everyone writing their own UX… having a preffered API makes it easier to write apps that will work on all the different custom UX’s that the vendors come up with.

[1] Edit: However, doing this is possible¬†with other OS’s (like Android). ¬†However, it’s the only one I know of that has this as a core implementation strategy.

MeeGo Conference 2011

May 30, 2011

In a Nut-shell

The MeeGo Conference was held in San Francisco on May 23-25, 2011. Summary:

“I have to admit #MeeGoConf started off flat but community got me pumped, now back @ Intel & getting more pumped. Cool MeeGo stuff on horizon” – Bob Duffy (@bobduffy)

Community, community, community…

"Sitting in the hack space..."The MeeGo Community (mostly Maemo community members, Nokia employees, and former Nokia employees) made the conference exciting. It was typically their enthusiasm and friendship that pumped energy into the conference.

When the keynote failed to deliver any news or announcements about devices shipping. Meanwhile, the developers in the hacker’s lounge discussed how they could take matters into their own hands.

The keynote was failing to register with the community. But when they brought established community member Robin Burchell (w00t) was brought on-stage for a demo, the audience became more responsive.

Most sessions, as well, were stocked full of people who knew each other well from forums, mailing lists, IRC, and the Maemo days. Tweets coming across the wire identified which topics were hot or exciting. (E.g. the AppUp encapsulator wowed several in the community).

The hacker’s lounge was hands-down the highlight of the conference. Most were the same people that I interact with day-to-day on MeeGo mailing lists and IRC, but there’s something different about meeting them face-to-face. In fact, Arjan van de Ven said as much when I met him, “That’s what these conferences are all about — names and faces.”

Call to Innovate

The most important session I attended was: The MeeGo Architecture Update with Sunil Saxena and Arjan van de Ven. They discussed the changes that happened in 1.2 and some of the changes planned for 1.3. They also discussed how some of the decisions were made (which has been discussed ad nauseum on the mailing lists). But he also made a call for innovation.

Arjan said that he was disappointed at the list of improvements in MeeGo 1.2, and that there is not enough innovation happening within MeeGo right now. Meanwhile, Android is pumping out releases and innovation at the same time. MeeGo will not compete if it does not innovate. “We need to have a mindset in MeeGo to do interesting technology,” said van de Ven. For example, the plans for Qt 5 look very compelling, and van de Ven said, “Can I get it in October??”

And this is not a call for Intel to innovate. It’s a call for innovation within the community. The Architecture board has said that in the future they will not adopt immature technologies again ‚ÄĒ which is what happened with several of the technologies dropped for 1.2 (e.g. buteo). Instead, they will wait for the technologies to be more mature before adopting them in MeeGo. This means that those in the community must establish and develop the technologies first, and then they may be included based on their merit.

Important Sessions

Another important talk was Carsten Munk’s Transparency, Inclusion, and Meritocracy in MeeGo: Theory and Practice. Munk presented several different patterns for how groups work within the MeeGo community. Each pattern was evaluated for transparency, inclusion, and effectiveness. He also gave suggestions for improvement for each type. If you missed it, be sure to go back and watch the whole thing.

Auke Kok’s talk on systemd was particularly enlightening to me as a distribution maintainer for Indamixx. Kok outlined the history of fast booting in Moblin and MeeGo, and how systemd addresses the problems with that system. He also gave handles to how the new system is configured and extended.

My own session, Writing Interactive Audio Applications with Low Latency was well received. Afterwards, I was surprised to find out how many people outside of Pro-Audio were having troubles with PulseAudio. So, I plan to look more closely at what’s happening and see how I might help things. I was also told that my talk was the most technical talk they attended… so I’m not sure if that’s a good or a bad thing. ūüôā

Booths and Demos

There were several vendors with booths in the expo area. This included Intel, Qt, Digia, ICS, Nomovok, and basysKom. Most of these were offering outsourcing and training.

Of particular interest was our own Indamixx 2 demo in the Intel booth (See videos from Engadget, The Nokia Blog, and Netbook News. We showed off our version of MeeGo that’s tweaked for audio, and people were very receptive. Probably the best reception is for the combination of Ivory (virtual midi keyboard) and Yoshimi (a synthesizer). But I’m biased, of course.

Nomovok was demonstrating their Steelrat framework. When vendors want to ship their own custom tablet, they help the vendors to do this from start to finish. They also include their own “Steelrat Framework” that accelerates the development of custom UX’s. They also sell their expertise on accelerated graphics. Very impressive vendor.

Round-Up

MeeGo is currently doing well as a starting point for appliances (set-top boxes, kiosks, PIM). The design and openness makes it very easy to create custom applications and user experiences. While tablet/handset/app-store experiences aren’t here today… they are coming.

The split between Intel and “the community” is getting better, but slowly. The Intel AppUp crew made great efforts to mingle with the community. Other key Intel folks seemed… hard to find. Perhaps word of this got out, because on the 3rd day the sessions seemed littered with Intel employees wearing black Intel shirts. (A good thing.)

Last year, I expected that the future of MeeGo would start with the 1.2 release. From the conference it’s clear to me that MeeGo has a future, and it will start with the 1.3 release.

Thanks

I would like to thank the Linux Foundation for sponsoring my trip. Also thanks to Intel for featuring us in their booth. And a world of thanks to Dawn Foster for her tireless effort to build community.

Last time I described how to use LD_LIBRARY_PATH for your private libs in your package. While this will usually get you what you want, it has one extremely big drawback: poisoning 3rd party libs. It also has one minor drawback: applications start up slower.

Starting Slower

When your application starts, a program called ld.so looks to see what libraries you need. (E.g. libQtCore.so.4 and libxml2.so.0 and so forth.) Since this happens all the time, it keeps an index of these libraries and where they are located. Thus, it’s able to resolve the libraries very fast.

But when you set LD_LIBRARY_PATH, these paths have to be searched first, and this is slower because you actually have to access the file system and search directories.

But this is only a minor problem… the bigger problem is…

Poisoning 3rd Part Libraries

To be MeeGo compliant, there is a prescribed list of libraries that we can depend on. For everything else, we have to bring our own. Suppose, for instance, that MeeGo’s version of libAtion.so.1 does not have all the features that you need. So, you package your own version of libAtion.so.1 with the extra features and ship it as a private library in your package.

Meanwhile, Qt is already linked to libAtion, and you use it (indirectly) in your code. When your program is initialized, it’ll see that Qt needs libAtion.so.1 and use your private version instead of the system version that Qt shipped with. Do you see how this might cause problems?

Or, suppose you had no idea that libAtion.so.1 was in any MeeGo, anywhere. However, DeviceMan, Inc. shipped a MeeGo device where they added libAtion.so.1 as part of their default Qt theme plug-in. Now when your application loads the theme, it is poisoned with your private libAtion.

Solutions to LD_LIBRARY_PATH

So, LD_LIBRARY_PATH isn’t the best solution (and some will say it is to be avoided at all costs). What other options do you have?

  • Statically link your programs to your private libraries — While this isn’t as convenient to your opt/non-opt build workflow, it is effective.
  • Use rpath when you link — the GNU linker has an -rpath option that is like setting LD_LIBRARY_PATH at compile time. The advantage is that it only applies to your binary… and not other 3rd party libs.
  • Do lots of homework — Make sure that your version is compatible with whatever version may be on the system. If possible, prefer the system’s version of the library. However, this option is destined to fail, eventually.

Further Reading

I found the following articles informative:

So last time I convinced you that packaging for /opt is a Good Thing for add-on software (e.g. app store stuff).[1] ¬†But now that you are convinced… this is a total re-think of how packaging works. Here are some tips on how to get it done without totally messing up your non-opt installs.

Suppose our company is indie.biz and our program is called Floobydust. ¬†On unix-like operating systems we’re used to installing our software like this:

  • Executable programs go in /usr/bin/
  • Libraries go in /usr/lib/
  • Desktop files go in /usr/share/applications/
  • Our extra stuff goes in /usr/share/floobydust/

But now, everything must go in /opt.  This means that:

  • Our program won’t be in $PATH
  • Our libraries won’t be found by ld.so [4]
  • Our desktop files won’t be discovered
  • Our hard-coded "/usr/share/floobydust" strings are now bugs

So… how do you handle this? ¬†In fact… how can I handle both cases without having to totally re-write my build system?

Step 1: Use PREFIX

Most build systems allow the user to define a PREFIX at build-time. ¬†This PREFIX will determine the location of the bin, lib, and share folders that we’ll use for install. ¬†All the paths above set PREFIX=/usr. ¬†It typically defaults to PREFIX=/usr/local. ¬†So, what happens when you set PREFIX=/opt/indie.biz/floobydust ?[3] ¬†Then…

  • Executable programs go in¬†/opt/indie.biz/floobydust/
  • Libraries go in¬†/opt/indie.biz/floobydust/lib/
  • Desktop files go in¬†/opt/indie.biz/floobydust/share/applications/[2]
  • Our extra stuff goes in¬†/opt/indie.biz/floobydust/share/floobydust/

Now, it’s essentially the same thing as if we had set any other prefix. ¬†Note also that you may choose to use PREFIX=/opt/indie.biz ‚ÄĒ as long as you make sure that all your programs cooperate!

Step 2: Use a redirect script to set up your private libraries

When installed in /usr/bin, ld.so (the dynamic linker) will search in /usr/local/lib, /usr/lib, and /lib for the shared object (.so) files that you need. However, you have installed them to /opt/indie.biz/floobydust/lib instead. To get ld.so to find your libraries, you need to modify LD_LIBRARY_PATH to include your package’s lib folder. You can do this by renaming your program to something like floobydust-1.2.3, and creating a redirect script called floobydust like this:

#!/bin/bash
LD_LIBRARY_PATH="/opt/indie.biz/floobydust/lib:$LD_LIBRARY_PATH"
export LD_LIBRARY_PATH
exec /opt/indie.biz/floobydust/bin/floobydust-1.2.3 "$@"

So, we (a) set LD_LIBRARY_PATH, (b) call our program, and (c) pass it all the command-line arguments (that’s the “$@” thing). However, this script only covers the happy case… so here’s the script that you would really use:

#!/bin/bash
PREFIX=/opt/indie.biz/floobydust
BINDIR="${PREFIX}/bin"
LIBDIR="${PREFIX}/lib"
EXEFILE=floobydust-1.2.3

LD_LIBRARY_PATH="${LIBDIR}${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
export LD_LIBRARY_PATH
PATH="${BINDIR}${PATH:+:$PATH}"
export PATH

exec "${BINDIR}/${EXEFILE}" "$@"

This is something that you could reuse in several different applications. Also note the shell expansion trick for LD_LIBRARY_PATH and PATH that makes sure we don’t end up with a trailing colon ("/opt/indie.biz/floobydust/lib:").

This method will help no matter where you installed your libs. You can configure the path at compile time.

Step 3: Namespace your .desktop file

Add your organization name to your desktop file indie.biz.floobydust.desktop. Since you are using your domain name, it’s extremely unlikely that you will conflict with anyone else’s .desktop file. Then install the file using the desktop-file-install utility (which will usually install to /usr/share/applications). You can optionally have that command do the file-name mangling for you. (Read the manual page for it.)

Also, be sure to put the full path to your redirect script from Step 2 (/opt/indie.biz/floobydust/bin/floobydust), as well as any icons.  Most build systems will let you make your desktop file a configure script (typ. floobydust.desktop.in) that gets modified for your compile-time configuration options.

Step 4: Make sure you don’t hard-code paths in your application

This is actually step 1, but it’s boring so I put it last. ¬†If some part of your program looks to /usr/share/floobydust without thinking first… you need to make your application configurable.[5]

What about $PATH??

Are you really shipping command-line apps through an app store? There isn’t really a solution to this (and still be MeeGo Compliant.) The .desktop file is the replacement for a $PATH, and the redirect script from step 2 can reset it if we need it internally. Another option is to create symlinks in /usr/bin. While this makes the app non-compliant, it’s a good compromise for a multi-distribution package.

Wrapping up

Whatever we do to install in /opt can translate back to /usr and /usr/local. Using this strategy not only helps in app-store situations, but also creates a safe practice for application-specific private libraries (.so). With a little extra run-time detection, these can also help in supporting relocatable RPM packages. While there are no good solutions for CLI apps, it seems unlikely that many CLI apps will be targeting app stores.

——
[1] Yeah, right! ūüôā
[2] Not really… but we’ll get to that.
[3] Note that MeeGo compliance says you can install in /opt/<packagename>. Using your organization name is optional, but recommended.
[4] ld.so is the dynamic linker. ¬†It’s the program that finds the .so files for your app to use.
[5] You are supposed to do this anyway… since you don’t know what PREFIX will be a priori.

The current MeeGo Compliance Spec will often give developers a start when they read this:

ÔĽŅÔĽŅAn application shall be installed to /opt/packagename/ and, if necessary to the /etc/opt/packagename/ and /var/opt/packagename/ directories.[1]

Most users reply, “Huh? ¬†Why don’t we install in /usr like a normal Linux distro??” ¬†The rationale is given as follows:

ÔĽŅÔĽŅThe rationale for these rules is to avoid filename clashes between application packages and with system files, by defining portions of the filesystem certain to be unique to that application.[2]

This leaves most devs a little…¬†underwhelmed. ¬†The first response is to appeal to the FHS/LSB… but lets start with an example.

Suppose I write a MeeGo game called “Zombie Professer Shootout.” ¬†Because I’ve got several modules for this game, I have an internal library called libzps.so.0. ¬†Because I don’t know any better, I install it in /usr/lib/libzps.so.0. ¬†Put the package in the App Store. ¬†Done.

Meanwhile, suppose that YOU, Zeek, write a hand MeeGo time management program called “Zeek’s Personal Scheduler.” ¬†For whatever reason, you put a lot of the core functionality in a library called libzps.so.0 so that other people could reuse it in their code. ¬†So, you install it to /usr/lib/libzps.so.0. ¬†Put the package in the App Store. ¬†Done.

First, they install my Zombie game. ¬†Then, months later, they install your Personal Scheduler. ¬†However, the app WILL NOT install because it would overwrite /usr/lib/libzps.so.0. ¬†There’s no way around it. ¬†You have a broken package.

And the user says, “This sucks!”

The whole point of being a MeeGo compliant app is that it’s a single, stand-alone, 3rd party app that can be installed to MeeGo… and it Just Works. ¬†But if we all install in /usr… then we all have to be on the same page with respect to file names, package names, etc. ¬†In a normal linux distro (where all packages are served from one repository), these get discovered and discussed among the developers. ¬†But with MeeGo apps coming from a myriad of sources there is no way that can happen.

So, MeeGo chose to use namespaces by requiring installation to /opt.  The opt folder is defined in the FHS as follows:

/opt is reserved for the installation of add-on application software packages.

A package to be installed in¬†/opt must locate its static files in a separate¬†/opt/<package> or¬†/opt/<provider> directory tree, where¬†<package> is a name that describes the software package and¬†<provider> is the provider’s LANANA registered name.[3]

Note that this is nearly identical to the MeeGo requirement… and serves to solve this exact problem. ¬†It’s a system that allows uncoordinated developers the freedom to organize their package however they need without stepping on anyone else’s toes. ¬†Everything they do is under the namespace of the company’s LANANA registered name (e.g. google.com or something). ¬†Without this, users will be inundated with broken packages and always come to the same conclusion: “This sucks.”

“But how do I find my project’s libs? ¬†What about $PATH? ¬†This is no fun for the developer!” ¬†We’ll talk about that next time.

[1]¬†ÔĽŅMeeGo 1.1 Compliance Specification, Section 3.3.4

[2] Ibid.

[3]¬†ÔĽŅhttp://www.pathname.com/fhs/pub/fhs-2.3.html#OPTADDONAPPLICATIONSOFTWAREPACKAGES

Fennec (Firefox Mobile)Fennec is the code name for the latest Firefox Mobile browser. ¬†I was playing with the version on the MeeGo Handset UX (on an Atom-based Ideapad)… and pulled up some Youtube videos. ¬†At first the video seemed a little jumpy… no doubt because of the compositing window manager I was using (mcompositor).

Then I clicked fullscreen.

The quality of the fullscreen video was amazing. ¬†It was like watching a DVD or television. ¬†I didn’t detect any jitter or pixelation… just clean video. ¬†I was impressed!

Other video players in MeeGo are no slouch. ¬†For example, watching the short film “Big Buck Bunny” in the Netbook UX with Banshee (a media player) is also impressively snappy. ¬†And flash video inside the Chromium browser is no slouch. ¬†But in Chromium, if you hit the button for full-screen flash, you’ll just get full-screen white. ūüė¶

This is just one of the things that is really well done with Firefox Mobile. ¬†If you get a chance to play with the latest version — take it.