aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--automoc/CMakeLists.txt5
-rw-r--r--automoc/kde4automoc.cpp345
3 files changed, 1 insertions, 355 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5a4b45da..a89a38bb 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,8 +1,4 @@
-
-#if(NOT AUTOMOC4_EXECUTABLE)
-# # this is just a fallback in case automoc4 from kdesupport isn't found, Alex
-# add_subdirectory(automoc)
-#endif(NOT AUTOMOC4_EXECUTABLE)
+# automoc comes now from kdesupport, Alex
add_subdirectory(modules)
diff --git a/automoc/CMakeLists.txt b/automoc/CMakeLists.txt
deleted file mode 100644
index 553aa1af..00000000
--- a/automoc/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-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
deleted file mode 100644
index 68ccdbdb..00000000
--- a/automoc/kde4automoc.cpp
+++ /dev/null
@@ -1,345 +0,0 @@
-/* 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 as
- published by the Free Software Foundation; either version 2 of
- the License, or (at your option) any later version.
-
- 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();
- bool run();
-
- private:
- void generateMoc(const QString &sourceFile, const QString &mocFileName);
- void waitForProcesses();
- void usage(const QString &);
- void echoColor(const QString &msg)
- {
- QProcess *cmakeEcho = new QProcess;
- cmakeEcho->setProcessChannelMode(QProcess::ForwardedChannels);
- QStringList args(cmakeEchoColorArgs);
- args << msg;
- cmakeEcho->start(QLatin1String("cmake"), args, QIODevice::NotOpen);
- processes.enqueue(Process(cmakeEcho, QString()));
- }
-
- QString builddir;
- QString mocExe;
- QStringList mocIncludes;
- QStringList cmakeEchoColorArgs;
- const bool verbose;
- QTextStream cerr;
- QTextStream cout;
- struct Process
- {
- Process(QProcess *a, const QString &b) : qproc(a), mocFilePath(b) {}
- QProcess *qproc;
- QString mocFilePath;
- };
- QQueue<Process> processes;
- bool failed;
-};
-
-void AutoMoc::usage(const QString &path)
-{
- cout << "usage: " << path << " <outfile> <srcdir> <builddir> <moc executable>" << endl;
- ::exit(EXIT_FAILURE);
-}
-
-int main(int argc, char **argv)
-{
- QCoreApplication app(argc, argv);
- if (!AutoMoc().run()) {
- return EXIT_FAILURE;
- }
- return 0;
-}
-
-AutoMoc::AutoMoc()
- : verbose(!qgetenv("VERBOSE").isEmpty()), cerr(stderr), cout(stdout), failed(false)
-{
- const QByteArray colorEnv = qgetenv("COLOR");
- cmakeEchoColorArgs << QLatin1String("-E") << QLatin1String("cmake_echo_color")
- << QLatin1String("--switch=") + colorEnv << QLatin1String("--blue")
- << QLatin1String("--bold");
-}
-
-bool 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 += '/';
- }
- builddir = args[3];
- if (!builddir.endsWith('/')) {
- builddir += '/';
- }
- 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) {
- if (!path.isEmpty()) {
- 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(QLatin1String("[\n]\\s*#\\s*include\\s+[\"<](moc_[^ \">]+\\.cpp|[^ \">]+\\.moc)[\">]"));
- QRegExp qObjectRegExp(QLatin1String("[\n]\\s*Q_OBJECT\\b"));
- QStringList headerExtensions;
- headerExtensions << ".h" << ".hpp" << ".hxx" << ".H";
- foreach (const QString &absFilename, sourceFiles) {
- //qDebug() << absFilename;
- const QFileInfo sourceFileInfo(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 = sourceFileInfo.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 = sourceFileInfo.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);
- }
- }
- const QString privateHeaderName = absPath + basename + "_p.h";
- if (QFile::exists(privateHeaderName) && !includedMocs.contains(privateHeaderName) &&
- !notIncludedMocs.contains(privateHeaderName)) {
- const QString currentMoc = "moc_" + basename + "_p.cpp";
- QFile header(privateHeaderName);
- header.open(QIODevice::ReadOnly);
- const QByteArray contents = header.readAll();
- if (qObjectRegExp.indexIn(QString::fromUtf8(contents)) >= 0) {
- //qDebug() << "header contains Q_OBJECT macro";
- notIncludedMocs.insert(privateHeaderName, 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);
- }
- bool headerFound = false;
- foreach (const QString &ext, headerExtensions) {
- QString sourceFilePath = absPath + basename + ext;
- if (QFile::exists(sourceFilePath)) {
- headerFound = true;
- includedMocs.insert(sourceFilePath, currentMoc);
- notIncludedMocs.remove(sourceFilePath);
- break;
- }
- }
- if (!headerFound) {
- cerr << "kde4automoc: The file \"" << absFilename <<
- "\" includes the moc file \"" << currentMoc << "\", but \"" <<
- absPath + basename + "{" + headerExtensions.join(",") + "}" <<
- "\" do not exist." << endl;
- ::exit(EXIT_FAILURE);
- }
- } 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_" + sourceFileInfo.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());
- }
-
- QByteArray automocSource;
- QTextStream outStream(&automocSource, QIODevice::WriteOnly);
- outStream << "/* This file is autogenerated, do not edit */\n";
-
- if (notIncludedMocs.isEmpty()) {
- outStream << "enum some_compilers { need_more_than_nothing };\n";
- } else {
- // 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";
- }
- }
-
- // let all remaining moc processes finish
- waitForProcesses();
-
- if (failed) {
- // if any moc process failed we don't want to touch the _automoc.cpp file so that
- // kde4automoc is rerun until the issue is fixed
- cerr << "returning failed.."<< endl;
- return false;
- }
- outStream.flush();
-
- // source file that includes all remaining moc files
- outfile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate);
- outfile.write(automocSource);
- outfile.close();
-
- return true;
-}
-
-void AutoMoc::waitForProcesses()
-{
- while (!processes.isEmpty()) {
- Process proc = processes.dequeue();
-
- bool result = proc.qproc->waitForFinished(-1);
- //ignore errors from the cmake echo process
- if (!proc.mocFilePath.isEmpty()) {
- if (!result || proc.qproc->exitCode()) {
- cerr << "kde4automoc: process for " << proc.mocFilePath
- << " failed: " << proc.qproc->errorString() << endl;
- cerr << "pid to wait for: " << proc.qproc->pid() << endl;
- cerr << "processes in queue: " << processes.size() << endl;
- failed = true;
- QFile::remove(proc.mocFilePath);
- }
- }
- delete proc.qproc;
- }
-}
-
-void 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 (verbose) {
- echoColor("Generating " + mocFilePath + " from " + sourceFile);
- } else {
- echoColor("Generating " + mocFileName);
- }
-
- // we don't want too many child processes
-#ifdef Q_OS_FREEBSD
- static const int max_processes = 0;
-#else
- static const int max_processes = 10;
-#endif
-
- if (processes.size() > max_processes) {
- waitForProcesses();
- }
-
- QProcess *mocProc = new QProcess;
- mocProc->setProcessChannelMode(QProcess::ForwardedChannels);
- QStringList args(mocIncludes);
-#ifdef Q_OS_WIN
- args << "-DWIN32";
-#endif
- args << QLatin1String("-o") << mocFilePath << sourceFile;
- //qDebug() << "executing: " << mocExe << args;
- mocProc->start(mocExe, args, QIODevice::NotOpen);
- if (mocProc->waitForStarted())
- processes.enqueue(Process(mocProc, mocFilePath));
- else {
- cerr << "kde4automoc: process for " << mocFilePath << "failed to start: "
- << mocProc->errorString() << endl;
- failed = true;
- delete mocProc;
- }
- }
-}