📜 ⬆️ ⬇️

Qt Build System: a lifeline to build


Note (06/17/2013): The syntax of the examples in the article does not correspond to the latest versions. Check the documentation. Also in March, Qt Creator 2.7 was released with QBS support.
Not so long ago, the Qt development team introduced a new build system - QBS. Of course, the main reaction was “Yes, what did not suit you QMAKE”, “Just adapt CMAKE”, “Another build system [xkcd, standards]”. The promised advantages of the new system: flexibility, understandable syntax for all developers (QML is a javascript-like declarative language), build speed (pure and incremental), as well as easy extensibility.
We have already heard all this somewhere, so in this article we will try to figure out how the developers came to this system, consider the simplest examples, study the basic constructs and see what kind of support is present at the IDE level at the moment.

Story


Now together we will try to repeat the path of Jörg Bornemann, the developer of QBS.

Criticism make (and derivatives)

The 1999 article by Peter Miller discusses the problems of recursive make and the convenience of makefiles in general.


The 2005 Adrian Neagu article discusses more common make issues:

')
In the article " What's wrong with GNU Make "
The minuses of the language and the same problems as before are described in more detail (I will not repeat)


A short note from Ian Lance Taylor , 2007, discusses the main drawback of Cmake as a replacement for Make-It. Too. Complicated This is a hell of a mixture of several languages; only development and debugging gurus can support it (for really complex systems) (debugging it is also problematic). Another disadvantage is that for flexibility (even FLEXIBILITY), you have to pay the loss of performance in the generated scripts.

What is wrong with QMake?

The Qt infrastructure today widely uses the Qmake build system, which is officially supported and is still being finalized. Why did the “just another one” build system need?

The article Marius Storm-Olsen analyzes the following qmake flaws:

Finally, we come to the point when the Qt mailing list discussed the new build system and the requirements for it:


Introducing the “lifeline” - Qt Build System


On February 15, 2012, in Qt labs, Jorg Borneman presented the draft QBS to the public. Now he is not even able to alpha, but somewhere in the middle between the prototype and the alpha version. In justification, we can say that Qt Creator is already going with it.
The basic principles of designing a new system:

What is not yet: checking the system configuration (using the qmake request to configure the toolchains), building packages, deploying, running tests and, most importantly, supporting any ide, except for the special QtCreator branch.

Let's start trying!

The author advises to build qbs from source , but you can bear in mind that there are binary builds for win and linux users
win - compiled under MSVC2010. I would also advise you to build a version from git (I had problems with plug-ins and MOC).
In binary form, qbs depends on the QtCore and QtScript libraries (+ Concurrent for Qt5)
Create a Hello World C ++ project:
main.cpp
 #include <iostream> using namespace std; int main() { cout << "Hello world!" << endl; return 0; } 


Let's also create a minimal project on qbs:
hello.qbp
 import qbs.base 1.0 CppApplication { name: "HelloWorld" files: "main.cpp" } 

LINUX:
1. Open the shell in the current folder.
2. Add the path where you unpacked / assembled qbs, in the PATH (or rather, bin folder)
PATH = ~ / qbs / bin /: $ PATH
3. start qbs:
qbs
 Found project file /home/mapron//example-3/hello.qbp loading project took: 69 ms build graph took: 18 ms for debug: - [hpp, application] HelloWorld as debug compiling main.cpp linking HelloWorld Build done. 

After that, the build program will start parsing the project and collect the executable file in the build / debug folder (well, haven't you specified the destination folder yet?)
WINDOWS:
4. Since under Windows, as a rule, the compiler and qt are not in the PATH, qbs may ask you to run “ qbs platform probe ”, which is necessary to do.
5. then you may need to run qbs config update or the like (if he asks, it may have been fixed already).
6. after that, when you start qbs [build] - you will get the “HelloWorld.exe” binary

We continue to study

Now we will try to master the assembly of something more complex, and at the same time, deal with the language.
To begin with, we will create a new folder and copy the 2dpainting and collidingmice folders from the examples folder with Qt.
Why just two? We will create a configuration for the assembly of two products at once.
The product is the target “output” of the build system, a kind of “.pro” file when building Qmake. In a single qbs project, there may be several products.
To begin, create the examples.qbp project.

 //     QML import qbs.base 1.0 import qbs.fileinfo 1.0 as FileInfo Project { //    - . moduleSearchPaths: "qbs" //     ,   cpp  qt //        -   . Product { name: "2dpainting" //    ( ,    ) type: "application" //  - , ..  . Depends { name: "cpp" } //      C++ Depends { name: "Qt"; submodules: ["core", "gui", "opengl"] } //  Qt  QtCore, QtGui, QtOpengl files: [ //     .    ,  . "2dpainting/glwidget.h", "2dpainting/helper.h", "2dpainting/widget.h", "2dpainting/window.h", "2dpainting/glwidget.cpp", "2dpainting/helper.cpp", "2dpainting/main.cpp", "2dpainting/widget.cpp", "2dpainting/window.cpp", ] } } 


Open the console and try to build, the error “ERROR: Error while setting up the environment: qt.core.incPath not set. Set qt.core.incPath or qt.core.path in your profile. "
Let's close our eyes for a not too user-friendly way of configuration, and create a file " qbs.config " with the following contents (WINDOWS):
 modules.qbs.platform: MSVC2010 profile: default profiles.default.qt.core.path: C:/QtSDK/Desktop/Qt/4.8.1/msvc2010/ 


either under linux (ubuntu):
 modules.qbs.platform: gcc profile: default profiles.default.qt.core.binPath: /usr/bin/ profiles.default.qt.core.libPath: /usr/lib/qt4 profiles.default.qt.core.incPath: /usr/include/qt4 profiles.default.qt.core.mkspecsPath: /usr/share/qt4/mkspecs 

and run qbs config --import qbs.config
After this, qbs will normally be able to build the project and place the output file in the build / debug folder.
To build a project into a release, execute “ qbs build release ”.
To clean all build files (i.e. “build” folders) execute “ qbs clean ”.
Now we will try to organize an expandable structure for two projects. Create in the subdirectories " 2dpainting " and " collidingmice " the names tags of your directories with the extension ".qbs" with the following contents:

 import qbs.base 1.0 Product { name: "2dpainting" type: "application" Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["core", "gui", "opengl"] } files: [ //     ,    . "glwidget.h", "helper.h", "widget.h", "window.h", "glwidget.cpp", "helper.cpp", "main.cpp", "widget.cpp", "window.cpp", ] } 


 import qbs.base 1.0 Product { name: "collidingmice" type: "application" Depends { name: "cpp" } Depends { name: "Qt"; submodules: ["core", "gui", "opengl"] } files: [ "mouse.h","main.cpp", "mouse.cpp" ,"mice.qrc"] } 


Those. we break the code into independent products that can be built in parallel. Make changes to examples.qbp:
 //     QML import qbs.base 1.0 import qbs.fileinfo 1.0 as FileInfo Project { //    - . moduleSearchPaths: "qbs" //        -   . //      references. :     ! //     ,    references: [ "2dpainting/2dpainting.qbs", "collidingmice/collidingmice.qbs", ] } 


You can run qbs again. Note that for the “.qrc” file the “rcc” will be automatically called and all this is linked together. All files are indicated by one list, without division into HEADERS, SOURCES, etc., as was the case with qmake.

How does all this work?

For starters, I recommend to get acquainted with the help
The basic concepts of the language are: Project (Project), Product (Product), Artifact (Artifact), Module (Module), Rule (Rule), Group (Group), Dependency (Depends), Tag (Tag).
The product is an analogue of pro or vcproj, i.e., one target for assembly.
A project is a collection of your products along with dependencies, perceived by the build system as one unit. One project - one graph assembly.
Tag - file classification system. For example, "* .cpp" => "cpp"
Rule - Conversion of project files marked with specific tags. Generates other files called artifacts. Typically, these are compilers or other build systems.
Artifact - the file over which is the output for the rule (and possibly the input for other rules). These are usually “obj”, “exe” files.
Many QML objects have a condition property that is responsible for whether or not they will be built. And if we need to split the files? To do this, they can be combined into a group (Group)
 Group { condition: qbs.targetOS == "windows" files: [ "file1", ...] } 

something like this.

What next?


A logical question, examples are great, but how can you go on a free swim with this system? Can:


Conclusion


QBS provides us with the following advantages:

But, unfortunately, it has the following (temporary disadvantages)


Unfortunately, the format of the article does not allow to reveal all the details, in future plans to open the topic:
  1. Creating your own module (it is included in the archive with examples);
  2. Writing rules for the assembly;
  3. Creating js-modules and their inclusion;
  4. Creating your own product types;
  5. Work with global config and module configs;
  6. Writing your own plugin (for parsing dependencies of the .drpoj file).

All this can be in this article, and something that will write in the comments.

Link to the archive with all the examples for the article:
narod.ru/disk/49759080001.18d6748f8ef86e26c6dea2e2c5ed7d13/examples.zip.html
Archive BONUS! an example of a module for assembling a DELPHI 2007 project not mentioned in the article (it is planned to do analysis in the next article)

Links


labs.qt.nokia.com/2012/02/15/introducing-qbs - presentation
doc-snapshot.qt-project.org/qbs - documentation
qt.gitorious.org/qt-labs/qbs - git
bugreports.qt-project.org/browse/QBS - bugtracker.

Note: Qt Build Salvation (Rescue for Qt Build) is the internal name of QBS, in the source tree's README.

Source: https://habr.com/ru/post/144127/


All Articles