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

List:       kde-buildsystem
Subject:    Re: automoc4
From:       Matthias Kretz <kretz () kde ! org>
Date:       2008-05-06 15:00:47
Message-ID: 200805061701.02539.kretz () kde ! org
[Download RAW message or body]

[Attachment #2 (multipart/signed)]

[Attachment #4 (multipart/mixed)]


On Friday 02 May 2008, Matthias Kretz wrote:
> On Wednesday 30 April 2008, Alexander Neundorf wrote:
> > Von: Matthias Kretz <kretz@kde.org>
> > > On Tuesday 29 April 2008, Alexander Neundorf wrote:
> > > > Is there an easy way to enforce rerunning automoc ? Would it be
> > > > possible to
> > > > add a command line switch which does that ? Like e.g. deleting all
> > > > generated moc files or something like that ?
> > >
> > > Alternatives:
> > > 1. add a new target (I'd like to avoid that because it would add a lot
> > > of I/O on a cmake run)
> > > 2. make it easy to run automoc4 manually
> >
> > Yes, something like "automoc4 --clean" or something like this which does
> > that for the current dir and maybe all subdirs would be nice to have.
>
> How about the following:
> - automoc, when done, writes an empty file <target>_automoc.notclean
> - SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES
> <target>_automoc.notclean)
> - automoc will recreate all moc files if the <target>_automoc.notclean file
> is not present (else it will work as it does now)
>
> =>
> after a make clean, running make which executes automoc will recreate all
> moc files.
>
> This would again need automoc to be called unconditionally (which I still
> believe would be good to do - and the touch can be done by automoc itself,
> which would be portable).

Patch attached (automoc.patch): I'm all for committing this.

I'm using this with the other patch against kdelibs/cmake - which makes the 
rest of KDE use the automoc from kdesupport.

On the first run all moc files will be regenerated, since the .notclean files 
don't exist yet. From then on it works as requested.

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

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

Index: modules/KDE4Macros.cmake
===================================================================
--- modules/KDE4Macros.cmake	(revision 804493)
+++ modules/KDE4Macros.cmake	(working copy)
@@ -29,6 +29,8 @@
 # Redistribution and use is allowed according to the terms of the BSD license.
 # For details see the accompanying COPYING-CMAKE-SCRIPTS file.
 
+find_package(Automoc4 REQUIRED)
+
 macro (KDE4_ADD_KCFG_FILES _sources )
    if( ${ARGV1} STREQUAL "GENERATE_MOC" )
       set(_kcfg_generatemoc TRUE)
@@ -161,78 +163,11 @@
 
 
 macro (KDE4_MOC_HEADERS _target_NAME)
-   set (_headers_to_moc)
-   foreach (_current_FILE ${ARGN})
-      get_filename_component(_suffix "${_current_FILE}" EXT)
-      if (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" \
                STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
-         list(APPEND _headers_to_moc ${_current_FILE})
-      else (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" \
                STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
-         message(STATUS "KDE4_MOC_HEADERS: ignoring non-header file \
                ${_current_FILE}")
-      endif (".h" STREQUAL "${_suffix}" OR ".hpp" STREQUAL "${_suffix}" OR ".hxx" \
                STREQUAL "${_suffix}" OR ".H" STREQUAL "${_suffix}")
-   endforeach (_current_FILE)
-   # need to create moc_<filename>.cpp file using kde4automoc.cmake
-   # and add it to the target
-   if(_headers_to_moc)
-      kde4_set_custom_target_property(${_target_NAME} AUTOMOC_HEADERS \
                "${_headers_to_moc}")
-   endif(_headers_to_moc)
+   automoc4_moc_headers(${_target_NAME})
 endmacro (KDE4_MOC_HEADERS)
 
 macro(KDE4_HANDLE_AUTOMOC _target_NAME _SRCS)
-   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)
-         list(APPEND _moc_files ${_abs_header})
-         list(APPEND _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)
-      get_source_file_property(_generated "${_abs_current_FILE}" GENERATED)
-
-      if(NOT _generated AND NOT _skip)
-         get_filename_component(_suffix "${_current_FILE}" EXT)
-         # skip every source file that's not C++
-         if(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL \
                ".cxx" OR _suffix STREQUAL ".C")
-            get_filename_component(_basename "${_current_FILE}" NAME_WE)
-            get_filename_component(_abs_path "${_abs_current_FILE}" PATH)
-            set(_header "${_abs_path}/${_basename}.h")
-            if(EXISTS "${_header}")
-               list(APPEND _moc_headers ${_header})
-            endif(EXISTS "${_header}")
-            set(_pheader "${_abs_path}/${_basename}_p.h")
-            if(EXISTS "${_pheader}")
-               list(APPEND _moc_headers ${_pheader})
-            endif(EXISTS "${_pheader}")
-            list(APPEND _moc_files ${_abs_current_FILE})
-         endif(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL \
                ".cxx" OR _suffix STREQUAL ".C")
-      endif(NOT _generated AND NOT _skip)
-   endforeach (_current_FILE)
-
-   if(_moc_files)
-      set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_automoc.cpp")
-      get_directory_property(_moc_incs INCLUDE_DIRECTORIES)
-      configure_file(${KDE4_MODULE_DIR}/kde4automoc.files.in \
                ${_automoc_source}.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}
-         )
-      # 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}})
-   endif(_moc_files)
+   automoc4(${_target_NAME} ${_SRCS})
 endmacro(KDE4_HANDLE_AUTOMOC)
 
 macro(KDE4_INSTALL_TS_FILES _lang _sdir)
@@ -621,7 +556,7 @@
    endif (${_with_PREFIX} STREQUAL "WITH_PREFIX")
 
    set(_SRCS ${_first_SRC} ${ARGN})
-   kde4_handle_automoc(${_target_NAME} _SRCS)
+   automoc4(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp \
                _separate_files ${_SRCS})
       add_library(${_target_NAME} MODULE  \
${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp ${_separate_files}) @@ \
-740,7 +675,7 @@  
       target_link_libraries(${_target_NAME} ${QT_QTMAIN_LIBRARY} \
kdeinit_${_target_NAME})  else(WIN32)
-      kde4_handle_automoc(kdeinit_${_target_NAME} _SRCS)
+      automoc4(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}) @@ -863,7 +798,7 @@
       set(_add_executable_param ${_add_executable_param} EXCLUDE_FROM_ALL)
    endif (_test AND NOT KDE4_BUILD_TESTS)
 
-   kde4_handle_automoc(${_target_NAME} _SRCS)
+   automoc4(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp \
                _separate_files ${_SRCS})
       add_executable(${_target_NAME} ${_add_executable_param} \
${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp ${_separate_files}) @@ \
-904,7 +839,7 @@  endif (${_lib_TYPE} STREQUAL "MODULE")
 
    set(_SRCS ${_first_SRC} ${ARGN})
-   kde4_handle_automoc(${_target_NAME} _SRCS)
+   automoc4(${_target_NAME} _SRCS)
    if (KDE4_ENABLE_FINAL)
       kde4_create_final_files(${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp \
                _separate_files ${_SRCS})
       add_library(${_target_NAME} ${_add_lib_param}  \
                ${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}_final_cpp.cpp \
                ${_separate_files})
Index: modules/FindKDE4Internal.cmake
===================================================================
--- modules/FindKDE4Internal.cmake	(revision 804493)
+++ modules/FindKDE4Internal.cmake	(working copy)
@@ -16,7 +16,6 @@
 # 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
 #
@@ -275,13 +274,11 @@
       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)
@@ -431,9 +428,6 @@
    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 )  
@@ -1057,11 +1051,6 @@
       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: CMakeLists.txt
===================================================================
--- CMakeLists.txt	(revision 804493)
+++ CMakeLists.txt	(working copy)
@@ -1,4 +1,3 @@
 
-add_subdirectory(automoc)
 add_subdirectory(modules)
 


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

Index: Automoc4Config.cmake
===================================================================
--- Automoc4Config.cmake	(revision 804491)
+++ Automoc4Config.cmake	(working copy)
@@ -4,12 +4,10 @@
 # are we in the source tree or already installed ?
 if(EXISTS ${_AUTOMOC4_CURRENT_DIR}/kde4automoc.cpp)
    get_target_property(AUTOMOC4_EXECUTABLE automoc4 LOCATION)
-   set(_AUTOMOC4_EXECUTABLE_DEP automoc4)
 else(EXISTS ${_AUTOMOC4_CURRENT_DIR}/kde4automoc.cpp)
    get_filename_component(_AUTOMOC4_BIN_DIR  "${_AUTOMOC4_CURRENT_DIR}" PATH)
    get_filename_component(_AUTOMOC4_BIN_DIR  "${_AUTOMOC4_BIN_DIR}" PATH)
    find_program(AUTOMOC4_EXECUTABLE automoc4 PATHS  "${_AUTOMOC4_BIN_DIR}/bin" \
                NO_DEFAULT_PATH)
-   set(_AUTOMOC4_EXECUTABLE_DEP)
 endif(EXISTS ${_AUTOMOC4_CURRENT_DIR}/kde4automoc.cpp)
 
 macro (AUTOMOC4_MOC_HEADERS _target_NAME)
@@ -78,12 +76,12 @@
          ${CMAKE_CURRENT_BINARY_DIR}
          ${QT_MOC_EXECUTABLE}
 #         ${CMAKE_COMMAND}
-         DEPENDS ${${_SRCS}} ${_moc_headers} ${_automoc_source}.files \
${_AUTOMOC4_EXECUTABLE_DEP} +         DEPENDS ${_automoc_source}.files
+         COMMENT ""
+         VERBATIM
          )
-      # 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}})
+      set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES \
${_automoc_source}.notclean)  endif(_moc_files)
 endmacro(AUTOMOC4)
 
Index: kde4automoc.cpp
===================================================================
--- kde4automoc.cpp	(revision 804491)
+++ kde4automoc.cpp	(working copy)
@@ -43,7 +43,7 @@
         bool run();
 
     private:
-        void generateMoc(const QString &sourceFile, const QString &mocFileName);
+        bool generateMoc(const QString &sourceFile, const QString &mocFileName);
         void waitForProcesses();
         void printUsage(const QString &);
         void printVersion();
@@ -72,6 +72,8 @@
         };
         QQueue<Process> processes;
         bool failed;
+        bool automocCppChanged;
+        bool generateAll;
 };
 
 void AutoMoc::printUsage(const QString &path)
@@ -94,7 +96,8 @@
 }
 
 AutoMoc::AutoMoc()
-    : verbose(!qgetenv("VERBOSE").isEmpty()), cerr(stderr), cout(stdout), \
failed(false) +    : verbose(!qgetenv("VERBOSE").isEmpty()), cerr(stderr), \
cout(stdout), failed(false), +    automocCppChanged(false)
 {
     const QByteArray colorEnv = qgetenv("COLOR");
     cmakeEchoColorArgs << QLatin1String("-E") << QLatin1String("cmake_echo_color") 
@@ -133,6 +136,9 @@
     }
     mocExe = args[4];
 
+    QFile notclean(args[1] + ".notclean");
+    generateAll = !notclean.exists();
+
     QFile dotFiles(args[1] + ".files");
     dotFiles.open(QIODevice::ReadOnly | QIODevice::Text);
     QByteArray line = dotFiles.readLine();
@@ -278,7 +284,9 @@
         end = notIncludedMocs.constEnd();
         it = notIncludedMocs.constBegin();
         for (; it != end; ++it) {
-            generateMoc(it.key(), it.value());
+            if (generateMoc(it.key(), it.value())) {
+                automocCppChanged = true;
+            }
             outStream << "#include \"" << it.value() << "\"\n";
         }
     }
@@ -294,11 +302,33 @@
     }
     outStream.flush();
 
-    // source file that includes all remaining moc files
+    if (generateAll) {
+        notclean.open(QIODevice::WriteOnly);
+        notclean.close();
+    }
+
+    if (!automocCppChanged) {
+        // compare contents of the _automoc.cpp file
+        outfile.open(QIODevice::ReadOnly | QIODevice::Text);
+        const QByteArray oldContents = outfile.readAll();
+        outfile.close();
+        if (oldContents == automocSource) {
+            // nothing changed: don't touch the _automoc.cpp file
+            return true;
+        }
+    }
+    // either the contents of the _automoc.cpp file or one of the mocs included by \
it have changed +
+    // source file that includes all remaining moc files (_automoc.cpp file)
     outfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
     outfile.write(automocSource);
     outfile.close();
 
+    // update the timestamp on the _automoc.cpp.files file
+    dotFiles.close();
+    dotFiles.open(QIODevice::WriteOnly | QIODevice::Append);
+    dotFiles.close();
+
     return true;
 }
 
@@ -323,11 +353,11 @@
     }
 }
 
-void AutoMoc::generateMoc(const QString &sourceFile, const QString &mocFileName)
+bool AutoMoc::generateMoc(const QString &sourceFile, const QString &mocFileName)
 {
     //qDebug() << Q_FUNC_INFO << sourceFile << mocFileName;
     const QString mocFilePath = builddir + mocFileName;
-    if (QFileInfo(mocFilePath).lastModified() < \
QFileInfo(sourceFile).lastModified()) { +    if (generateAll || \
QFileInfo(mocFilePath).lastModified() < QFileInfo(sourceFile).lastModified()) {  if \
                (verbose) {
             echoColor("Generating " + mocFilePath + " from " + sourceFile);
         } else {
@@ -354,13 +384,15 @@
         args << QLatin1String("-o") << mocFilePath << sourceFile;
         //qDebug() << "executing: " << mocExe << args;
         mocProc->start(mocExe, args, QIODevice::NotOpen);
-        if (mocProc->waitForStarted())
+        if (mocProc->waitForStarted()) {
             processes.enqueue(Process(mocProc, mocFilePath));
-        else {
+            return true;
+        } else {
             cerr << "automoc4: process for " << mocFilePath << "failed to start: " 
                  << mocProc->errorString() << endl;
             failed = true;
             delete mocProc;
         }
     }
+    return false;
 }


["signature.asc" (application/pgp-signature)]

_______________________________________________
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