Qt update

Alberto Mardegan mardy at users.sourceforge.net
Tue Apr 9 10:13:57 PDT 2013


On 04/09/2013 08:02 PM, Dirk Hohndel wrote:
> Alberto Mardegan <mardy at users.sourceforge.net> writes:
>
>> Seems to work here, but please test before applying. :-)
>
> How would I test without applying it? :-)
>
> Or are you implying that I usually don't test the code that I push out?
> I at least try...

Hehe, no, I simply thought that, since the Qt branch is at its early 
stages, you might not be testing all changes before pushing them -- 
especially those regarding the Makefile which are especially boring. :-)

>> +# Add the objects for the header files which define QObject subclasses
>> +HEADERS_NEEDING_MOC += $(shell grep -l -s 'Q_OBJECT' $(OBJS:.o=.h))
>> +MOC_OBJS = $(HEADERS_NEEDING_MOC:.h=.moc.o)
>
> So this assumes that every Q_OBJECT will have both a .cpp and a .h file.
> I guess that is normal in Qt...

Not exactly "assumes", but rather uses that as a heuristic.
The rule above says that if a header file contains the Q_OBJECT test, 
then a <filename>.moc.o object needs to be built. Note that there isn't 
a corresponding .cpp file in the git repo; it's generated by the moc 
with the "%.moc.cpp" rule I re-added.

>> +ALL_OBJS = $(OBJS) $(MOC_OBJS)
>
> Why not just add them to OBJS?

That's what I did at first, but it causes "make" to complain that the 
OBJS variable is recursively modified.

>> +# Detect which files require the moc or uic tools to be run
>> +CPP_NEEDING_MOC = $(shell grep -l -s '^\#include \".*\.moc\"' $(OBJS:.o=.cpp))
>
> OBJS contains objects that stem from .c files as well... so this won't
> work for those.

It works, it just ignores them: the "$(OBJS:.o=.cpp)" expression indeed 
expands to a lot of filenames ending in .cpp which don't exist, but grep 
ignores them (see the "-s" option of grep).

>> +OBJS_NEEDING_MOC += $(CPP_NEEDING_MOC:.cpp=.o)
>
> So now we have HEADERS_NEEDING_MOC and CPP_NEEDING_MOC but
> OBJS_NEEDING_MOC only uses CPP_NEEDING_MOC. How come?

OBJS_NEEDING_MOC = list of object files which, in addition to the 
.c/.cpp source file, depend on a .moc file

CPP_NEEDING_MOC = temporary variable, only functional to compute the 
other variable

HEADERS_NEEDING_MOC = list of headers files using the Q_OBJECT macro. 
These files need to be processed by the moc tool, but the resulting file 
(which we name as <filename>.moc.cpp) is not included by any other file 
and therefore needs to be compiled as a .o object of its own.

>> +CPP_NEEDING_UIC = $(shell grep -l -s '^\#include \"ui_.*\.h\"' $(OBJS:.o=.cpp))
>> +OBJS_NEEDING_UIC += $(CPP_NEEDING_UIC:.cpp=.o)
>
> Again, what about the C files?

Same as above: we ask grep to grep over a number of files, some of which 
don't exist; it will just ignore them.

> Wouldn't it make more sense to have
>
> OBJS     == all object files as it used to be
> QT_OBJS  == all Qt/C++ object files - those are the ones used for the
>              xxx_NEEDING_yyy macros
> MOC_OBJS == object files created from .moc files created from .h files
>              (do I have that right?)

You got it right, except the second point: QT_OBJS (at least the way 
that I understood it) is just a variable added to OBJS whose sole goal 
is to make the OBJS definition shorter, by defining the UI files in 
another variable.
The .cpp files generating QT_OBJS might or might not need to be 
processed by the moc/uic.
Though indeed, now that you make me think of it, my rules above could be 
optimized by grepping on QT_OBJS, rather than OBJS (that would guarantee 
that we are talking about .cpp files).

To summarize: there are three kind of processing which we apply:

1) uic: if a file has a "#include "ui_<filename>.h" line

2) moc on header: if a .h file has a "Q_OBJECT" line, we need to run 
"moc" on it, build the C++ file which the moc generates, and add the 
compiled object to the linker

3) moc on .cpp: if a .cpp file has a "#include "<filename>.moc" line,
we run "moc" on it *before compiling the .cpp file*, because the moc 
generates the "<filename>.moc" file which the .cpp file includes

If may also be that the same couple of .cpp/.h files requires all three 
of these rules.

>> @@ -13,5 +13,3 @@ void MainWindow::on_actionNew_triggered()
>>   {
>>       qDebug() << "actionNew";
>>   }
>> -
>> -#include "mainwindow.moc"
>
> So all the rules above imply that we still need to do the #include on
> the .moc files, yet you remove that here. Let me take a wild guess.
>
> If the classes are defined in .h files then we don't need the #include,
> but if they are defined in .cpp files then we do?

Exactly!

Ciao,
   Alberto


More information about the subsurface mailing list