Jörg Bornemann

qbs 1.0.0 released

Published Friday May 31st, 2013 | by

Qbs has reached a state where it’s conveniently possible to build projects of the complexity of Qt Creator. Therefore it deserves a version number that reflects its usefulness to the public. To encourage you to use it for your own projects, we hereby present to you qbs 1.0.0.

Why should I use it?

  • Qbs takes care of your build environment. Build your project for different platforms in the same shell.
  • Build multiple configurations of your project in parallel.
  • Fast incremental builds. A speed comparision is here.
  • QMLish language. Write your complicated tasks in JavaScript instead of some obscure language (I’m looking at you, qmake).
  • Qbs is supported in Qt Creator 2.8.
  • Qbs is not tied to the Qt version. That means switching the Qt version doesn’t automatically switch your build tool version.

Where can I get it?

Qt Creator 2.8 will come with qbs integrated.
Instruction how to build qbs from source can be found in the wiki: http://qt-project.org/wiki/qbs

Please report any bugs you may find at https://bugreports.qt-project.org/browse/QBS

Please ask your questions on our mailing list at http://lists.qt-project.org/mailman/listinfo/qbs

Can it build Qt?

This is a question that arises very often. Though it would be possible to replace the current qmake-based build system of Qt with qbs, we still would need a configure script and our infamous syncqt. I don’t see much gained from that. We’re aiming somewhat higher and want to replace configure and syncqt as well. That’s where qbs still lacks features. Also, bootstrapping qbs is not possible yet.

42 Comments


Posted in Build system

Qtified JavaScript

Published Thursday May 16th, 2013 | by

When writing JavaScript code, it doesn’t take long until I’m missing some function which is available in Qt’s C++ API. One very simple example is QList::contains. Checking whether an array contains a certain element works like this in JavaScript:

var names = ["Egon", "Peter", "Raymond", "Waldo"];
if (names.indexOf("Waldo") !== -1)
    print("We've found him!");

It would be nice if we could express the condition using a contains method but Array doesn’t provide one.
Luckily, JavaScript enables us to add methods to inbuilt types by modifiying the corresponding prototype object.

Array.prototype.contains = function(e) {
    return this.indexOf(e) !== -1;
}
if (names.contains("Waldo"))
    print("We've found him!");

Yay! Now we can use the contains method for all arrays!
But wait – there’s a surprise lurking right around the corner once you’re trying to iterate over the keys of the array.

for (var i in names)
    print(i);

This will print:

0
1
2
3
contains

I know, iterating over arrays should be done with an index variable…but still…this additional key is unexpected and asking for trouble.

The solution for this problem is to mark the property contains as non-enumerable. We can use the Object.defineProperty function for that which is available since JavaScript 1.8.5.

Object.defineProperty(Array.prototype, "contains", {
    value: function(e) { return this.indexOf(e) !== -1; },
    enumerable: false    // This is the default and can be omitted.
})

We’re passing to Object.defineProperty the object we want to enhance, the name of the property we want to add and a descriptor object that contains the attributes of our new property.
The value of  contains will be the function that we formerly passed directly to the prototype. Setting the enumerable property to false in the descriptor object will hide contains when using a for (... in ...) loop.

This way we can create a nice Qtish API for the inbuilt JavaScript types Array and String. This can be put into a .js file and used it in QML/JS or in qbs project files.

What do you think? Would such an API be helpful for your QML code? Which QList or QString method are you missing most?

14 Comments


Posted in Qt Quick, Qt Quick 2

qbs reached mile stone 0.3

Published Tuesday April 16th, 2013 | by

Qbs, our alternative build tool, has reached a new mile stone. Since the last one in December, qbs has had the following improvements:

The whole codebase has seen a major overhaul. Experiments from the prototype phase have been removed. The API for the Qt Creator plugin has been stabilized. The test suite has been extended to cover most features. On our internal test farm – the same that is used for Qt Creator – qbs is tested on Linux, OS X and Windows every time the testing infrastructure detects a new change in the repository.

Support for installing your built products has been added. To install your project to ~/foo/bar use

qbs install --install-root ~/foo/bar

The project loading phase got faster. On my machine, the times to generate the makefiles respectively create the build graph for Qt Creator 2.7 look like this:

Linux Windows
qmake -r 26.284 s 99.581 s
qbs resolve 13.813 s 5.510 s

The running time of incremental null builds, that is determining that nothing of your project has changed, look currently like this for Qt Creator 2.7 (same machine with Windows/Linux dual boot):

Linux Windows
(n)make 3.228s 45.199 s
jom n/a 25.098 s
qbs 1.884s 1.630 s

The performance gain stems from the fact that qbs only has to check the timestamps of the project’s source files. It already knows the timestamps of generated files from the previous build.
On Windows this approach gains us much more than on Linux because retrieving the file timestamps is so unbelievably slow.

Support for detecting changes of project settings has been improved. Changing properties like cpp.defines will now get noticed and result in a rebuild of the affected products.

Last but not least, Qt Creator 2.7 comes with an experimental Qbs project manager plugin. It provides support for loading and building qbs projects.

21 Comments


Posted in Build system

Introducing qbs

Published Wednesday February 15th, 2012 | by

Over the years we have developed a kind of a love-hate relationship towards qmake. It does its job but also has its quirks and is widely considered unmaintainable. The blog post [TMQB] contains a wish list for a qmake replacement. We have considered the various tools on the market, but none satisfied us – see for example [WNCM]. So some time ago we have initiated an internal project to try some of the ideas. This is the outcome of it: the Qt Build Suite, aka qbs (pronounced as “Cubes”).

It is not qmake

Unlike qmake, qbs is not tied to the Qt version, and it generates a proper build graph (dependency graph) from the high-level project description in the project file. Also, classical makefile generators like qmake and CMake create makefiles and leave the execution of the actual build commands to tools like make or ninja. Qbs on the other hand fills the role of a parallel make and directly calls the compiler, linker and other tools, pretty much like SCons and Ant do.

Declarative Language

The language of qbs is a simplified version of QML, providing an IDE-friendly representation of software projects. Still it provides the freedom of writing all kinds of JavaScript expressions on the right-hand-side of property bindings. A project file editor could know how to edit file lists that are pure string array literals. For more complicated constructs it would fall back to opening the project file in a text editor.

files: ["foo.h", "foo.cpp", "main.cpp"]              // editable from IDE
files: generateFileList().concat(['extra.cpp'])      // only editable in your text editor

For most use cases it should be possible to write IDE-friendly project files. But if you need more power, you are free to unleash all your l33t JavaScript skillz.

Now let’s have a look at the obligatory “Hello World” example:

// helloworld.qbp
import qbs.base 1.0

CppApplication {
     name: "HelloWorld"
     files: "main.cpp"
}

The import statement enables us to use items like “Application”. We are giving our application the name “HelloWorld” and adding a C++ source file to it.

A thorough walk-through of the language can be found in the documentation under “language introduction”.

Extensible

Dealing with code generators or resource compilers is something you really want to avoid in qmake. In qbs you can easily write rules to transform files of a certain type to files of another type. One can either call processes that do the transformation externally (e.g., rcc) or directly execute the transformation in JavaScript. This simplified example demonstrates how to turn the .pluginspec.in files of the Qt Creator source tree to .pluginspec files.

Rule {
    ...
    prepare: {
        var cmd = new JavaScriptCommand();
        cmd.description = "generating " + FileInfo.fileName(output.fileName);
        cmd.qtcreator_version = product.module.qtcreator_version;
        cmd.sourceCode = function() {
            var inf = new TextFile(input.fileName);
            var all = inf.readAll();
            all = all.replace(new RegExp('$$QTCREATOR_VERSION(?!w)', 'g'), qtcreator_version);
            var file = new TextFile(output.fileName, TextFile.WriteOnly);
            file.write(all);
            file.close();
        }
        return cmd;
    }
}

Fast incremental builds

Qbs sees the project as whole and thus does not need to fork itself for subdirectories. Even if only a part of the project is built, the whole build graph is taken into consideration. The problems of recursive make (see [RMCH]) are no more.

This also has the consequence that incremental builds are much faster than with make. I have modified the benchmark generator script from [QPBS] and added qbs support. The following results were obtained from incremental builds of a project with 200 libraries, 50 classes per library, 30 lib-internal includes per file and 10 lib-external includes per file.

On my machine, doing an incremental build without any changed files with make takes

real 0m4.076s
user 0m2.556s
sys 0m1.952s

doing the same with qbs

real 0m0.843s
user 0m0.724s
sys 0m0.112s

Build Instructions

Enough talk. Where do I get it? How to build it?


git clone git://gitorious.org/qt-labs/qbs.git
cd qbs
qmake -r qbs.pro
make
make docs

Please read the docs, esp. the part “configuring qbs”. You can find them online here. Then you can start playing around with the example projects in qbs/tests/manual. If you are more in search of a real-world project, you can find qbs project files for Qt Creator right here.

The project is open for contributions. Please see “Setting up Gerrit” on the Qt Project’s wiki for instructions. The URL of the gerrit remote is <Gerrit/Jira username>@codereview.qt-project.org:qt-labs/qbs.
The project’s mailinglist can be found at http://lists.qt-project.org/mailman/listinfo/qbs

Outlook

The state of this project is experimental. It is meant as a playground for different build tool concepts. Qmake will still be around for a long time, and nobody will force you to use qbs or any other build tool – though of course we will probably try to push qbs for Qt’s own build system at some point.

Users of common meta build tools like CMake or the GNU Autotools may have noticed that a crucial part is missing if qbs is meant to seriously compete in the cross-platform build tool market: adapting to the host environment, aka configure checks. For the time being it is still necessary to use an external configure script to generate a JSON file for qbs’ use, but that is of course not meant to be the long-term solution. The idea is to make configure tests usable like other modules. Their implementation will of course not be purely declarative, but will contain some JavaScript code.

There is plenty to do! For a non-exhaustive list of ideas, see our issue tracker (once our admins configure public access to the product).

References

[RMCH] Peter Miller (1998), “Recursive Make Considered Harmful”, AUUGN Journal of AUUG Inc., 19(1), pp. 14-25
[TMQB] Marius Storm-Olsen (2009), “To make, or not to make – QMake and beyond”, http://labs.qt.nokia.com/2009/10/12/to-make-or-not-to-make-qmake-and-beyond/
[WNCM] http://lists.qt.nokia.com/pipermail/qt5-feedback/2011-June/000494.html
[QPBS] Noel Llopis (2005), “The Quest for the Perfect Build System”, http://gamesfromwithin.com/the-quest-for-the-perfect-build-system

121 Comments


Posted in Build system

Qt VS Add-in 1.1.10 released

Published Monday December 19th, 2011 | by

Together with Qt 4.8.0 we’ve released version 1.1.10 of the Qt Visual Studio Add-in.
This release contains multiple bugfixes and improvements.
The full changelog is available here.

You can get it here:
http://qt.nokia.com/downloads/visual-studio-add-in

If you find bugs, please report them in our bug tracker:
https://bugreports.qt.nokia.com/

Note: Qt VS Add-in 1.1.10 will be the last release done by Nokia.
We’re happy to announce that the project has been handed over to Digia, Qt Commercial (http://qt.digia.com/) who offers commercial support and will take over future maintenance.

22 Comments


Posted in Qt, Windows

Qt VS Add-in 1.1.9 released

Published Wednesday March 30th, 2011 | by

Today we’ve released version 1.1.9 of the Qt Visual Studio Add-in.

The following fixes are included:

  • Fix a regression when importing .pro files that was introduced in 1.1.8.
  • Make the add-in work with Intel VTune projects. (QTVSADDINBUG-65)
  • Check for compatibility with VS version when adding new Qt version. This will hopefully stop people from trying to use a MinGW Qt build with Visual Studio. ;-) (QTVSADDINBUG-58)
  • Added possiblity to specifiy lupdate/lrelease options. (QTVSADDINBUG-48)

You can get it here: http://qt.nokia.com/downloads/visual-studio-add-in

35 Comments


Posted in Qt, Windows

Rhymin’ and Freein’

Published Wednesday September 15th, 2010 | by

While everyone is holding their breath for the release of Qt 4.7.0 I will entertain
the masses in the meantime with a little poem.

A Windows programmer from Latin
Am’rica was almost forgettin’
to sleep and to eat
cause it has been freed
the Visual Studio Add-in.

That’s right! The source code of the Qt Visual Studio Add-in is now available on gitorious.
Check out the repository page and the build instructions.

Contributions are welcome and can be provided in the usual way via merge requests.
The published Qt Visual Studio Add-in can be used under the Qt Commercial License or the LGPL.

9 Comments


Posted in Qt, Windows

Speeding up Visual C++ Qt Builds

Published Friday March 27th, 2009 | by

Poor, poor Visual C++ developer. You see these MinGW or Linux guys using GNU make on their fancy quad core machines to compile Qt. They are already hacking again while you still sip at your coffee, watching the distressing 25% CPU usage in the task manager. And just because nmake doesn’t make use of all available processing power.

But good news, everyone! The misery is over. I’ve writte a nmake clone that can use an arbitrary number of processes concurrently. The thing is called jom and the sources are here, a ZIP with the binary is available for download here.

To install jom, just extract the zip file to a directory which is in your PATH. Now, instead of calling nmake to build Qt, call jom. It automatically detects the number of processor cores in your PC by calling QThread::idealThreadCount().
You also can use the -j command line argument to set the number of concurrent processes.

On a quad core machine with a Qt build takes half of the time it took using nmake. There’s still room for improvement. Jom is aimed to be compatible with decent nmake Makefiles. Its not complete yet but hey, you can already speed up your Qt builds!

Update:
This project moved to gitorious! The source can now be found here:
http://qt.gitorious.org/qt-labs/jom

13 Comments


Posted in Labs, Qt

WebKit on Windows CE

Published Wednesday August 27th, 2008 | by

I want to introduce a feature that we’ve been asked for over and over: QtWebKit on Windows CE. Its still in the works but already in a quite usable state. Eventually its possible to create your own applications with web browsing capabilities on your favourite Windows CE device!

To give QtWebKit for Windows CE a whirl, you can fetch the current source from the QtWebKit git repository. So make sure that you have the following software installed:

  • Qt for Windows CE
  • Git for getting the source
  • Perl for calling the build script

First of all, download the source code:

git clone git://code.staikos.net/webkit
git checkout -b wince origin/joerg/wince-master

You now should have a local branch called wince, which is based on the remote Windows CE branch. Then you must set up your environment to build Qt for Windows CE applications.
This could look like this:

call vsvars32
set QTDIR=c:Qt4.4.1
set PATH=%QTDIR%bin;%PATH%
setcepaths wince-mymakespec

Go into your WebKit directory and call the build script:

perl WebKitToolsScriptsbuild-webkit

If everything goes well, you will find in WebKitBuildReleasebin a QtWebKit4.dll and QtLauncher.exe. Deploy these files to your device (with the Qt binaries including network and image plugins), run it and browse the web!

For Windows CE 5 I strongly recommend to build a smaller Qt version, tailored to your needs. Remember that you only have 32 MB memory per process which is pretty soon filled if you’re displaying web sites with many images or animations.

Try it, have fun and use the mailing list qt-wince-interest@trolltech.com if you have questions or comments.

3 Comments


Posted in Labs, WebKit