<table><tr><td style="">mpyne added a comment.
</td><a style="text-decoration: none; padding: 4px 8px; margin: 0 8px 8px; float: right; color: #464C5C; font-weight: bold; border-radius: 3px; background-color: #F7F7F9; background-image: linear-gradient(to bottom,#fff,#f1f0f1); display: inline-block; border: 1px solid rgba(71,87,120,.2);" href="https://phabricator.kde.org/D9334" rel="noreferrer">View Revision</a></tr></table><br /><div><div><blockquote style="border-left: 3px solid #8C98B8;
color: #6B748C;
font-style: italic;
margin: 4px 0 12px 0;
padding: 8px 12px;
background-color: #F8F9FC;">
<div style="font-style: normal;
padding-bottom: 4px;">In <a href="https://phabricator.kde.org/D9334#180881" style="background-color: #e7e7e7;
border-color: #e7e7e7;
border-radius: 3px;
padding: 0 4px;
font-weight: bold;
color: black;text-decoration: line-through;" rel="noreferrer">D9334#180881</a>, <a href="https://phabricator.kde.org/p/kossebau/" style="
border-color: #f1f7ff;
color: #19558d;
background-color: #f1f7ff;
border: 1px solid transparent;
border-radius: 3px;
font-weight: bold;
padding: 0 4px;" rel="noreferrer">@kossebau</a> wrote:</div>
<div style="margin: 0;
padding: 0;
border: 0;
color: rgb(107, 116, 140);"><blockquote style="border-left: 3px solid #8C98B8;
color: #6B748C;
font-style: italic;
margin: 4px 0 12px 0;
padding: 8px 12px;
background-color: #F8F9FC;">
<div style="font-style: normal;
padding-bottom: 4px;">In <a href="https://phabricator.kde.org/D9334#180830" style="background-color: #e7e7e7;
border-color: #e7e7e7;
border-radius: 3px;
padding: 0 4px;
font-weight: bold;
color: black;text-decoration: line-through;" rel="noreferrer">D9334#180830</a>, <a href="https://phabricator.kde.org/p/mpyne/" style="
border-color: #f1f7ff;
color: #19558d;
background-color: #f1f7ff;
border: 1px solid transparent;
border-radius: 3px;
font-weight: bold;
padding: 0 4px;" rel="noreferrer">@mpyne</a> wrote:</div>
<div style="margin: 0;
padding: 0;
border: 0;
color: rgb(107, 116, 140);"><p>In fact this appears to force files containing <tt style="background: #ebebeb; font-size: 13px;">K_PLUGIN_FACTORY*</tt> into being evaluated by CMake's AUTOMOC (other warning fixes removed files from consideration by CMake AUTOMOC).</p>
<p>CMake itself appears to have had an interface change for AUTOMOC between 3.8 and 3.9+.</p>
<p>In particular, <a href="https://cmake.org/cmake/help/v3.8/manual/cmake-qt.7.html#automoc" class="remarkup-link" target="_blank" rel="noreferrer">https://cmake.org/cmake/help/v3.8/manual/cmake-qt.7.html#automoc</a></p>
<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>If the macro is found in a C++ implementation file, the moc output will be put into a file named according to <basename>.moc, following the Qt conventions. The moc file may be included by the user in the C++ implementation file with a preprocessor #include. If it is not so included, it will be added to a separate file which is compiled into the target.</p></blockquote>
<p>vs. <a href="https://cmake.org/cmake/help/v3.9/manual/cmake-qt.7.html#automoc" class="remarkup-link" target="_blank" rel="noreferrer">https://cmake.org/cmake/help/v3.9/manual/cmake-qt.7.html#automoc</a></p>
<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>If the macro is found in a C++ implementation file, the moc output will be put into a file named according to <basename>.moc, following the Qt conventions. The <basename>.moc must be included by the user in the C++ implementation file with a preprocessor #include.</p></blockquote></div>
</blockquote>
<p>Not sure if this is a behavioural change, or rather a fix in the docu.</p></div>
</blockquote>
<p>It's definitely at least a behavior change. Before, CMake's AUTOMOC would generate a separate <tt style="background: #ebebeb; font-size: 13px;">moc_foo.cpp</tt> and automatically add it to the project being built, unless the user manually added an <tt style="background: #ebebeb; font-size: 13px;">#include "foo.moc"</tt> within the appropriate .cpp file. So the user could allow moc to generate a separate file and then have it compiled and linked separately, or include it directly in the .cpp file as used to be mandatory. From CMake 3.9 on, that is no longer true, and user code for moc files generated by AUTOMOC from classes found in a *.cpp* file now *must* be manually <tt style="background: #ebebeb; font-size: 13px;">#include</tt>'d into that .cpp file.</p>
<p>There may be reasons for this, I'm not sure, but the separate-compilation model for moc has worked fine in CMake up to 3.9, even for classes being moc'd that were defined in a .cpp.</p>
<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>unless I missed something, the code in the moc file has to see (or rather the compiler compiling it) the declaration of the class with the Q_OBJECT macro, as the code consists of the definitions of those declarations done by the Q_OBJECT macro.</p></blockquote>
<p>Yes, moc has to see the class that is using Q_OBJECT and, of course, generate the member function implementations for the methods added by the Q_OBJECT macro. So</p>
<blockquote style="border-left: 3px solid #a7b5bf; color: #464c5c; font-style: italic; margin: 4px 0 12px 0; padding: 4px 12px; background-color: #f8f9fc;"><p>And if the macro is used for a declaration in a cpp file, the moc file cannot include the cpp file (otherwise the cpp definition content would be compiled 2x), so it has to be rather the cpp file which explicitely includes the moc file (after the code with the class with the Q_OBJECT declaration).</p></blockquote>
<p>Compiling the same file twice is certainly less efficient but it's not actually a C++ violation due to the one-definition rule (ODR). The linker gets to figure out what happens with duplicate symbols. Of course if the common subset of code in the foo.cpp compiles *differently* somehow when compiled as part of a moc_foo.cpp then that means we've introduced undefined behavior. So this is much more brittle method of use.</p>
<p>All the same, in code meeting our quality standards, separate moc compilation of classes defined in a .cpp *should* be nothing but a missed opportunity for optimization, not something that is impossible to make work.</p>
<p>Given that this did catch an error in kwinscripts, it sounds like it may be a worthy behavior change, but I still think it's a behavior change, even in code that was not technically broken.</p></div></div><br /><div><strong>REPOSITORY</strong><div><div>R244 KCoreAddons</div></div></div><br /><div><strong>REVISION DETAIL</strong><div><a href="https://phabricator.kde.org/D9334" rel="noreferrer">https://phabricator.kde.org/D9334</a></div></div><br /><div><strong>To: </strong>mlaurent, dfaure<br /><strong>Cc: </strong>kossebau, mpyne, ngraham, Frameworks<br /></div>