[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