[cmake-developers] Current deficiencies of automoc
Sebastian Holtermann
seblist at xwmw.org
Mon Nov 14 03:06:36 EST 2016
Am 13.11.2016 um 07:48 schrieb Alan W. Irwin:
> On 2016-10-22 19:49+0200 Sebastian Holtermann wrote:
>
> [...]
>> Actually I made an implementation in 3.6.0 that generated the moc files
>> in the a build tree subdirectory correspoding to the header path.
>> But that blew up on some projects because the generated paths got too
>> long for some compiĺers. That implementation was theefore reverted.
>> In 3.7 there is a new approatch that generates the moc files in
>> ${CMAKE_BINARY_DIR}/
>> ${TARGETNAME}_automoc.dir/
>> ${HEADERNAME}_${HEADERPATHCHECKSUM}.cpp
>> This ensures that the paths don't get too long and that there won't be
>> any name collisions.
>
> Hi Sebastian:
>
> After a substantial break to finish off a different project, I have
> now had a chance to return to the present topic using my attached
> test_automoc project. (Also available in the cmake/test_automoc
> subdirectory of the PLplot git master branch that can be accessed at
> <https://sourceforge.net/p/plplot/plplot/ci/master/tree/>.) The
> project builds 6 separate simple Qt5 applications that #include a
> header that needs moc processing. The only differences between the
> source code files for the various executables is the name and
> directory location of that #include'd file and the various instructions
> given to automoc (and in one case qt5_wrap_cpp) to process that file.
>
> With that test project, I now confirm (sorry about the noise to the
> contrary before) that automoc does use the approach you mentioned
> above for CMake-3.7.0 to reduce the name collisions that occur for
> that same project for earlier versions of CMake.
>
> Concerning the collisions still expected for 3.7.0, the automoc
> documentation (see
> <https://cmake.org/cmake/help/v3.7/prop_tgt/AUTOMOC.html>) states the
> following:
>
> "However, if multiple source files in different directories do this
> [i.e., contain an "#include "moc_<headerbasename>.cpp" when the header
> name is <headerbasename>.h] then their generated moc files would
> collide. In this case a diagnostic will be issued."
>
> For the life of me, I cannot find a way to generate that diagnostic.
> Instead, three different targets (two targets concerning the same
> implementation code and header in the same directory and a third
> target for a copy of that same implementation code and header in a
> different directory) generate at build time a file named
> moc_test_q_object.cpp in the same build directory at different times.
> This is a clear example of a three-way name collision, but CMake does
> not issue a diagnostic for any of these targets concerning that
> collision contrary to the above documentation.
>
> Could you please take a look at the three last executables configured
> for this test case (helloworld_automoc_same_include,
> helloworld_automoc_same_include1, and
> helloworld_automoc_same_include2) to see why that collision diagnostic
> is not being issued with cmake-3.7.0? Better yet, of course, would be
> to solve these remaining name collisions completely by using a
> modification of your idea above, i.e., for this special case where
> users implementation code contained
>
> #include "moc_<headerbasename>.cpp"
>
> then moc should generate the file
>
> ${CMAKE_BINARY_DIR}/${TARGETNAME}_automoc.dir/${HEADERPATHCHECKSUM}/moc_${HEADERNAME}.cpp
>
>
> Note, the generated moc file has the name expected by the #include so
> I believe this idea would work so long as automoc automatically
> appended
> ${CMAKE_BINARY_DIR}/${TARGETNAME}_automoc.dir/${HEADERPATHCHECKSUM} to
> the target INCLUDE_DIRECTORIES property.
>
Hi Alan,
the automoc diagnostic checks for name collisions within a single target
only, not across multiple targets - as in your example.
The problem I see is that all moc files included by the
#include "moc_<headerbasename>.cpp"
scheme get generated in ${CMAKE_BINARY_DIR}.
It would be better to generate them in
${CMAKE_BINARY_DIR}/${TARGETNAME}_automoc.dir
to avoid inter target name collisions.
Your solution using the path checksum as well would be event better
as it avoids name collisions even within a target.
The problem there is though that it would require to add
a .cpp file specific -I compiler statement for every .cpp file
that includes a moc file.
This is hard to do with the current automoc implementation.
I would not want to do it.
What probably could be done is to add
${CMAKE_BINARY_DIR}/${TARGETNAME}_automoc.dir
to the INCLUDE_DIRECTORIES of the target and then generate all
#included moc file there, accepting the risk of intra target name
collisions.
-Sebastian
More information about the cmake-developers
mailing list