From kde-buildsystem Tue Mar 24 19:40:46 2009 From: Helio Chissini de Castro Date: Tue, 24 Mar 2009 19:40:46 +0000 To: kde-buildsystem Subject: Re: automoc4 corner issues - what lerned from qt-creator port Message-Id: <200903241640.47571.helio () kde ! org> X-MARC-Message: https://marc.info/?l=kde-buildsystem&m=123792372104864 MIME-Version: 1 Content-Type: multipart/mixed; boundary="--Boundary-00=_/cTyJS2hsVSHkYO" --Boundary-00=_/cTyJS2hsVSHkYO Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Content-Disposition: inline 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( 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 > /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 --Boundary-00=_/cTyJS2hsVSHkYO Content-Type: text/x-patch; charset="UTF-8"; name="kde4automoc-handle-non-includes.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="kde4automoc-handle-non-includes.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; --Boundary-00=_/cTyJS2hsVSHkYO Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Kde-buildsystem mailing list Kde-buildsystem@kde.org https://mail.kde.org/mailman/listinfo/kde-buildsystem --Boundary-00=_/cTyJS2hsVSHkYO--