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

List:       kde-core-devel
Subject:    Re: automoc4 and subdirs
From:       Matthias Kretz <kretz () kde ! org>
Date:       2008-07-31 13:07:06
Message-ID: 200807311507.07203.kretz () kde ! org
[Download RAW message or body]

On Thursday 31 July 2008 01:47:28 Aaron J. Seigo wrote:
> hi all...
>
> so i just found out that automoc4 will fail on things like:
>
> #include "subdir/foo.moc"

That pattern doesn't exist anywhere else in the KDE sources AFAIK. What is 
supported now, is to add
AUTOMOC4_MOC_HEADERS(subdir/foo.h)
to your CMakeLists.txt and not #include the moc file. Of course this is only 
possible if you don't use Q_PRIVATE_SLOT.

> the attached patch is a quick hack to make it work, by preserving the path
> and trying to create the moc file properly.

The patch looks good except for an incorrect (I think) s/basename/currentMoc/ 
on line 384.

Also the mkpath looks more complicated than I'd expect. QDir::mkpath could 
certainly use some better docs...

See attached patch.

> is there any particular reason why automoc4 doesn't already support this
> other than "nobody has done it" or is something like this ok to commit?

"nobody has done it"

-- 
________________________________________________________
Matthias Kretz (Germany)                            <><
http://Vir.homelinux.org/
MatthiasKretz@gmx.net, kretz@kde.org,
Matthias.Kretz@urz.uni-heidelberg.de


["automoc.diff" (text/x-patch)]

Index: kde4automoc.cpp
===================================================================
--- kde4automoc.cpp	(revision 839933)
+++ kde4automoc.cpp	(working copy)
@@ -25,6 +25,7 @@
 
 #include <QtCore/QCoreApplication>
 #include <QtCore/QDateTime>
+#include <QtCore/QDir>
 #include <QtCore/QFile>
 #include <QtCore/QFileInfo>
 #include <QtCore/QHash>
@@ -257,7 +258,7 @@
     QHash<QString, QString> includedMocs;    // key = moc source filepath, value = \
                moc output filepath
     QHash<QString, QString> notIncludedMocs; // key = moc source filepath, value = \
moc output filename  
-    QRegExp mocIncludeRegExp(QLatin1String("[\n]\\s*#\\s*include\\s+[\"<](moc_[^ \
\">]+\\.cpp|[^ \">]+\\.moc)[\">]")); +    QRegExp \
mocIncludeRegExp(QLatin1String("[\n]\\s*#\\s*include\\s+[\"<]((?:[^ \">]+/)?moc_[^ \
\">/]+\\.cpp|[^ \">]+\\.moc)[\">]"));  QRegExp \
qObjectRegExp(QLatin1String("[\n]\\s*Q_OBJECT\\b"));  QStringList headerExtensions;
 #ifdef Q_OS_WIN
@@ -354,12 +355,30 @@
                 do { // call this for every moc include in the file
                     const QString currentMoc = mocIncludeRegExp.cap(1);
                     //qDebug() << "found moc include: " << currentMoc << " at offset \
                " << matchOffset;
-                    QString basename = QFileInfo(currentMoc).completeBaseName();
-                    const bool moc_style = currentMoc.startsWith("moc_");
+                    const QFileInfo currentMocInfo(currentMoc);
+                    QString basename = currentMocInfo.completeBaseName();
+                    const bool moc_style = basename.startsWith("moc_");
+
+                    // If the moc include is of the moc_foo.cpp style we expect the \
Q_OBJECT class +                    // declaration in a header file.
+                    // If the moc include is of the foo.moc style we need to look \
for a Q_OBJECT +                    // macro in the current source file, if it \
contains the macro we generate the +                    // moc file from the source \
file, else from the header. +                    //
+                    // TODO: currently any .moc file name will be used if the source \
contains +                    // Q_OBJECT
                     if (moc_style || qObjectRegExp.indexIn(contentsString) < 0) {
                         if (moc_style) {
+                            // basename should be the part of the moc filename used \
for finding the +                            // correct header, so we need to remove \
                the moc_ part
                             basename = basename.right(basename.length() - 4);
                         }
+
+                        // the moc file is in a subdir => look for the header in the \
same subdir +                        if (currentMoc.indexOf('/') != -1) {
+                            basename.prepend('/').prepend(currentMocInfo.path());
+                        }
+
                         bool headerFound = false;
                         foreach (const QString &ext, headerExtensions) {
                             QString sourceFilePath = absPath + basename + ext;
@@ -489,7 +508,14 @@
 {
     //qDebug() << Q_FUNC_INFO << sourceFile << mocFileName;
     const QString mocFilePath = builddir + mocFileName;
-    if (generateAll || QFileInfo(mocFilePath).lastModified() <= \
QFileInfo(sourceFile).lastModified()) { +    QFileInfo mocInfo(mocFilePath);
+    if (generateAll || mocInfo.lastModified() <= \
QFileInfo(sourceFile).lastModified()) { +        QDir mocDir = mocInfo.dir();
+        // make sure the directory for the resulting moc file exists
+        if (!mocDir.exists()) {
+            mocDir.mkpath(mocDir.path());
+        }
+
         static bool initialized = false;
         if (!initialized) {
             initialized = true;
Index: Automoc4Version.cmake
===================================================================
--- Automoc4Version.cmake	(revision 839472)
+++ Automoc4Version.cmake	(working copy)
@@ -1,7 +1,7 @@
 # set the current version number
 set(AUTOMOC4_VERSION_MAJOR  "0")
 set(AUTOMOC4_VERSION_MINOR  "9")
-set(AUTOMOC4_VERSION_PATCH "85")
+set(AUTOMOC4_VERSION_PATCH "86")
 
 set(AUTOMOC4_VERSION \
"${AUTOMOC4_VERSION_MAJOR}.${AUTOMOC4_VERSION_MINOR}.${AUTOMOC4_VERSION_PATCH}")  



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

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