[Development] Notes on "Qt Build Systems" @ QtCon 2016

Milian Wolff milian.wolff at kdab.com
Thu Sep 8 14:48:23 CEST 2016


On Donnerstag, 8. September 2016 14:03:05 CEST Bo Thorsen wrote:
> Den 08-09-2016 kl. 13:47 skrev Milian Wolff:
> > On Donnerstag, 8. September 2016 13:41:21 CEST Bo Thorsen wrote:
> >> Den 05-09-2016 kl. 20:49 skrev Milian Wolff:
> >>>> As an incredibly simple example, make is inherently limited in that it
> >>>> 
> >>>>> cannot even represent a rule with multiple outputs (there are some
> >>>>> workarounds, but they are hacky and rather limited in how they can be
> >>>>> applied). And ninja is no magic bullet here either, because that still
> >>>>> represents a static build graph, whereas the content of Qbs' build
> >>>>> graph
> >>>>> can actually change during the execution of the build.
> >>> 
> >>> Can you give an example for why we should care? This may sound
> >>> flame-baity,
> >>> but I'm really truly interested. I simply don't care about my build
> >>> system, as long as it gets the job done without too much hassle (and
> >>> yes,
> >>> that is the case for me personally with cmake), and fast, too (which is
> >>> the case with ninja). See also below.
> >> 
> >> I can answer that because I asked for this feature all the way back at
> >> QtCS in Bilbao.
> >> 
> >> The context I was talking about was code generators. At the time I had
> >> built a code generator that created both the Qt and the PHP side of a
> >> client-server system. It had a single JSON file that described a server
> >> with the available remote methods on it. The output from the C++ code
> >> generator was a .h and .cpp file per method and a single .h and .cpp
> >> that described the server. So on qmake run time you can't know how many
> >> output files you have unless you force the user to run qmake every time
> >> you modify the JSON description.
> >> 
> >> And to make the problem worse, the customer wanted each of the classes
> >> describing a remote call to be qobjects with a Q_OBJECT so a moc run is
> >> required.
> >> 
> >> AFAIK this is impossible to do with both qmake and cmake. Not just hard,
> >> actually impossible.
> > 
> > At least for CMake, I don't think so - if I'm not misunderstanding the
> > problem. You add a target that depends on your .json file, and then
> > whenever that is changed you generate headers. Then you add a dependent
> > target which runs moc. And then you let your actual target depend on that
> > one?
> > 
> >> And the reason is that you can't know until build
> >> time what files you have to run moc on. (Now as a mental exersize,
> >> imagine having multiple server descriptions in a single json file...)
> > 
> > That is not an issue, no? You have one file that you need your targets
> > depend on - the JSON file. If that one changes, the dependent targets
> > must be rebuild.
> > 
> >> It's possible to do in pure make by calling the code generator and
> >> creating a sub make file and then calling make on that. But you can't do
> >> that in any way that supports hitting the build button once in QtCreator.
> >> 
> >> I finally solved this by convincing the customer it was sufficient to
> >> have a qobject base class for the remote calls and live without the meta
> >> object descriptions on those. And yes, this is a very specific case. But
> >> it's an example of something that neither cmake nor qmake can do because
> >> they have a makefile generating step.
> >> 
> >> Maybe this seems more important to me than others because I'm a huge fan
> >> of custom built code generators for stuff like database connections and
> >> client-server communications.
> > 
> > I'm not yet convinced.
> 
> Ok, go try it. Create a simple python or perl script that reads a file.
> The file just has a single number N inside it. And based on N the script
> outputs those files:
> 
> server.h
> method1.h
> method2.h
> ...
> methodN.h
> 
> Inside method1.h you write this:
> 
> #include <QObject>
> 
> class Method1 : public QObject {
>    Q_OBJECT
> };
> 
> server.h has this:
> 
> #include "method1.h"
> ...
> #include "methodN.h"
> 
> class Server {
> public:
>    Method1* call1() { return new Method1; }
>    ...
>    MethodN* callN() { return new MethodN; }
> };
> 
> In main.cpp you instantiate Server.
> 
> The only problem is that you have to run moc on each of the .h files.
> 
> Solution to the problem is only accepted if you can press build one
> single time inside both Visual Studio and Qt Creator and it builds this
> even when you modify the input file and the main.cpp.
> 
> I'm sure there are ways you can make the build call cmake or force a
> build to fail and rebuild, and that's what you can currently do. And
> those all feels annoying when you work on the project.
> 
> You asked why modifying the tree at build time could be necessary. This
> is one of the (probably very few) examples of it.

Someone else also told me that this is apparently harder then I thought it is 
with CMake, when the name of the output files of a code generator is not 
known. It is possible, but far from easy esp. when you don't have control over 
the generator script (though one can always use a wrapper). I see now that 
having support for this in QBS can be advantageous for the cases where one has 
such cases. Thankfully, I never ran into this so far, ever.

Cheers

-- 
Milian Wolff | milian.wolff at kdab.com | Software Engineer
KDAB (Deutschland) GmbH&Co KG, a KDAB Group company
Tel: +49-30-521325470
KDAB - The Qt Experts
-------------- next part --------------
A non-text attachment was scrubbed...
Name: smime.p7s
Type: application/pkcs7-signature
Size: 5903 bytes
Desc: not available
URL: <http://lists.qt-project.org/pipermail/development/attachments/20160908/cc5ca14e/attachment.bin>


More information about the Development mailing list