diff options
| author | Matthias Kretz <kretz@kde.org> | 2007-07-09 15:27:27 +0000 | 
|---|---|---|
| committer | Matthias Kretz <kretz@kde.org> | 2007-07-09 15:27:27 +0000 | 
| commit | c0980c740022e025fb6c089092f03992ac8a90ba (patch) | |
| tree | e3cf833e605e44f9dd8324185f63c975e05d8dbf | |
| parent | 789a43a8e400806a43b043860ca65d2ff538f8ac (diff) | |
| download | extra-cmake-modules-c0980c740022e025fb6c089092f03992ac8a90ba.tar.gz extra-cmake-modules-c0980c740022e025fb6c089092f03992ac8a90ba.tar.bz2 | |
As posted to kde-buildsystem:
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).
svn path=/trunk/KDE/kdelibs/; revision=685719
| -rw-r--r-- | CMakeLists.txt | 1 | ||||
| -rw-r--r-- | automoc/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | automoc/kde4automoc.cpp | 270 | ||||
| -rw-r--r-- | modules/FindKDE4Internal.cmake | 14 | ||||
| -rw-r--r-- | modules/KDE4Macros.cmake | 67 | 
5 files changed, 317 insertions, 40 deletions
| diff --git a/CMakeLists.txt b/CMakeLists.txt index 38a9971a..0a44a796 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(automoc)  add_subdirectory(modules) diff --git a/automoc/CMakeLists.txt b/automoc/CMakeLists.txt new file mode 100644 index 00000000..553aa1af --- /dev/null +++ b/automoc/CMakeLists.txt @@ -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}) diff --git a/automoc/kde4automoc.cpp b/automoc/kde4automoc.cpp new file mode 100644 index 00000000..8023a3a9 --- /dev/null +++ b/automoc/kde4automoc.cpp @@ -0,0 +1,270 @@ +/*  This file is part of the KDE project +    Copyright (C) 2007 Matthias Kretz <kretz@kde.org> + +    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); +    } +} diff --git a/modules/FindKDE4Internal.cmake b/modules/FindKDE4Internal.cmake index ac7c6e43..24803eab 100644 --- a/modules/FindKDE4Internal.cmake +++ b/modules/FindKDE4Internal.cmake @@ -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 @@ if (_kdeBootStrapping)        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 @@ if (_kdeBootStrapping)     # 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 @@ else (_kdeBootStrapping)    # ... 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 @@ else (_kdeBootStrapping)     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 @@ macro (KDE4_PRINT_RESULTS)     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) diff --git a/modules/KDE4Macros.cmake b/modules/KDE4Macros.cmake index 3da9c5a1..d9891727 100644 --- a/modules/KDE4Macros.cmake +++ b/modules/KDE4Macros.cmake @@ -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 @@ macro (KDE4_MOC_HEADERS _target_NAME)     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 @@ macro(KDE4_HANDLE_AUTOMOC _target_NAME _SRCS)           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 @@ macro (KDE4_ADD_PLUGIN _target_NAME _with_PREFIX)     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 @@ macro (KDE4_ADD_KDEINIT_EXECUTABLE _target_NAME )  #   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 @@ macro (KDE4_ADD_TEST_EXECUTABLE _target_NAME)     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 @@ macro (KDE4_ADD_EXECUTABLE _target_NAME)        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 @@ macro (KDE4_ADD_LIBRARY _target_NAME _lib_TYPE)     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}) | 
