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

Bo Thorsen bo at vikingsoft.eu
Thu Sep 8 14:03:05 CEST 2016


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.

Bo Thorsen,
Director, Viking Software.

-- 
Viking Software
Qt and C++ developers for hire
http://www.vikingsoft.eu



More information about the Development mailing list