[CMake] Forcibly run 'moc' on Qt files that are NOT part of the build

Michael Jackson mike.jackson at bluequartz.net
Thu Mar 8 11:44:40 EST 2012


On Thu, Mar 8, 2012 at 11:30 AM, Andreas Pakulat <apaku at gmx.de> wrote:
> On 08.03.12 09:50:55, Michael Jackson wrote:
>> On Mar 7, 2012, at 11:43 AM, Andreas Pakulat wrote:
>>
>> > On 07.03.12 10:10:27, Michael Jackson wrote:
>> >> In an effort to speed up the build of a project that uses Qt (and moc) I tried an alternate approach with the moc files. Normally I use the basic idea of gathering the headers that need to be "moc'ed" and feed those to moc with this type of CMake Code:
>> >>
>> >> QT4_WRAP_CPP( FilterWidgets_Generated_MOC_SRCS ${QFilterWidget_HDRS} ${FilterWidget_GEN_HDRS})
>> >>
>> >> The in the Add_Executable(...) call include the ${FilterWidgets_Generated_MOC_SRCS} variable to the list of sources. In my project I have at least 30 auto-generated files which all get moc'ed. That gives me an additional 60 compiled files. So I tried the idea of #include "moc_[some_file.cxx]" in each of the auto-generated .cpp files for each Widget. This would cut the number of files compiled in half. The issue is that since they are being #include'ed in the .cpp files then they do NOT need to be compiled themselves so I took the ${FilterWidgets_Generated_MOC_SRCS} out of the list of sources in the add_executable() call. What happened is that CMake did NOT run moc on those headers because there were now NOT included in the build.
>> >>
>> >> So for that version of the cmake code I have something like this:
>> >>
>> >> QT4_WRAP_CPP( FilterWidgets_Generated_MOC_SRCS ${FilterWidget_GEN_HDRS})
>> >> QT4_WRAP_CPP( FilterWidgets_MOC_SRCS ${QFilterWidget_HDRS} )
>> >>
>> >> Is there a way to forcibly run the moc step even if the resulting source files are NOT directly included in the add_executable? Custom_Command? Add_Depends?
>> >
>> > A few options I can think of:
>> >
>> > - Use the automoc developed as part of KDE (its pure-Qt though)
>> >    https://projects.kde.org/projects/kdesupport/automoc/repository
>> > - Use the automoc function from FindQt4.cmake
>> > - Use the new automoc function in CMake 2.8.7
>> >
>> > All of these will help handle the qt4_wrap_cpp stuff for you as long as
>> > you have the #include. Note that I think there's at least 2 or 3
>> > differnet filenames for the include depending on which of the above you
>> > use (foo.moc vs moc_foo.cpp vs. moc_foo.cxx or something like that).
>> >
>> > If none of them is an option for you then I guess using
>> > add_custom_target and add_dependencies is the way to go.
>> >
>> > Andreas
>> >
>> I looked into the automoc functionality and after some tinkering around I think there is still a disconnect in my cmake code. When are the source/header files scanned by automoc to determine if they will have moc run on them.
>>    Currently during cmake time I generate a blank header and source file (well, there is a #error ... in them) which then get over written by a new files during build time. The new files are complete and proper C++ source files/headers with the Q_OBJECT macro in the header and #include "moc_*.cpp" in the source file. When I compile (using makefiles on OS X currently as a test) I get an error that the moc_*.cpp file can not be found and searching the entire build directory does not reveal the file. If I run CMake again and compile then the auto moc files do appear. From this I think that automoc runs during CMake time. Is this correct?
>
> Yes, all three automoc's do the header-check during cmake-time. But if
> you already generate the source files during build-time couldn't you add
> another step for running moc there?
>
> Andreas
>

I ended up using the hint that Michael gave about setting the source
files properties to "HEADER_ONLY". This combination gives the proper
dependencies between my build time generation of the source files and
the need to moc those files. Along with some other techniques recently
brought up on the list I was able to optimize our builds and shave
over 95% of the build time for rebuilds. Thanks to everyone for their
time, patience and explanations.

Thanks
--
Mike J.


More information about the CMake mailing list