[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-buildsystem
Subject:    Re: automoc4 corner issues - what lerned from qt-creator port
From:       Helio Chissini de Castro <helio () kde ! org>
Date:       2009-03-24 19:40:46
Message-ID: 200903241640.47571.helio () kde ! org
[Download RAW message or body]

<missing patch>
Attached is the new way better patch to handle cases 1, 2 and 4 correctly. 
3 still have need use the automoc4_moc_headers

An interesting case for 3 is generated headers from .ui files, 

[]'s

On Tuesday 24 of March 2009 15:36:19 Helio Chissini de Castro wrote:
> 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-handle-non-includes.patch" (text/x-patch)]

--- kde4automoc.cpp	2009-01-22 16:50:09.000000000 -0200
+++ kde4automoc-new.cpp	2009-03-24 16:33:56.000000000 -0300
@@ -340,15 +340,27 @@
             const QString absPath = sourceFileInfo.absolutePath() + '/';
             Q_ASSERT(absPath.endsWith('/'));
             int matchOffset = mocIncludeRegExp.indexIn(contentsString);
-            if (matchOffset < 0) {
+            int matchQObject = qObjectRegExp.indexIn(QString::fromUtf8(contents));
+
+            // Teste if .cpp file contains Q_OBJECT class and is not 
+            // already included
+            const QString sourceName = sourceFileInfo.completeBaseName();
+
+
+            qDebug() << mocIncludeRegExp.capturedTexts();
+
+            if (matchQObject && ! \
mocIncludeRegExp.capturedTexts().contains(sourceName + ".moc")) { +                \
notIncludedMocs.insert(absPath + sourceName + ".cpp", sourceName + ".moc" ); +        \
} +
+            if (matchOffset < 0 || ! \
                mocIncludeRegExp.capturedTexts().contains("moc_" + sourceName + \
                ".cpp")) {
                 // 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();
                 foreach (const QString &ext, headerExtensions) {
-                    const QString headername = absPath + basename + ext;
+                    const QString headername = absPath + sourceName + ext;
                     if (QFile::exists(headername) && \
                !includedMocs.contains(headername) &&
                             !notIncludedMocs.contains(headername)) {
-                        const QString currentMoc = "moc_" + basename + ".cpp";
+                        const QString currentMoc = "moc_" + sourceName + ".cpp";
                         QFile header(headername);
                         header.open(QIODevice::ReadOnly);
                         const QByteArray contents = header.readAll();
@@ -360,10 +372,10 @@
                     }
                 }
                 foreach (const QString &ext, headerExtensions) {
-                    const QString privateHeaderName = absPath + basename + "_p" + \
ext; +                    const QString privateHeaderName = absPath + sourceName + \
                "_p" + ext;
                     if (QFile::exists(privateHeaderName) && \
                !includedMocs.contains(privateHeaderName) &&
                             !notIncludedMocs.contains(privateHeaderName)) {
-                        const QString currentMoc = "moc_" + basename + "_p.cpp";
+                        const QString currentMoc = "moc_" + sourceName + "_p.cpp";
                         QFile header(privateHeaderName);
                         header.open(QIODevice::ReadOnly);
                         const QByteArray contents = header.readAll();
@@ -374,7 +386,9 @@
                         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
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic