Hi,

attached you'll find the next generation of automoc

I replaced kde4automoc.cmake with a C++/QtCore based program that can run more 
efficient.

Instead of creating a <targetname>.automoc file that is added to the target I 
create a <targetname>_automoc.cpp file now that is compiled and linked into 
the target. This file #includes all moc files that are not included by other 
source files. This way the automoc can, at make-time, decide what mocs need 
to be compiled explicitly and linked into the target.

E.g. the following is possible now:
foo.h:
class A : public QObject
{
  Q_OBJECT
...
};

foo.cpp does not #include "foo.moc"

run make - everything compiles and links fine (without mentioning the header 
in KDE4_MOC_HEADERS either since the new automoc looks at all corresponding 
header files from the .cpp files by itself)

now change foo.cpp to #include "foo.moc"

running make now will just work, even with the /fast target.

Next change I did was to create a <targetname>_automoc.cpp.files file to pass 
the moc includes and the source files that belong to the target to the 
automoc. I could have kept it on the command line but I got a report that the 
command line was already too long for Windows' cmd.exe.

Implementation details:
- The messages of the automoc are written using cmake -E cmake_echo_color, so 
the automoc correctly colorizes its messages now.
- The moc QProcesses are started in parallel (up to 10).

Please test and let me know if you have any problems (you might have to remove 
some explicit QT4_WRAP_CPP calls from CMakeLists.txt now). I'd like to commit 
soon, as this is supposed to fix compilation on Windows again...

-- 
________________________________________________________
Matthias Kretz (Germany)                            <><
http://Vir.homelinux.org/
[EMAIL PROTECTED], [EMAIL PROTECTED],
[EMAIL PROTECTED]
Index: automoc/kde4automoc.cpp
===================================================================
--- automoc/kde4automoc.cpp	(revision 0)
+++ automoc/kde4automoc.cpp	(revision 0)
@@ -0,0 +1,270 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2007 Matthias Kretz <[EMAIL PROTECTED]>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License version 2
+    as published by the Free Software Foundation.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+    02110-1301, USA.
+
+*/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QDateTime>
+#include <QtCore/QFile>
+#include <QtCore/QFileInfo>
+#include <QtCore/QHash>
+#include <QtCore/QProcess>
+#include <QtCore/QQueue>
+#include <QtCore/QRegExp>
+#include <QtCore/QStringList>
+#include <QtCore/QTextStream>
+#include <QtCore/QtDebug>
+#include <cstdlib>
+
+class AutoMoc
+{
+    public:
+        AutoMoc();
+        ~AutoMoc();
+        void run();
+
+    private:
+        void generateMoc(const QString &sourceFile, const QString &mocFileName);
+        void usage(const QString &);
+        void echoColor(const QString &msg)
+        {
+            QProcess cmakeEcho;
+            cmakeEcho.setProcessChannelMode(QProcess::ForwardedChannels);
+            QStringList args(cmakeEchoColorArgs);
+            args << msg;
+            cmakeEcho.startDetached("cmake", args);
+        }
+
+        QString bindir;
+        QString mocExe;
+        QStringList mocIncludes;
+        QStringList cmakeEchoColorArgs;
+        const bool verbose;
+        QTextStream cerr;
+        QTextStream cout;
+        QQueue<QProcess *> mocProcesses;
+};
+
+void AutoMoc::usage(const QString &path)
+{
+    cout << "usage: " << path << " <outfile> <srcdir> <bindir> <moc executable>" << endl;
+    ::exit(EXIT_FAILURE);
+}
+
+int main(int argc, char **argv)
+{
+    QCoreApplication app(argc, argv);
+    AutoMoc().run();
+    return 0;
+}
+
+AutoMoc::AutoMoc()
+    : verbose(!QByteArray(getenv("VERBOSE")).isEmpty()), cerr(stderr), cout(stdout)
+{
+    const QByteArray colorEnv = getenv("COLOR");
+    cmakeEchoColorArgs << "-E" << "cmake_echo_color" << QString("--switch=") + colorEnv << "--blue"
+        << "--bold";
+}
+
+void AutoMoc::run()
+{
+    const QStringList args = QCoreApplication::arguments();
+    Q_ASSERT(args.size() > 0);
+    if (args.size() < 4) {
+        usage(args[0]);
+    }
+    QFile outfile(args[1]);
+    const QFileInfo outfileInfo(outfile);
+
+    QString srcdir(args[2]);
+    if (!srcdir.endsWith('/')) {
+        srcdir += '/';
+    }
+    bindir = args[3];
+    if (!bindir.endsWith('/')) {
+        bindir += '/';
+    }
+    mocExe = args[4];
+
+    QFile dotFiles(args[1] + ".files");
+    dotFiles.open(QIODevice::ReadOnly | QIODevice::Text);
+    QByteArray line = dotFiles.readLine();
+    Q_ASSERT(line == "MOC_INCLUDES:\n");
+    line = dotFiles.readLine().trimmed();
+    const QStringList incPaths = QString::fromUtf8(line).split(';');
+    foreach (const QString &path, incPaths) {
+        mocIncludes << "-I" + path;
+    }
+    line = dotFiles.readLine();
+    Q_ASSERT(line == "SOURCES:\n");
+    line = dotFiles.readLine().trimmed();
+    dotFiles.close();
+    const QStringList sourceFiles = QString::fromUtf8(line).split(';');
+
+    // the program goes through all .cpp files to see which moc files are included. It is not really
+    // interesting how the moc file is named, but what file the moc is created from. Once a moc is
+    // included the same moc may not be included in the _automoc.cpp file anymore. OTOH if there's a
+    // header containing Q_OBJECT where no corresponding moc file is included anywhere a
+    // moc_<filename>.cpp file is created and included in the _automoc.cpp file.
+    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("[\n]\\s*#\\s*include\\s+[\"<](moc_[^ \">]+\\.cpp|[^ \">]+\\.moc)[\">]");
+    QRegExp qObjectRegExp("[\n]\\s*Q_OBJECT\\b");
+    foreach (const QString &absFilename, sourceFiles) {
+        //qDebug() << absFilename;
+        const QFileInfo absFilenameInfo(absFilename);
+        if (absFilename.endsWith(".cpp") || absFilename.endsWith(".cc") ||
+                absFilename.endsWith(".cxx") || absFilename.endsWith(".C")) {
+            //qDebug() << "check .cpp file";
+            QFile sourceFile(absFilename);
+            sourceFile.open(QIODevice::ReadOnly);
+            const QByteArray contents = sourceFile.readAll();
+            if (contents.isEmpty()) {
+                cerr << "kde4automoc: empty source file: " << absFilename << endl;
+                continue;
+            }
+            const QString contentsString = QString::fromUtf8(contents);
+            const QString absPath = absFilenameInfo.absolutePath() + '/';
+            Q_ASSERT(absPath.endsWith('/'));
+            int matchOffset = mocIncludeRegExp.indexIn(contentsString);
+            if (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 = absFilenameInfo.completeBaseName();
+                const QString headername = absPath + basename + ".h";
+                if (QFile::exists(headername) && !includedMocs.contains(headername) &&
+                        !notIncludedMocs.contains(headername)) {
+                    const QString currentMoc = "moc_" + basename + ".cpp";
+                    QFile header(headername);
+                    header.open(QIODevice::ReadOnly);
+                    const QByteArray contents = header.readAll();
+                    if (qObjectRegExp.indexIn(QString::fromUtf8(contents)) >= 0) {
+                        //qDebug() << "header contains Q_OBJECT macro";
+                        notIncludedMocs.insert(headername, currentMoc);
+                    }
+                }
+            } else {
+                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_");
+                    if (moc_style || qObjectRegExp.indexIn(contentsString) < 0) {
+                        if (moc_style) {
+                            basename = basename.right(basename.length() - 4);
+                        }
+                        const QString sourceFilePath = absPath + basename + ".h";
+                        if (!QFile::exists(sourceFilePath)) {
+                            cerr << "kde4automoc: The file \"" << absFilename <<
+                                "\" includes the moc file \"" << currentMoc << "\", but \"" <<
+                                sourceFilePath << "\" does not exist." << endl;
+                            ::exit(EXIT_FAILURE);
+                        }
+                        includedMocs.insert(sourceFilePath, currentMoc);
+                        notIncludedMocs.remove(sourceFilePath);
+                    } else {
+                        includedMocs.insert(absFilename, currentMoc);
+                        notIncludedMocs.remove(absFilename);
+                    }
+
+                    matchOffset = mocIncludeRegExp.indexIn(contentsString,
+                            matchOffset + currentMoc.length());
+                } while(matchOffset >= 0);
+            }
+        } else if (absFilename.endsWith(".h") || absFilename.endsWith(".hpp") ||
+                absFilename.endsWith(".hxx") || absFilename.endsWith(".H")) {
+            if (!includedMocs.contains(absFilename) && !notIncludedMocs.contains(absFilename)) {
+                // if this header is not getting processed yet and is explicitly mentioned for the
+                // automoc the moc is run unconditionally on the header and the resulting file is
+                // included in the _automoc.cpp file (unless there's a .cpp file later on that
+                // includes the moc from this header)
+                const QString currentMoc = "moc_" + absFilenameInfo.completeBaseName() + ".cpp";
+                notIncludedMocs.insert(absFilename, currentMoc);
+            }
+        } else {
+            if (verbose) {
+               cout << "kde4automoc: ignoring file '" << absFilename << "' with unknown suffix" << endl;
+            }
+        }
+    }
+
+    // run moc on all the moc's that are #included in source files
+    QHash<QString, QString>::ConstIterator end = includedMocs.constEnd();
+    QHash<QString, QString>::ConstIterator it = includedMocs.constBegin();
+    for (; it != end; ++it) {
+        generateMoc(it.key(), it.value());
+    }
+
+    // source file that includes all remaining moc files
+    outfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
+    QTextStream outStream(&outfile);
+    outStream << "/* This file is autogenerated, do not edit */\n";
+
+    // run moc on the remaining headers and include them in the _automoc.cpp file
+    end = notIncludedMocs.constEnd();
+    it = notIncludedMocs.constBegin();
+    for (; it != end; ++it) {
+        generateMoc(it.key(), it.value());
+        outStream << "#include \"" << it.value() << "\"\n";
+    }
+    outfile.close();
+}
+
+AutoMoc::~AutoMoc()
+{
+    // let all remaining moc processes finish
+    while (!mocProcesses.isEmpty()) {
+        QProcess *mocProc = mocProcesses.dequeue();
+        if (!mocProc->waitForFinished()) {
+            cerr << "kde4automoc: moc failed: " << mocProc->errorString() << endl;
+        }
+        delete mocProc;
+    }
+}
+
+void AutoMoc::generateMoc(const QString &sourceFile, const QString &mocFileName)
+{
+    //qDebug() << Q_FUNC_INFO << sourceFile << mocFileName;
+    const QString mocFilePath = bindir + mocFileName;
+    if (QFileInfo(mocFilePath).lastModified() < QFileInfo(sourceFile).lastModified()) {
+        if (verbose) {
+            echoColor("Generating " + mocFileName);
+        } else {
+            echoColor("Generating " + mocFilePath + " from " + sourceFile);
+        }
+
+        // we don't want too many child processes
+        if (mocProcesses.size() > 10) {
+            while (!mocProcesses.isEmpty()) {
+                QProcess *mocProc = mocProcesses.dequeue();
+                if (!mocProc->waitForFinished()) {
+                    cerr << "kde4automoc: moc failed: " << mocProc->errorString() << endl;
+                }
+                delete mocProc;
+            }
+        }
+
+        QProcess *mocProc = new QProcess;
+        mocProc->setProcessChannelMode(QProcess::ForwardedChannels);
+        QStringList args(mocIncludes);
+        args << "-o" << mocFilePath << sourceFile;
+        //qDebug() << "executing: " << mocExe << args;
+        mocProc->start(mocExe, args, QIODevice::NotOpen);
+        mocProcesses.enqueue(mocProc);
+    }
+}
Index: automoc/CMakeLists.txt
===================================================================
--- automoc/CMakeLists.txt	(revision 0)
+++ automoc/CMakeLists.txt	(revision 0)
@@ -0,0 +1,5 @@
+include_directories(${QT_INCLUDE_DIR})
+add_executable(kde4automoc kde4automoc.cpp)
+kde4_handle_rpath_for_executable(kde4automoc "RUN_UNINSTALLED")
+target_link_libraries(kde4automoc ${QT_QTCORE_LIBRARY})
+install(TARGETS kde4automoc DESTINATION ${BIN_INSTALL_DIR})
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 684432)
+++ CMakeLists.txt	(working copy)
@@ -1,3 +1,4 @@
 
+add_subdirectory(automoc)
 add_subdirectory(modules)
 
Index: modules/FindKDE4Internal.cmake
===================================================================
--- modules/FindKDE4Internal.cmake	(revision 684432)
+++ modules/FindKDE4Internal.cmake	(working copy)
@@ -16,6 +16,7 @@
 # compile KDE software:
 #
 # KDE4_KCFGC_EXECUTABLE    - the kconfig_compiler executable
+# KDE4_AUTOMOC_EXECUTABLE  - the kde4automoc executable
 # KDE4_MEINPROC_EXECUTABLE - the meinproc4 executable
 # KDE4_MAKEKDEWIDGETS_EXECUTABLE - the makekdewidgets executable
 #
@@ -389,11 +390,13 @@
       set(LIBRARY_OUTPUT_PATH  ${EXECUTABLE_OUTPUT_PATH} )
       # CMAKE_CFG_INTDIR is the output subdirectory created e.g. by XCode and MSVC
       set(KDE4_KCFGC_EXECUTABLE       ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/kconfig_compiler )
+      set(KDE4_AUTOMOC_EXECUTABLE     ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/kde4automoc )
       set(KDE4_MEINPROC_EXECUTABLE    ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/meinproc4 )
       set(KDE4_MAKEKDEWIDGETS_EXECUTABLE    ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/makekdewidgets )
    else (WIN32)
       set(LIBRARY_OUTPUT_PATH  ${CMAKE_BINARY_DIR}/lib )
       set(KDE4_KCFGC_EXECUTABLE       ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/kconfig_compiler.shell )
+      set(KDE4_AUTOMOC_EXECUTABLE     ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/kde4automoc.shell )
       set(KDE4_MEINPROC_EXECUTABLE    ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/meinproc4.shell )
       set(KDE4_MAKEKDEWIDGETS_EXECUTABLE    ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR}/makekdewidgets.shell )
    endif (WIN32)
@@ -402,6 +405,7 @@
 
    # when building kdelibs, make the kcfg rules depend on the binaries...
    set( _KDE4_KCONFIG_COMPILER_DEP kconfig_compiler)
+   set( _KDE4_AUTOMOC_EXECUTABLE_DEP kde4automoc)
    set( _KDE4_MAKEKDEWIDGETS_DEP makekdewidgets)
    set( _KDE4_MEINPROC_EXECUTABLE_DEP meinproc4)
 
@@ -411,6 +415,7 @@
 
   # ... but NOT otherwise
    set( _KDE4_KCONFIG_COMPILER_DEP)
+   set( _KDE4_AUTOMOC_EXECUTABLE_DEP)
    set( _KDE4_MAKEKDEWIDGETS_DEP)
    set( _KDE4_MEINPROC_EXECUTABLE_DEP)
 
@@ -530,6 +535,9 @@
    find_program(KDE4_KCFGC_EXECUTABLE NAME kconfig_compiler PATHS ${KDE4_BIN_INSTALL_DIR} NO_DEFAULT_PATH )
    find_program(KDE4_KCFGC_EXECUTABLE NAME kconfig_compiler )
 
+   find_program(KDE4_AUTOMOC_EXECUTABLE NAME kde4automoc PATHS ${KDE4_BIN_INSTALL_DIR} NO_DEFAULT_PATH )
+   find_program(KDE4_AUTOMOC_EXECUTABLE NAME kde4automoc )
+
    find_program(KDE4_MEINPROC_EXECUTABLE NAME meinproc4 PATHS ${KDE4_BIN_INSTALL_DIR} NO_DEFAULT_PATH )
    find_program(KDE4_MEINPROC_EXECUTABLE NAME meinproc4 )
 
@@ -864,6 +872,12 @@
    else(KDE4_KCFGC_EXECUTABLE)
       message(STATUS "Didn't find the KDE4 kconfig_compiler preprocessor")
    endif(KDE4_KCFGC_EXECUTABLE)
+
+   if(KDE4_AUTOMOC_EXECUTABLE)
+      message(STATUS "Found KDE4 automoc: ${KDE4_AUTOMOC_EXECUTABLE}")
+   else(KDE4_AUTOMOC_EXECUTABLE)
+      message(STATUS "Didn't find the KDE4 automoc")
+   endif(KDE4_AUTOMOC_EXECUTABLE)
 endmacro (KDE4_PRINT_RESULTS)
 
 
Index: modules/KDE4Macros.cmake
===================================================================
--- modules/KDE4Macros.cmake	(revision 684432)
+++ modules/KDE4Macros.cmake	(working copy)
@@ -8,7 +8,6 @@
 # KDE4_SET_CUSTOM_TARGET_PROPERTY
 # KDE4_GET_CUSTOM_TARGET_PROPERTY
 # KDE4_MOC_HEADERS
-# KDE4_APPEND_MOC_FILES
 # KDE4_HANDLE_AUTOMOC
 # KDE4_INSTALL_LIBTOOL_FILE
 # KDE4_CREATE_FINAL_FILES
@@ -184,25 +183,21 @@
    endif(_headers_to_moc)
 endmacro (KDE4_MOC_HEADERS)
 
-macro(KDE4_APPEND_MOC_FILES _target_name _SRCS)
-   KDE4_GET_CUSTOM_TARGET_PROPERTY(_headers_to_moc ${_target_name} AUTOMOC_HEADERS)
-   if(NOT _headers_to_moc STREQUAL "NOTFOUND")
-      qt4_get_moc_inc_dirs(_moc_INCS)
-      foreach (_current_FILE ${_headers_to_moc})
-         get_filename_component(_basename "${_current_FILE}" NAME_WE)
-         set(_moc "${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp")
-         set_source_files_properties(${_moc} PROPERTIES GENERATED TRUE)
-         set(${_SRCS} ${${_SRCS}} ${_moc})
-         add_custom_command(OUTPUT ${_moc} COMMAND ${QT_MOC_EXECUTABLE} ${_moc_INCS} ${CMAKE_CURRENT_SOURCE_DIR}/${_current_FILE} -o ${_moc}
-            DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${_current_FILE})
-      endforeach (_current_FILE)
-   endif(NOT _headers_to_moc STREQUAL "NOTFOUND")
-endmacro(KDE4_APPEND_MOC_FILES)
-
 macro(KDE4_HANDLE_AUTOMOC _target_NAME _SRCS)
-   set(_mark_file "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}.automoc")
    set(_moc_files)
    set(_moc_headers)
+
+   # first list all explicitly set headers
+   KDE4_GET_CUSTOM_TARGET_PROPERTY(_headers_to_moc ${_target_NAME} AUTOMOC_HEADERS)
+   if(NOT _headers_to_moc STREQUAL "NOTFOUND")
+      foreach(_header_to_moc ${_headers_to_moc})
+         get_filename_component(_abs_header ${_header_to_moc} ABSOLUTE)
+         set(_moc_files ${_moc_files} ${_abs_header})
+         set(_moc_headers ${_moc_headers} ${_abs_header})
+      endforeach(_header_to_moc)
+   endif(NOT _headers_to_moc STREQUAL "NOTFOUND")
+
+   # now add all the sources for the automoc
    foreach (_current_FILE ${${_SRCS}})
       get_filename_component(_abs_current_FILE "${_current_FILE}" ABSOLUTE)
       get_source_file_property(_skip "${_abs_current_FILE}" SKIP_AUTOMOC)
@@ -215,28 +210,25 @@
          if(EXISTS "${_header}")
             set(_moc_headers ${_moc_headers} ${_header})
          endif(EXISTS "${_header}")
-         #macro_additional_clean_files("${CMAKE_CURRENT_BINARY_DIR}/${_basename}.moc")
-         #macro_additional_clean_files("${CMAKE_CURRENT_BINARY_DIR}/moc_${_basename}.cpp")
-         set(_moc_files "${_moc_files}\;${_abs_current_FILE}")
+         set(_moc_files ${_moc_files} ${_abs_current_FILE})
       endif(NOT _generated AND NOT _skip)
    endforeach (_current_FILE)
 
-   set(_moc_incs)
-   GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)
-   FOREACH(_current ${_inc_DIRS})
-      SET(_moc_incs "${_moc_incs}\;-I\;${_current}")
-   ENDFOREACH(_current)
-   add_custom_command(OUTPUT ${_mark_file}
-      COMMAND ${CMAKE_COMMAND}
-      -DKDE4_CURRENT_BINARY_DIR=${CMAKE_CURRENT_BINARY_DIR}
-      -DQT_MOC_EXECUTABLE=${QT_MOC_EXECUTABLE}
-      -DQT_MOC_INCS="${_moc_incs}"
-      -DMOC_FILES="${_moc_files}"
-      -DMARK_FILE="${_mark_file}"
-      -P ${KDE4_MODULE_DIR}/kde4automoc.cmake
-      DEPENDS ${${_SRCS}} ${_moc_headers}
+   set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_automoc.cpp")
+   GET_DIRECTORY_PROPERTY(_moc_incs INCLUDE_DIRECTORIES)
+   FILE(WRITE ${_automoc_source}.files "MOC_INCLUDES:\n${_moc_incs}\nSOURCES:\n${_moc_files}")
+   add_custom_command(OUTPUT ${_automoc_source}
+      COMMAND ${KDE4_AUTOMOC_EXECUTABLE}
+      ${_automoc_source}
+      ${CMAKE_CURRENT_SOURCE_DIR}
+      ${CMAKE_CURRENT_BINARY_DIR}
+      ${QT_MOC_EXECUTABLE}
+      DEPENDS ${${_SRCS}} ${_moc_headers} ${_automoc_source}.files ${_KDE4_AUTOMOC_EXECUTABLE_DEP}
       )
-   set(${_SRCS} ${${_SRCS}} ${_mark_file})
+   # the OBJECT_DEPENDS is only necessary when a new moc file has to be generated that is included in a source file
+   # problem: the whole target is recompiled when the automoc.cpp file is touched
+   # set_source_files_properties(${${_SRCS}} PROPERTIES OBJECT_DEPENDS ${_automoc_source})
+   set(${_SRCS} ${_automoc_source} ${${_SRCS}})
 endmacro(KDE4_HANDLE_AUTOMOC)
 
 macro(KDE4_CREATE_PO_FILES)
@@ -655,7 +647,6 @@
    endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
 
    set(_SRCS ${_first_SRC} ${ARGN})
-   kde4_append_moc_files(${_target_NAME} _SRCS)
    kde4_handle_automoc(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp _separate_files ${_SRCS})
@@ -743,7 +734,6 @@
 #   else (WIN32)
       # under UNIX, create a shared library and a small executable, which links to this library
 
-   kde4_append_moc_files(${_target_NAME} _SRCS)
    kde4_handle_automoc(kdeinit_${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/kdeinit_${_target_NAME}_final_cpp.cpp _separate_files ${_SRCS})
@@ -804,7 +794,6 @@
    set( EXECUTABLE_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR} )
 
    set(_SRCS ${ARGN})
-   kde4_append_moc_files(${_target_NAME} _SRCS)
    kde4_handle_automoc(${_target_NAME} _SRCS)
    add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS})
 
@@ -847,7 +836,6 @@
       set(_type "RUN_UNINSTALLED")
    endif (_uninst)
 
-   kde4_append_moc_files(${_target_NAME} _SRCS)
    kde4_handle_automoc(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp _separate_files ${_SRCS})
@@ -885,7 +873,6 @@
    endif (${_lib_TYPE} STREQUAL "MODULE")
 
    set(_SRCS ${_first_SRC} ${ARGN})
-   kde4_append_moc_files(${_target_NAME} _SRCS)
    kde4_handle_automoc(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp _separate_files ${_SRCS})

Attachment: pgp6EjhKVnq4x.pgp
Description: PGP signature

_______________________________________________
Kde-buildsystem mailing list
Kde-buildsystem@kde.org
https://mail.kde.org/mailman/listinfo/kde-buildsystem

Reply via email to