diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in index 2c7c72469..44f2da2cf 100644 --- a/Modules/AutomocInfo.cmake.in +++ b/Modules/AutomocInfo.cmake.in @@ -13,3 +13,4 @@ set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) set(AM_Qt5Core_VERSION_MAJOR "@Qt5Core_VERSION_MAJOR@" ) set(AM_TARGET_NAME "@_moc_target_name@") +set(AM_STRICT_MODE "@_moc_strict_mode@") diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index c8c83b9c1..a0632a2b3 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -507,6 +507,20 @@ void cmDocumentVariables::DefineVariables(cmake* cm) false, "Variables That Change Behavior"); + cm->DefineProperty + ("CMAKE_AUTOMOC_STRICT_MODE", cmProperty::VARIABLE, + "Switch between strict and relaxed automoc mode.", + "When TRUE, automoc behaves exactly as described in the documentation " + "of the AUTOMOC target property. " + "When set to FALSE, it accepts more input and tries to find the correct " + "input file for moc even if it differs from the documented behaviour. " + "In this mode it e.g. also checks whether a header file is intended to " + "be processed by moc when a \"foo.moc\" file has been included.\n" + "When using Qt4, CMAKE_AUTOMOC_STRICT_MODE is initialized to FALSE. " + "It also has to be set to FALSE for KDE4 compatibility.", + false, + "Variables That Change Behavior"); + cm->DefineProperty ("CMAKE_FIND_LIBRARY_PREFIXES", cmProperty::VARIABLE, "Prefixes to prepend when looking for libraries.", diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index d07f84b78..65c7952d7 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -17,11 +17,70 @@ #include "cmSourceFile.h" #include "cmSystemTools.h" -# include +#include + +#include #include "cmQtAutomoc.h" +static bool containsQ_OBJECT(const std::string& text) +{ + // this simple check is much much faster than the regexp + if (strstr(text.c_str(), "Q_OBJECT") == NULL) + { + return false; + } + + cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + return qObjectRegExp.find(text); +} + + +static std::string findMatchingHeader(const std::string& absPath, + const std::string& mocSubDir, + const std::string& basename, + const std::list& headerExtensions) +{ + std::string header; + for(std::list::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + std::string sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + header = sourceFilePath; + break; + } + if (!mocSubDir.empty()) + { + sourceFilePath = mocSubDir + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + header = sourceFilePath; + break; + } + } + } + + return header; +} + + +static std::string extractSubDir(const std::string& absPath, + const std::string& currentMoc) +{ + std::string subDir; + if (currentMoc.find_first_of('/') != std::string::npos) + { + subDir = absPath + + cmsys::SystemTools::GetFilenamePath(currentMoc) + '/'; + } + return subDir; +} + + cmQtAutomoc::cmQtAutomoc() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,ColorOutput(true) @@ -60,6 +119,12 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) return; } + bool strictMode = (qtMajorVersion == "5"); + if (makefile->IsDefinitionSet("CMAKE_AUTOMOC_STRICT_MODE")) + { + strictMode = makefile->IsOn("CMAKE_AUTOMOC_STRICT_MODE"); + } + // create a custom target for running automoc at buildtime: std::string automocTargetName = targetName; automocTargetName += "_automoc"; @@ -148,6 +213,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) makefile->AddDefinition("_moc_options", _moc_options.c_str()); makefile->AddDefinition("_moc_files", _moc_files.c_str()); makefile->AddDefinition("_moc_headers", _moc_headers.c_str()); + makefile->AddDefinition("_moc_strict_mode", strictMode ? "TRUE" : "FALSE"); const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT"); std::string inputFile = cmakeRoot; @@ -247,6 +313,8 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + this->StrictMode = makefile->IsOn("AM_STRICT_MODE"); + return true; } @@ -415,6 +483,23 @@ bool cmQtAutomoc::RunAutomoc() std::vector sourceFiles; cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); + std::list headerExtensions; + headerExtensions.push_back(".h"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); +#if defined(_WIN32) + // not case sensitive, don't add ".H" +#elif defined(__APPLE__) + // detect case-sensitive filesystem + long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); + if (caseSensitive == 1) + { + headerExtensions.push_back(".H"); + } +#else + headerExtensions.push_back(".H"); +#endif + for (std::vector::const_iterator it = sourceFiles.begin(); it != sourceFiles.end(); ++it) @@ -424,7 +509,15 @@ bool cmQtAutomoc::RunAutomoc() { std::cout << "AUTOMOC: Checking " << absFilename << std::endl; } - this->ParseCppFile(absFilename, includedMocs, headerFiles); + if (this->StrictMode == false) + { + this->ParseCppFile(absFilename, headerExtensions, includedMocs); + } + else + { + this->StrictParseCppFile(absFilename, headerExtensions, includedMocs); + } + this->SearchHeadersForCppFile(absFilename, headerExtensions, headerFiles); } std::vector headerFilesVec; @@ -505,40 +598,37 @@ bool cmQtAutomoc::RunAutomoc() void cmQtAutomoc::ParseCppFile(const std::string& absFilename, - std::map& includedMocs, - std::set& absHeaders) + const std::list& headerExtensions, + std::map& includedMocs) { cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); - std::list headerExtensions; - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); -#if defined(_WIN32) - // not case sensitive, don't add ".H" -#elif defined(__APPLE__) - // detect case-sensitive filesystem - long caseSensitive = pathconf(this->Srcdir.c_str(), _PC_CASE_SENSITIVE); - if (caseSensitive == 1) - { - headerExtensions.push_back(".H"); - } -#else - headerExtensions.push_back(".H"); -#endif const std::string contentsString = this->ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "AUTOMOC: empty source file: " << absFilename << std::endl; + std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + << std::endl; return; } const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + const std::string scannedFileBasename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename); + const bool cppContainsQ_OBJECT = containsQ_OBJECT(contentsString); + bool dotMocIncluded = false; + bool mocUnderscoreIncluded = false; + std::string ownMocUnderscoreFile; + std::string ownDotMocFile; + std::string ownMocHeaderFile; std::string::size_type matchOffset = 0; - if (mocIncludeRegExp.find(contentsString.c_str())) + // first a simply string check for "moc" is *much* faster than the regexp, + // and if the string search already fails, we don't have to try the + // expensive regexp + if ((strstr(contentsString.c_str(), "moc") != NULL) + && (mocIncludeRegExp.find(contentsString))) { // for every moc include in the file do @@ -561,78 +651,248 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, // 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.substr(4); + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); - bool headerFound = false; - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + if (!headerToMoc.empty()) { - const std::string &sourceFilePath = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + includedMocs[headerToMoc] = currentMoc; + if (basename == scannedFileBasename) { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - break; + mocUnderscoreIncluded = true; + ownMocUnderscoreFile = currentMoc; + ownMocHeaderFile = headerToMoc; } } - if (!headerFound) + else { - // the moc file is in a subdir => look for the header in the - // same subdir - if (currentMoc.find_first_of('/') != std::string::npos) + std::cerr << "AUTOMOC: error: " << absFilename << " The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->Join(headerExtensions, ',') << "}\" "; + if (mocSubDir.empty()) { - const std::string &filepath = absPath - + cmsys::SystemTools::GetFilenamePath(currentMoc) - + '/' + basename; - - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) - { - const std::string &sourceFilePath = filepath + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) - { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - break; - } - } - if (!headerFound) - { - std::cerr << "AUTOMOC: The file \"" << absFilename - << "\" includes the moc file \"" << currentMoc - << "\", but neither \"" << absPath << basename - << '{' << this->Join(headerExtensions, ',') - << "}\" nor \"" << filepath << '{' - << this->Join(headerExtensions, ',') << '}' - << "\" exist." << std::endl; - ::exit(EXIT_FAILURE); - } + std::cerr << "in " << absPath << "\n" << std::endl; } else { - std::cerr << "AUTOMOC: The file \"" << absFilename - << "\" includes the moc file \"" << currentMoc - << "\", but \"" << absPath << basename << '{' - << this->Join(headerExtensions, ',') << '}' - << "\" does not exist." << std::endl; - ::exit(EXIT_FAILURE); + std::cerr << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; } + + ::exit(EXIT_FAILURE); } } else { + std::string fileToMoc = absFilename; + if ((basename != scannedFileBasename) || (cppContainsQ_OBJECT==false)) + { + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); + if (!headerToMoc.empty()) + { + // this is for KDE4 compatibility: + fileToMoc = headerToMoc; + if ((cppContainsQ_OBJECT==false) &&(basename==scannedFileBasename)) + { + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", but does not contain a Q_OBJECT macro. " + "Running moc on " + << "\"" << headerToMoc << "\" ! Better include \"moc_" + << basename << ".cpp\" for a robust build.\n" + << std::endl; + } + else + { + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\" instead of \"moc_" << basename << ".cpp\". " + "Running moc on " + << "\"" << headerToMoc << "\" ! Better include \"moc_" + << basename << ".cpp\" for a robust build.\n" + << std::endl; + } + } + else + { + std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. CMake also could not find a matching " + "header.\n" << std::endl; + ::exit(EXIT_FAILURE); + } + } + else + { + dotMocIncluded = true; + ownDotMocFile = currentMoc; + } + includedMocs[fileToMoc] = currentMoc; + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } + + // In this case, check whether the scanned file itself contains a Q_OBJECT. + // If this is the case, the moc_foo.cpp should probably be generated from + // foo.cpp instead of foo.h, because otherwise it won't build. + // But warn, since this is not how it is supposed to be used. + if ((dotMocIncluded == false) && (cppContainsQ_OBJECT == true)) + { + if (mocUnderscoreIncluded == true) + { + // this is for KDE4 compatibility: + std::cerr << "AUTOMOC: warning: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\", but instead " + "includes " + << "\"" << ownMocUnderscoreFile << "\". Running moc on " + << "\"" << absFilename << "\" ! Better include \"" + << scannedFileBasename << ".moc\" for a robust build.\n" + << std::endl; + includedMocs[absFilename] = ownMocUnderscoreFile; + includedMocs.erase(ownMocHeaderFile); + } + else + { + // otherwise always error out since it will not compile: + std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + ::exit(EXIT_FAILURE); + } + } + +} + + +void cmQtAutomoc::StrictParseCppFile(const std::string& absFilename, + const std::list& headerExtensions, + std::map& includedMocs) +{ + cmsys::RegularExpression mocIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); + + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) + { + std::cerr << "AUTOMOC: warning: " << absFilename << ": file is empty\n" + << std::endl; + return; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + const std::string scannedFileBasename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename); + + bool dotMocIncluded = false; + + std::string::size_type matchOffset = 0; + // first a simply string check for "moc" is *much* faster than the regexp, + // and if the string search already fails, we don't have to try the + // expensive regexp + if ((strstr(contentsString.c_str(), "moc") != NULL) + && (mocIncludeRegExp.find(contentsString))) + { + // for every moc include in the file + do + { + const std::string currentMoc = mocIncludeRegExp.match(1); + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool mocUnderscoreStyle = this->StartsWith(basename, "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. + if (mocUnderscoreStyle) + { + // 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.substr(4); + std::string mocSubDir = extractSubDir(absPath, currentMoc); + std::string headerToMoc = findMatchingHeader( + absPath, mocSubDir, basename, headerExtensions); + + if (!headerToMoc.empty()) + { + includedMocs[headerToMoc] = currentMoc; + } + else + { + std::cerr << "AUTOMOC: error: " << absFilename << " The file " + << "includes the moc file \"" << currentMoc << "\", " + << "but could not find header \"" << basename + << '{' << this->Join(headerExtensions, ',') << "}\" "; + if (mocSubDir.empty()) + { + std::cerr << "in " << absPath << "\n" << std::endl; + } + else + { + std::cerr << "neither in " << absPath + << " nor in " << mocSubDir << "\n" << std::endl; + } + + ::exit(EXIT_FAILURE); + } + } + else + { + if (basename != scannedFileBasename) + { + std::cerr <<"AUTOMOC: error: " << absFilename << ": The file " + "includes the moc file \"" << currentMoc << + "\", which seems to be the moc file from a different " + "source file. This is not supported. " + "Include \"" << scannedFileBasename << ".moc\" to run " + "moc on this source file.\n" << std::endl; + ::exit(EXIT_FAILURE); + } + dotMocIncluded = true; includedMocs[absFilename] = currentMoc; } matchOffset += mocIncludeRegExp.end(); } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); } + // In this case, check whether the scanned file itself contains a Q_OBJECT. + // If this is the case, the moc_foo.cpp should probably be generated from + // foo.cpp instead of foo.h, because otherwise it won't build. + // But warn, since this is not how it is supposed to be used. + if ((dotMocIncluded == false) && (containsQ_OBJECT(contentsString))) + { + // otherwise always error out since it will not compile: + std::cerr << "AUTOMOC: error: " << absFilename << ": The file " + << "contains a Q_OBJECT macro, but does not include " + << "\"" << scannedFileBasename << ".moc\" !\n" + << std::endl; + ::exit(EXIT_FAILURE); + } + +} + + +void cmQtAutomoc::SearchHeadersForCppFile(const std::string& absFilename, + const std::list& headerExtensions, + std::set& absHeaders) +{ // search for header files and private header files we may need to moc: const std::string basename = cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + for(std::list::const_iterator ext = headerExtensions.begin(); ext != headerExtensions.end(); ++ext) @@ -663,7 +923,6 @@ void cmQtAutomoc::ParseHeaders(const std::set& absHeaders, const std::map& includedMocs, std::map& notIncludedMocs) { - cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); for(std::set::const_iterator hIt=absHeaders.begin(); hIt!=absHeaders.end(); ++hIt) @@ -682,7 +941,7 @@ void cmQtAutomoc::ParseHeaders(const std::set& absHeaders, const std::string currentMoc = "moc_" + basename + ".cpp"; const std::string contents = this->ReadAll(headerName); - if (qObjectRegExp.find(contents)) + if (containsQ_OBJECT(contents)) { //std::cout << "header contains Q_OBJECT macro"; notIncludedMocs[headerName] = currentMoc; @@ -759,7 +1018,7 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); if (!result || retVal) { - std::cerr << "AUTOMOC: process for " << mocFilePath << " failed:\n" + std::cerr << "AUTOMOC: error: process for " << mocFilePath <<" failed:\n" << output << std::endl; this->RunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath.c_str()); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index f6355de3d..a31f36a33 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -39,8 +39,15 @@ private: bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); void ParseCppFile(const std::string& absFilename, - std::map& includedMocs, - std::set& absHeaders); + const std::list& headerExtensions, + std::map& includedMocs); + void StrictParseCppFile(const std::string& absFilename, + const std::list& headerExtensions, + std::map& includedMocs); + void SearchHeadersForCppFile(const std::string& absFilename, + const std::list& headerExtensions, + std::set& absHeaders); + void ParseHeaders(const std::set& absHeaders, const std::map& includedMocs, std::map& notIncludedMocs); @@ -78,6 +85,7 @@ private: bool ColorOutput; bool RunMocFailed; bool GenerateAll; + bool StrictMode; }; diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index d3715b897..fc3c1c9e1 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -161,8 +161,10 @@ void cmTarget::DefineProperties(cmake *cm) "This property is initialized by the value of the variable " "CMAKE_AUTOMOC if it is set when a target is created.\n" "Additional command line options for moc can be set via the " - "AUTOMOC_MOC_OPTIONS property." - ); + "AUTOMOC_MOC_OPTIONS property.\n" + "By setting the CMAKE_AUTOMOC_STRICT_MODE variable to FALSE the rules " + "for searching the files which will be processed by moc can be relaxed. " + "See the documentation for this variable for more details."); cm->DefineProperty ("AUTOMOC_MOC_OPTIONS", cmProperty::TARGET, diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt index 01f6bead5..ebfb4f5fb 100644 --- a/Tests/QtAutomoc/CMakeLists.txt +++ b/Tests/QtAutomoc/CMakeLists.txt @@ -13,7 +13,7 @@ add_definitions(-DFOO) # create an executable and a library target, both requiring automoc: add_library(codeeditorLib STATIC codeeditor.cpp) -add_executable(foo main.cpp calwidget.cpp foo.cpp) +add_executable(foo main.cpp calwidget.cpp foo.cpp blub.cpp bar.cpp abc.cpp xyz.cpp yaf.cpp private_slot.cpp) set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE) diff --git a/Tests/QtAutomoc/abc.cpp b/Tests/QtAutomoc/abc.cpp new file mode 100644 index 000000000..4bbc76905 --- /dev/null +++ b/Tests/QtAutomoc/abc.cpp @@ -0,0 +1,49 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + + +#include "abc.h" +#include "abc_p.h" + +#include + +class PrintAbc : public QObject +{ + Q_OBJECT + public: + PrintAbc():QObject() {} + public slots: + void print() const { printf("abc\n"); } +}; + +Abc::Abc() +:QObject() +{ +} + + +void Abc::doAbc() +{ + PrintAbc pa; + pa.print(); + AbcP abcP; + abcP.doAbcP(); +} + +// check that including the moc file for the cpp file and the header works: +#include "abc.moc" +#include "moc_abc.cpp" +#include "moc_abc_p.cpp" + +// check that including a moc file from another header works: +#include "moc_xyz.cpp" diff --git a/Tests/QtAutomoc/abc.h b/Tests/QtAutomoc/abc.h new file mode 100644 index 000000000..d1924b0da --- /dev/null +++ b/Tests/QtAutomoc/abc.h @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef ABC_H +#define ABC_H + +#include + +class Abc : public QObject +{ + Q_OBJECT + public: + Abc(); + public slots: + void doAbc(); +}; + +#endif diff --git a/Tests/QtAutomoc/abc_p.h b/Tests/QtAutomoc/abc_p.h new file mode 100644 index 000000000..952fff315 --- /dev/null +++ b/Tests/QtAutomoc/abc_p.h @@ -0,0 +1,30 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef ABC_P_H +#define ABC_P_H + +#include + +#include + +class AbcP : public QObject +{ + Q_OBJECT + public: + AbcP() {} + public slots: + void doAbcP() { printf("I am private abc !\n"); } +}; + +#endif diff --git a/Tests/QtAutomoc/bar.cpp b/Tests/QtAutomoc/bar.cpp new file mode 100644 index 000000000..8be48159d --- /dev/null +++ b/Tests/QtAutomoc/bar.cpp @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "sub/bar.h" + +#include + +Bar::Bar() +:QObject() +{ +} + +void Bar::doBar() +{ + printf("Hello bar !\n"); +} + +#include "sub/moc_bar.cpp" diff --git a/Tests/QtAutomoc/blub.cpp b/Tests/QtAutomoc/blub.cpp new file mode 100644 index 000000000..bd53972ac --- /dev/null +++ b/Tests/QtAutomoc/blub.cpp @@ -0,0 +1,40 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "blub.h" + +#include + +class BlubBlub : public QObject +{ + Q_OBJECT + public: + BlubBlub():QObject() {} + public slots: + int getValue() const { return 13; } +}; + +Blub::Blub() +{ +} + + +void Blub::blubber() +{ + BlubBlub bb; + printf("Blub blub %d ! \n", bb.getValue()); +} + +// test the case that the wrong moc-file is included, it should +// actually be "blub.moc" +#include "moc_blub.cpp" diff --git a/Tests/QtAutomoc/blub.h b/Tests/QtAutomoc/blub.h new file mode 100644 index 000000000..1967bc1ea --- /dev/null +++ b/Tests/QtAutomoc/blub.h @@ -0,0 +1,26 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef BLUB_H +#define BLUB_H + +#include + +class Blub +{ + public: + Blub(); + void blubber(); +}; + +#endif diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp index b7cfb410e..738f67720 100644 --- a/Tests/QtAutomoc/main.cpp +++ b/Tests/QtAutomoc/main.cpp @@ -43,6 +43,11 @@ #include "codeeditor.h" #include "calwidget.h" #include "foo.h" +#include "blub.h" +#include "sub/bar.h" +#include "abc.h" +#include "xyz.h" +#include "yaf.h" int main(int argv, char **args) { @@ -58,5 +63,20 @@ int main(int argv, char **args) Foo foo; foo.doFoo(); + Blub b; + b.blubber(); + + Bar bar; + bar.doBar(); + + Abc abc; + abc.doAbc(); + + Xyz xyz; + xyz.doXyz(); + + Yaf yaf; + yaf.doYaf(); + return app.exec(); } diff --git a/Tests/QtAutomoc/private_slot.cpp b/Tests/QtAutomoc/private_slot.cpp new file mode 100644 index 000000000..1387a70cf --- /dev/null +++ b/Tests/QtAutomoc/private_slot.cpp @@ -0,0 +1,21 @@ + +#include "private_slot.h" + +class PrivateSlotPrivate +{ +public: + + void privateSlot() + { + + } +}; + +PrivateSlot::PrivateSlot(QObject *parent) + : QObject(parent), + d(new PrivateSlotPrivate) +{ + +} + +#include "private_slot.moc" diff --git a/Tests/QtAutomoc/private_slot.h b/Tests/QtAutomoc/private_slot.h new file mode 100644 index 000000000..28e54482a --- /dev/null +++ b/Tests/QtAutomoc/private_slot.h @@ -0,0 +1,20 @@ + +#ifndef PRIVATE_SLOT_H +#define PRIVATE_SLOT_H + +#include + +class PrivateSlotPrivate; + +class PrivateSlot : public QObject +{ + Q_OBJECT +public: + PrivateSlot(QObject *parent = 0); + +private: + PrivateSlotPrivate * const d; + Q_PRIVATE_SLOT(d, void privateSlot()) +}; + +#endif diff --git a/Tests/QtAutomoc/sub/bar.h b/Tests/QtAutomoc/sub/bar.h new file mode 100644 index 000000000..db56b8ed5 --- /dev/null +++ b/Tests/QtAutomoc/sub/bar.h @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef BAR_H +#define BAR_H + +#include + +class Bar : public QObject +{ + Q_OBJECT + public: + Bar(); + public slots: + void doBar(); +}; + +#endif diff --git a/Tests/QtAutomoc/xyz.cpp b/Tests/QtAutomoc/xyz.cpp new file mode 100644 index 000000000..a3562a337 --- /dev/null +++ b/Tests/QtAutomoc/xyz.cpp @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + + +#include "xyz.h" + +#include + +Xyz::Xyz() +:QObject() +{ +} + + +void Xyz::doXyz() +{ + printf("This is xyz !\n"); +} diff --git a/Tests/QtAutomoc/xyz.h b/Tests/QtAutomoc/xyz.h new file mode 100644 index 000000000..8175d3792 --- /dev/null +++ b/Tests/QtAutomoc/xyz.h @@ -0,0 +1,28 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef XYZ_H +#define XYZ_H + +#include + +class Xyz : public QObject +{ + Q_OBJECT + public: + Xyz(); + public slots: + void doXyz(); +}; + +#endif diff --git a/Tests/QtAutomoc/yaf.cpp b/Tests/QtAutomoc/yaf.cpp new file mode 100644 index 000000000..d278ab422 --- /dev/null +++ b/Tests/QtAutomoc/yaf.cpp @@ -0,0 +1,32 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + + +#include "yaf.h" +#include "yaf_p.h" + +#include + +Yaf::Yaf() +{ +} + + +void Yaf::doYaf() +{ + YafP yafP; + yafP.doYafP(); +} + +// check that including a moc file from a private header the wrong way works: +#include "yaf_p.moc" diff --git a/Tests/QtAutomoc/yaf.h b/Tests/QtAutomoc/yaf.h new file mode 100644 index 000000000..8689f8308 --- /dev/null +++ b/Tests/QtAutomoc/yaf.h @@ -0,0 +1,25 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef YAF_H +#define YAF_H + +class Yaf +{ + public: + Yaf(); + public: + void doYaf(); +}; + +#endif diff --git a/Tests/QtAutomoc/yaf_p.h b/Tests/QtAutomoc/yaf_p.h new file mode 100644 index 000000000..f0368ade1 --- /dev/null +++ b/Tests/QtAutomoc/yaf_p.h @@ -0,0 +1,30 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2004-2011 Kitware, Inc. + Copyright 2011 Alexander Neundorf (neundorf@kde.org) + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#ifndef YAF_P_H +#define YAF_P_H + +#include + +#include + +class YafP : public QObject +{ + Q_OBJECT + public: + YafP() {} + public slots: + void doYafP() { printf("I am yet another file !\n"); } +}; + +#endif