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

Konstantin Tokarev annulen at yandex.ru
Thu Sep 8 14:19:08 CEST 2016



08.09.2016, 15:03, "Bo Thorsen" <bo at vikingsoft.eu>:
> 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.

Run moc from inside script when you generate header.

>
> 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
> _______________________________________________
> Development mailing list
> Development at qt-project.org
> http://lists.qt-project.org/mailman/listinfo/development

-- 
Regards,
Konstantin



More information about the Development mailing list