Hi

Since i finished the port of qt-creator build, i'm trying to identify why 
automoc4 wasn't been able to build without patches adding moc_* in some codes  
but qmake can.

DFaure helped a lot to identify the issue, and we have four corner cases to be 
treated:

1 - w.cpp have an internal Q_OBJECT class and includes w.h with other class 
with Q_OBJECT, and have on code #include "moc_w.cpp" and #include "w.moc"

2 - w.cpp have an internal Q_OBJECT class and includes w.h with other class 
with Q_OBJECT, but have only  "w.moc"

3 - w.cpp, independent of having internal Q_OBJECT class, includes a different 
header, y.h with a Q_OBJECT class, but without correspondent y.cpp code

4 - w.cpp have an internal Q_OBJECT class and includes w.h with other class 
with Q_OBJECT but have no moc includes.

qmake can handle all cases, based on addition of headers and sources on .pro, 
so where and why automoc4 fails:

* On case 1: Autmoc4 works 100%

* On case 2: Automoc4 generates w.moc, but not generates moc_w.cpp. This 
results in a linker error when using --no-undefined.
The case is that automoc4 detects the existency of a w.moc header and simply 
discards the fact that exists an Q_OBJECT inside the cpp, so was a logic 
question.
As automoc4 handles the case of having no moc includes, i did a patch that 
test case 2 and solve case 2. Patch attached, don't know if is the best 
approach

* On case 3: There's no way to do it automatically. Automoc4 can solve in 
CMakeLists using AUTOMOC4_MOC_HEADERS( <target> y.h )
Is similar as qmake parsing headers, so in this case we still need add the 
headers that not match for all the cases. A *perfect world* solution would be 
automoc4 parse the local includes in source and verify if are standalone and 
have Q_OBJECT, but is not a trivial change and should touch too much in the 
current automoc4 structure. But is doable

* On case 4: The right behavior is add only w.moc, and of course not test the 
.cpp, not generating moc_w.cpp falling in case 2. I'm expanding my patch to 
cover this one.

For who want to help or test, i borrowed a dfaure's example an tweaked to be 
Qt only and have w.cpp with all moc includes commented. Is located in 
<kdesvnserver>/trunk/branches/work/~helio/
The default status is failing on case 3 and 4 leading to case 2.

[]'s

-- 
Helio Chissini de Castro
KDE Developer
Brasil/South America Primary Contact
--- kde4automoc.cpp	2009-01-22 16:50:09.000000000 -0200
+++ kde4automoc-new.cpp	2009-03-23 18:06:58.000000000 -0300
@@ -282,6 +282,7 @@
     QHash<QString, QString> notIncludedMocs; // key = moc source filepath, value = moc output filename
 
     QRegExp mocIncludeRegExp(QLatin1String("[\n]\\s*#\\s*include\\s+[\"<]((?:[^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"));
+    QRegExp mocSourceIncludeRegExp(QLatin1String("[\n]\\s*#\\s*include\\s+[\"<]((?:[^ \">]+/)?moc_[^ \">/]+\\.cpp)[\">]"));
     QRegExp qObjectRegExp(QLatin1String("[\n]\\s*Q_OBJECT\\b"));
     QStringList headerExtensions;
 #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
@@ -340,7 +341,10 @@
             const QString absPath = sourceFileInfo.absolutePath() + '/';
             Q_ASSERT(absPath.endsWith('/'));
             int matchOffset = mocIncludeRegExp.indexIn(contentsString);
-            if (matchOffset < 0) {
+            int matchSourceOffset = mocSourceIncludeRegExp.indexIn(contentsString);
+            int matchQObject = qObjectRegExp.indexIn(QString::fromUtf8(contents));
+            if ( ( matchSourceOffset < 0 && matchQObject >= 0 ) || matchOffset < 0 )
+            {
                 // no moc #include, look whether we need to create a moc from the .h nevertheless
                 //qDebug() << "no moc #include in the .cpp file";
                 const QString basename = sourceFileInfo.completeBaseName();
@@ -374,7 +378,10 @@
                         break;
                     }
                 }
-            } else {
+            }
+            
+            if ( matchOffset >= 0 )
+            {
                 do { // call this for every moc include in the file
                     const QString currentMoc = mocIncludeRegExp.cap(1);
                     //qDebug() << "found moc include: " << currentMoc << " at offset " << matchOffset;
_______________________________________________
Kde-buildsystem mailing list
[email protected]
https://mail.kde.org/mailman/listinfo/kde-buildsystem

Reply via email to