From a65011baf109fd0afe759cf3d9e7b6ab7013a805 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 7 Aug 2011 12:02:46 +0200 Subject: Start work on automoc: add empty cmQtAutomoc class Alex --- Source/CMakeLists.txt | 2 ++ Source/cmQtAutomoc.cxx | 10 ++++++++++ Source/cmQtAutomoc.h | 11 +++++++++++ Source/cmake.cxx | 7 +++++++ 4 files changed, 30 insertions(+) create mode 100644 Source/cmQtAutomoc.cxx create mode 100644 Source/cmQtAutomoc.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 1c942ba..96b3ea0 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -228,6 +228,8 @@ SET(SRCS cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h + cmQtAutomoc.cxx + cmQtAutomoc.h cmScriptGenerator.h cmScriptGenerator.cxx cmSourceFile.cxx diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx new file mode 100644 index 0000000..efbfc38 --- /dev/null +++ b/Source/cmQtAutomoc.cxx @@ -0,0 +1,10 @@ +#include "cmQtAutomoc.h" + +cmQtAutomoc::cmQtAutomoc() +{ +} + + +bool cmQtAutomoc::Run(const char* targetDirectory) +{ +} diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h new file mode 100644 index 0000000..657b208 --- /dev/null +++ b/Source/cmQtAutomoc.h @@ -0,0 +1,11 @@ +#ifndef cmQtAutomoc_h +#define cmQtAutomoc_h + +class cmQtAutomoc +{ +public: + cmQtAutomoc(); + bool Run(const char* targetDirectory); +}; + +#endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 51cc9d4..47520df 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -20,6 +20,7 @@ #include "cmCommand.h" #include "cmFileTimeComparison.h" #include "cmGeneratedFileStream.h" +#include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmTest.h" @@ -1574,6 +1575,12 @@ int cmake::ExecuteCMakeCommand(std::vector& args) } #endif + else if (args[1] == "cmake_automoc") + { + cmQtAutomoc automoc; + automoc.Run("target directory"); + } + // Tar files else if (args[1] == "tar" && args.size() > 3) { -- cgit v0.12 From d1c0a5fce6c9adccd1abf6b41ba448976ef895d0 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 7 Aug 2011 17:16:00 +0200 Subject: Start implementing skeleton for automoc in cmake Alex --- Source/cmQtAutomoc.cxx | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ Source/cmQtAutomoc.h | 18 ++++++++++++ Source/cmake.cxx | 3 +- 3 files changed, 100 insertions(+), 1 deletion(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index efbfc38..26d359d 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -1,3 +1,8 @@ +#include "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmMakefile.h" +#include "cmSystemTools.h" + #include "cmQtAutomoc.h" cmQtAutomoc::cmQtAutomoc() @@ -7,4 +12,79 @@ cmQtAutomoc::cmQtAutomoc() bool cmQtAutomoc::Run(const char* targetDirectory) { + cmake cm; + cmGlobalGenerator* gg = this->CreateGlobalGenerator(&cm, targetDirectory); + cmMakefile* makefile = gg->GetCurrentLocalGenerator()->GetMakefile(); + + this->ReadAutomocInfoFile(makefile, targetDirectory); + this->ReadOldMocDefinitionsFile(makefile, targetDirectory); + + delete gg; + gg = NULL; + makefile = NULL; + + if (this->QtMajorVersion == "4") + { + this->RunAutomocQt4(); + } + + this->WriteOldMocDefinitionsFile(targetDirectory); +} + + +cmGlobalGenerator* cmQtAutomoc::CreateGlobalGenerator(cmake* cm, + const char* targetDirectory) +{ + cmGlobalGenerator* gg = new cmGlobalGenerator(); + gg->SetCMakeInstance(cm); + + cmLocalGenerator* lg = gg->CreateLocalGenerator(); + lg->GetMakefile()->SetHomeOutputDirectory(targetDirectory); + lg->GetMakefile()->SetStartOutputDirectory(targetDirectory); + lg->GetMakefile()->SetHomeDirectory(targetDirectory); + lg->GetMakefile()->SetStartDirectory(targetDirectory); + gg->SetCurrentLocalGenerator(lg); + + return gg; +} + + +bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, + const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocInfo.cmake"; + + if (!makefile->ReadListFile(0, filename.c_str())) + { + cmSystemTools::Error("Error processing file:", filename.c_str()); + } + return true; +} + + +bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, + const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocOldMocDefinitions.cmake"; + + if (!makefile->ReadListFile(0, filename.c_str())) + { + cmSystemTools::Error("Error processing file:", filename.c_str()); + } + return true; +} + + +bool cmQtAutomoc::RunAutomocQt4() +{ + return true; +} + + +void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) +{ } diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 657b208..d6f809c 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -1,11 +1,29 @@ #ifndef cmQtAutomoc_h #define cmQtAutomoc_h +class cmGlobalGenerator; +class cmMakefile; + class cmQtAutomoc { public: cmQtAutomoc(); bool Run(const char* targetDirectory); + +private: + cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, + const char* targetDirectory); + + bool ReadAutomocInfoFile(cmMakefile* makefile, + const char* targetDirectory); + bool ReadOldMocDefinitionsFile(cmMakefile* makefile, + const char* targetDirectory); + void WriteOldMocDefinitionsFile(const char* targetDirectory); + + bool RunAutomocQt4(); + + std::string QtMajorVersion; + }; #endif diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 47520df..06229e0 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1578,7 +1578,8 @@ int cmake::ExecuteCMakeCommand(std::vector& args) else if (args[1] == "cmake_automoc") { cmQtAutomoc automoc; - automoc.Run("target directory"); + automoc.Run(args[2].c_str()); + return 0; } // Tar files -- cgit v0.12 From d65689a3bd059b2f70e11644e43df4251c71987e Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Mon, 8 Aug 2011 15:20:13 +0200 Subject: Add actual automoc code from automoc It already works :-) Needs more refactoring, e.g. using the cmake facilities to turn a string into a vector etc. Also still missing is the part which creates the custom target. Alex --- Source/cmQtAutomoc.cxx | 566 ++++++++++++++++++++++++++++++++++++++++++++++++- Source/cmQtAutomoc.h | 29 +++ 2 files changed, 589 insertions(+), 6 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 26d359d..7fac2f2 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -5,7 +5,13 @@ #include "cmQtAutomoc.h" + +#define TRACE_LINE() printf(" %s %d\n", __PRETTY_FUNCTION__, __LINE__) + cmQtAutomoc::cmQtAutomoc() +:Verbose(true) +,RunMocFailed(false) +,GenerateAll(false) { } @@ -19,9 +25,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) this->ReadAutomocInfoFile(makefile, targetDirectory); this->ReadOldMocDefinitionsFile(makefile, targetDirectory); - delete gg; - gg = NULL; - makefile = NULL; + this->Init(); if (this->QtMajorVersion == "4") { @@ -29,6 +33,11 @@ bool cmQtAutomoc::Run(const char* targetDirectory) } this->WriteOldMocDefinitionsFile(targetDirectory); + + delete gg; + gg = NULL; + makefile = NULL; + } @@ -59,7 +68,22 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, if (!makefile->ReadListFile(0, filename.c_str())) { cmSystemTools::Error("Error processing file:", filename.c_str()); + return false; } + + this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); + this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); + this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); + this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR"); + this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); + this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); + this->MocCompileDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS"); + this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); + this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); + this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); + this->ProjectSourceDir = makefile->GetSafeDefinition("AM_CMAKE_SOURCE_DIR"); + this->TargetName = makefile->GetSafeDefinition("AM_TARGET_NAME"); + return true; } @@ -71,20 +95,550 @@ bool cmQtAutomoc::ReadOldMocDefinitionsFile(cmMakefile* makefile, cmSystemTools::ConvertToUnixSlashes(filename); filename += "/AutomocOldMocDefinitions.cmake"; - if (!makefile->ReadListFile(0, filename.c_str())) + if (makefile->ReadListFile(0, filename.c_str())) { - cmSystemTools::Error("Error processing file:", filename.c_str()); + this->OldMocDefinitionsStr = + makefile->GetSafeDefinition("AM_OLD_MOC_DEFINITIONS"); } return true; } +void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) +{ + std::string filename(cmSystemTools::CollapseFullPath(targetDirectory)); + cmSystemTools::ConvertToUnixSlashes(filename); + filename += "/AutomocOldMocDefinitions.cmake"; + + std::fstream outfile; + outfile.open(filename.c_str(), + std::ios_base::out | std::ios_base::trunc); + outfile << "set(AM_OLD_MOC_DEFINITIONS \"" + << this->Join(this->MocDefinitions, ' ') << "\")\n"; + + outfile.close(); +} + + +void cmQtAutomoc::Init() +{ + this->OutMocCppFilename = this->Builddir; + this->OutMocCppFilename += this->TargetName; + this->OutMocCppFilename += ".cpp"; + + std::vector cdefList; + cmSystemTools::ExpandListArgument(this->MocCompileDefinitionsStr, cdefList); + if (!cdefList.empty()) + { + for(std::vector::const_iterator it = cdefList.begin(); + it != cdefList.end(); + ++it) + { + this->MocDefinitions.push_back("-D" + (*it)); + } + } + else + { + std::string tmpMocDefs = this->MocDefinitionsStr; + cmSystemTools::ReplaceString(tmpMocDefs, " ", ";"); + + std::vector defList; + cmSystemTools::ExpandListArgument(tmpMocDefs, defList); + + for(std::vector::const_iterator it = defList.begin(); + it != defList.end(); + ++it) + { + if (this->StartsWith(*it, "-D")) + { + this->MocDefinitions.push_back(*it); + } + } + } + + std::vector incPaths; + cmSystemTools::ExpandListArgument(this->MocIncludesStr, incPaths); + + std::set frameworkPaths; + for(std::vector::const_iterator it = incPaths.begin(); + it != incPaths.end(); + ++it) + { + const std::string &path = *it; + this->MocIncludes.push_back("-I" + path); + if (this->EndsWith(path, ".framework/Headers")) + { + // Go up twice to get to the framework root + std::vector pathComponents; + cmsys::SystemTools::SplitPath(path.c_str(), pathComponents); + std::string frameworkPath =cmsys::SystemTools::JoinPath( + pathComponents.begin(), pathComponents.end() - 2); + frameworkPaths.insert(frameworkPath); + } + } + + for (std::set::const_iterator it = frameworkPaths.begin(); + it != frameworkPaths.end(); ++it) + { + this->MocIncludes.push_back("-F"); + this->MocIncludes.push_back(*it); + } + + + if (this->IncludeProjectDirsBefore) + { + const std::string &binDir = "-I" + this->ProjectBinaryDir; + + const std::string srcDir = "-I" + this->ProjectSourceDir; + + std::list sortedMocIncludes; + std::list::iterator it = this->MocIncludes.begin(); + while (it != this->MocIncludes.end()) + { + if (this->StartsWith(*it, binDir)) + { + sortedMocIncludes.push_back(*it); + it = this->MocIncludes.erase(it); + } + else + { + ++it; + } + } + it = this->MocIncludes.begin(); + while (it != this->MocIncludes.end()) + { + if (this->StartsWith(*it, srcDir)) + { + sortedMocIncludes.push_back(*it); + it = this->MocIncludes.erase(it); + } + else + { + ++it; + } + } + sortedMocIncludes.insert(sortedMocIncludes.end(), + this->MocIncludes.begin(), this->MocIncludes.end()); + this->MocIncludes = sortedMocIncludes; + } + +} + + bool cmQtAutomoc::RunAutomocQt4() { + if (!cmsys::SystemTools::FileExists(this->OutMocCppFilename.c_str()) + || (this->OldMocDefinitionsStr != this->Join(this->MocDefinitions, ' '))) + { + this->GenerateAll = true; + } + + // 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_.cpp file is created and included in the _automoc.cpp file. + std::map includedMocs; // key = moc source filepath, value = moc output filepath + std::map notIncludedMocs; // key = moc source filepath, value = moc output filename + + cmsys::RegularExpression mocIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); + cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + std::list headerExtensions; +#if defined(_WIN32) + // not case sensitive + headerExtensions.push_back(".h"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); +#elif defined(__APPLE__) + headerExtensions.push_back(".h"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); + + // 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"); + headerExtensions.push_back(".hpp"); + headerExtensions.push_back(".hxx"); + headerExtensions.push_back(".H"); +#endif + + std::vector sourceFiles; + cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); + + for (std::vector::const_iterator it = sourceFiles.begin(); + it != sourceFiles.end(); + ++it) + { + const std::string &absFilename = *it; + if (this->Verbose) + { + printf("Checking -%s-\n", absFilename.c_str()); + } + std::string extension = absFilename.substr(absFilename.find_last_of('.')); + + if (extension == ".cpp" || extension == ".cc" || extension == ".mm" + || extension == ".cxx" || extension == ".C") + { + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) + { + std::cerr << "automoc4: empty source file: " << absFilename << std::endl; + continue; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + + int matchOffset = 0; + if (!mocIncludeRegExp.find(contentsString.c_str())) + { + // no moc #include, look whether we need to create a moc from the .h nevertheless + //std::cout << "no moc #include in the .cpp file"; + const std::string basename = + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string headername = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(headername.c_str()) + && includedMocs.find(headername) == includedMocs.end() + && notIncludedMocs.find(headername) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + ".cpp"; + const std::string contents = this->ReadAll(headername); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[headername] = currentMoc; + } + break; + } + } + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) + && includedMocs.find(privateHeaderName) == includedMocs.end() + && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + "_p.cpp"; + const std::string contents = this->ReadAll(privateHeaderName); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[privateHeaderName] = currentMoc; + } + break; + } + } + } + else + { + // for every moc include in the file + do + { + const std::string currentMoc = mocIncludeRegExp.match(1); + //std::cout << "found moc include: " << currentMoc << std::endl; + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool moc_style = 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, else from the header. + // + // TODO: currently any .moc file name will be used if the source contains + // Q_OBJECT + if (moc_style || !qObjectRegExp.find(contentsString)) + { + if (moc_style) + { + // 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); + } + + bool headerFound = false; + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string &sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + // the moc file is in a subdir => look for the header in the same subdir + if (currentMoc.find_first_of('/') != std::string::npos) + { + 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; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + std::cerr << "automoc4: 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); + } + } + else + { + std::cerr << "automoc4: The file \"" << absFilename << + "\" includes the moc file \"" << currentMoc << "\", but \"" << + absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' << + "\" does not exist." << std::endl; + ::exit(EXIT_FAILURE); + } + } + } + else + { + includedMocs[absFilename] = currentMoc; + notIncludedMocs.erase(absFilename); + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } + } + else if (extension == ".h" || extension == ".hpp" + || extension == ".hxx" || extension == ".H") + { + if (includedMocs.find(absFilename) == includedMocs.end() + && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) + { + // 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 std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp"; + notIncludedMocs[absFilename] = currentMoc; + } + } + else + { + if (this->Verbose) + { + std::cout << "automoc4: ignoring file '" << absFilename << "' with unknown suffix" << std::endl; + } + } + } + + // run moc on all the moc's that are #included in source files + for(std::map::const_iterator it = includedMocs.begin(); + it != includedMocs.end(); + ++it) + { + this->GenerateMoc(it->first, it->second); + } + + std::stringstream outStream(std::stringstream::out); + outStream << "/* This file is autogenerated, do not edit*/\n"; + + bool automocCppChanged = false; + if (notIncludedMocs.empty()) + { + outStream << "enum some_compilers { need_more_than_nothing };\n"; + } + else + { + // run moc on the remaining headers and include them in the _automoc.cpp file + for(std::map::const_iterator it = notIncludedMocs.begin(); + it != notIncludedMocs.end(); + ++it) + { + bool mocSuccess = this->GenerateMoc(it->first, it->second); + if (mocSuccess) + { + automocCppChanged = true; + } + outStream << "#include \"" << it->second << "\"\n"; + } + } + + if (this->RunMocFailed) + { + // if any moc process failed we don't want to touch the _automoc.cpp file so that + // automoc4 is rerun until the issue is fixed + std::cerr << "returning failed.."<< std::endl; + return false; + } + outStream.flush(); + std::string automocSource = outStream.str(); + if (!automocCppChanged) + { + // compare contents of the _automoc.cpp file + const std::string oldContents = this->ReadAll(this->OutMocCppFilename); + 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) + std::fstream outfile; + outfile.open(this->OutMocCppFilename.c_str(), + std::ios_base::out | std::ios_base::trunc); + outfile << automocSource; + outfile.close(); + return true; } -void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) +bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, + const std::string& mocFileName) +{ + //std::cout << "AutoMoc::generateMoc" << sourceFile << mocFileName << std::endl; + const std::string mocFilePath = this->Builddir + mocFileName; + int sourceNewerThanMoc = 0; + bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(), + mocFilePath.c_str(), + &sourceNewerThanMoc); + if (this->GenerateAll || !success || sourceNewerThanMoc >= 0) + { + // make sure the directory for the resulting moc file exists + std::string mocDir = mocFilePath.substr(0, mocFilePath.rfind('/')); + if (!cmsys::SystemTools::FileExists(mocDir.c_str(), false)) + { + cmsys::SystemTools::MakeDirectory(mocDir.c_str()); + } + +/* if (this->Verbose) + { + echoColor("Generating " + mocFilePath + " from " + sourceFile); + } + else + { + echoColor("Generating " + mocFileName); + }*/ + + std::vector command; + command.push_back(this->MocExecutable); + for (std::list::const_iterator it = this->MocIncludes.begin(); + it != this->MocIncludes.end(); + ++it) + { + command.push_back(*it); + } + for(std::list::const_iterator it=this->MocDefinitions.begin(); + it != this->MocDefinitions.end(); + ++it) + { + command.push_back(*it); + } +#ifdef _WIN32 + command.push_back("-DWIN32"); +#endif + command.push_back("-o"); + command.push_back(mocFilePath); + command.push_back(sourceFile); + + if (this->Verbose) + { + for(int i=0; iRunMocFailed = true; + cmSystemTools::RemoveFile(mocFilePath.c_str()); + } + return true; + } + return false; +} + + +std::string cmQtAutomoc::Join(const std::list& lst,char separator) +{ + if (lst.empty()) + { + return ""; + } + + std::string result; + for (std::list::const_iterator it = lst.begin(); + it != lst.end(); + ++it) + { + result += (*it) + separator; + } + result.erase(result.end() - 1); + return result; +} + + +bool cmQtAutomoc::StartsWith(const std::string& str, const std::string& with) +{ + return (str.substr(0, with.length()) == with); +} + + +bool cmQtAutomoc::EndsWith(const std::string& str, const std::string& with) +{ + if (with.length() > (str.length())) + { + return false; + } + return (str.substr(str.length() - with.length(), with.length()) == with); +} + + +std::string cmQtAutomoc::ReadAll(const std::string& filename) { + std::ifstream file(filename.c_str()); + std::stringstream stream; + stream << file.rdbuf(); + file.close(); + return stream.str(); } diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index d6f809c..0dafd4a 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -21,8 +21,37 @@ private: void WriteOldMocDefinitionsFile(const char* targetDirectory); bool RunAutomocQt4(); + bool GenerateMoc(const std::string& sourceFile, + const std::string& mocFileName); + void Init(); + + std::string Join(const std::list& lst, char separator); + bool EndsWith(const std::string& str, const std::string& with); + bool StartsWith(const std::string& str, const std::string& with); + std::string ReadAll(const std::string& filename); std::string QtMajorVersion; + std::string Sources; + bool IncludeProjectDirsBefore; + std::string Srcdir; + std::string Builddir; + std::string MocExecutable; + std::string MocCompileDefinitionsStr; + std::string MocDefinitionsStr; + std::string MocIncludesStr; + std::string ProjectBinaryDir; + std::string ProjectSourceDir; + std::string TargetName; + + std::string OldMocDefinitionsStr; + + std::string OutMocCppFilename; + std::list MocIncludes; + std::list MocDefinitions; + + bool Verbose; + bool RunMocFailed; + bool GenerateAll; }; -- cgit v0.12 From de91feb367c127294a56b492799c4bf042954fd8 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 9 Aug 2011 09:11:53 +0200 Subject: Remove the need to check for .h/.cxx during buildtime Instead it now relies on cmake time to put that information correctly into AutomocInfo.cmake Alex --- Source/cmQtAutomoc.cxx | 286 ++++++++++++++++++++++++------------------------- Source/cmQtAutomoc.h | 1 + 2 files changed, 143 insertions(+), 144 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 7fac2f2..5494b2a 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -73,6 +73,7 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); + this->Headers = makefile->GetSafeDefinition("AM_HEADERS"); this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR"); this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); @@ -282,184 +283,181 @@ bool cmQtAutomoc::RunAutomocQt4() { printf("Checking -%s-\n", absFilename.c_str()); } - std::string extension = absFilename.substr(absFilename.find_last_of('.')); - if (extension == ".cpp" || extension == ".cc" || extension == ".mm" - || extension == ".cxx" || extension == ".C") + const std::string contentsString = this->ReadAll(absFilename); + if (contentsString.empty()) { - const std::string contentsString = this->ReadAll(absFilename); - if (contentsString.empty()) - { - std::cerr << "automoc4: empty source file: " << absFilename << std::endl; - continue; - } - const std::string absPath = cmsys::SystemTools::GetFilenamePath( - cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + std::cerr << "automoc4: empty source file: " << absFilename << std::endl; + continue; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - int matchOffset = 0; - if (!mocIncludeRegExp.find(contentsString.c_str())) + int matchOffset = 0; + if (!mocIncludeRegExp.find(contentsString.c_str())) + { + // no moc #include, look whether we need to create a moc from the .h nevertheless + //std::cout << "no moc #include in the .cpp file"; + const std::string basename = + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) { - // no moc #include, look whether we need to create a moc from the .h nevertheless - //std::cout << "no moc #include in the .cpp file"; - const std::string basename = - cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + const std::string headername = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(headername.c_str()) + && includedMocs.find(headername) == includedMocs.end() + && notIncludedMocs.find(headername) == notIncludedMocs.end()) { - const std::string headername = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(headername.c_str()) - && includedMocs.find(headername) == includedMocs.end() - && notIncludedMocs.find(headername) == notIncludedMocs.end()) + const std::string currentMoc = "moc_" + basename + ".cpp"; + const std::string contents = this->ReadAll(headername); + if (qObjectRegExp.find(contents)) { - const std::string currentMoc = "moc_" + basename + ".cpp"; - const std::string contents = this->ReadAll(headername); - if (qObjectRegExp.find(contents)) - { - //std::cout << "header contains Q_OBJECT macro"; - notIncludedMocs[headername] = currentMoc; - } - break; + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[headername] = currentMoc; } + break; } - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + } + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) + && includedMocs.find(privateHeaderName) == includedMocs.end() + && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) { - const std::string privateHeaderName = absPath+basename+"_p"+(*ext); - if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) - && includedMocs.find(privateHeaderName) == includedMocs.end() - && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) + const std::string currentMoc = "moc_" + basename + "_p.cpp"; + const std::string contents = this->ReadAll(privateHeaderName); + if (qObjectRegExp.find(contents)) { - const std::string currentMoc = "moc_" + basename + "_p.cpp"; - const std::string contents = this->ReadAll(privateHeaderName); - if (qObjectRegExp.find(contents)) - { - //std::cout << "header contains Q_OBJECT macro"; - notIncludedMocs[privateHeaderName] = currentMoc; - } - break; + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[privateHeaderName] = currentMoc; } + break; } } - else + } + else + { + // for every moc include in the file + do { - // for every moc include in the file - do + const std::string currentMoc = mocIncludeRegExp.match(1); + //std::cout << "found moc include: " << currentMoc << std::endl; + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool moc_style = 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, else from the header. + // + // TODO: currently any .moc file name will be used if the source contains + // Q_OBJECT + if (moc_style || !qObjectRegExp.find(contentsString)) { - const std::string currentMoc = mocIncludeRegExp.match(1); - //std::cout << "found moc include: " << currentMoc << std::endl; - - std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(currentMoc); - const bool moc_style = 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, else from the header. - // - // TODO: currently any .moc file name will be used if the source contains - // Q_OBJECT - if (moc_style || !qObjectRegExp.find(contentsString)) + if (moc_style) { - if (moc_style) - { - // 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); - } + // 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); + } - bool headerFound = false; - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) + bool headerFound = false; + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string &sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { - const std::string &sourceFilePath = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) - { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - notIncludedMocs.erase(sourceFilePath); - break; - } + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; } - if (!headerFound) + } + if (!headerFound) + { + // the moc file is in a subdir => look for the header in the same subdir + if (currentMoc.find_first_of('/') != std::string::npos) { - // the moc file is in a subdir => look for the header in the same subdir - if (currentMoc.find_first_of('/') != std::string::npos) + 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 &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; - notIncludedMocs.erase(sourceFilePath); - break; - } - } - if (!headerFound) + const std::string &sourceFilePath = filepath + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) { - std::cerr << "automoc4: 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); + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; } } - else + if (!headerFound) { std::cerr << "automoc4: The file \"" << absFilename << - "\" includes the moc file \"" << currentMoc << "\", but \"" << - absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' << - "\" does not exist." << std::endl; + "\" includes the moc file \"" << currentMoc << "\", but neither \"" << + absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" << + filepath + '{' + this->Join(headerExtensions, ',') + '}' << + "\" exist." << std::endl; ::exit(EXIT_FAILURE); } } + else + { + std::cerr << "automoc4: The file \"" << absFilename << + "\" includes the moc file \"" << currentMoc << "\", but \"" << + absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' << + "\" does not exist." << std::endl; + ::exit(EXIT_FAILURE); + } } - else - { - includedMocs[absFilename] = currentMoc; - notIncludedMocs.erase(absFilename); - } - matchOffset += mocIncludeRegExp.end(); - } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); - } + } + else + { + includedMocs[absFilename] = currentMoc; + notIncludedMocs.erase(absFilename); + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); } - else if (extension == ".h" || extension == ".hpp" - || extension == ".hxx" || extension == ".H") + } + + std::vector headerFiles; + cmSystemTools::ExpandListArgument(this->Headers, headerFiles); + for (std::vector::const_iterator it = headerFiles.begin(); + it != headerFiles.end(); + ++it) + { + const std::string &absFilename = *it; + if (this->Verbose) { - if (includedMocs.find(absFilename) == includedMocs.end() - && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) - { - // 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 std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp"; - notIncludedMocs[absFilename] = currentMoc; - } + printf("Checking -%s-\n", absFilename.c_str()); } - else + if (includedMocs.find(absFilename) == includedMocs.end() + && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) { - if (this->Verbose) - { - std::cout << "automoc4: ignoring file '" << absFilename << "' with unknown suffix" << std::endl; - } + // 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 std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp"; + notIncludedMocs[absFilename] = currentMoc; } } diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 0dafd4a..891b47a 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -32,6 +32,7 @@ private: std::string QtMajorVersion; std::string Sources; + std::string Headers; bool IncludeProjectDirsBefore; std::string Srcdir; std::string Builddir; -- cgit v0.12 From 126c6ead7707ac29f3b2fa779752025c7cc0da32 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 9 Aug 2011 09:18:37 +0200 Subject: Add the cmake module required currently for automoc Alex --- Modules/Automoc.cmake | 158 ++++++++++++++++++++++++++++++++++++++ Modules/AutomocInfo.cmake.in | 13 ++++ Source/cmAddExecutableCommand.cxx | 30 +++++++- Source/cmQtAutomoc.cxx | 126 ++++++++++++++++++++++++++++++ Source/cmQtAutomoc.h | 6 ++ Source/cmake.cxx | 7 ++ Source/cmake.h | 1 + 7 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 Modules/Automoc.cmake create mode 100644 Modules/AutomocInfo.cmake.in diff --git a/Modules/Automoc.cmake b/Modules/Automoc.cmake new file mode 100644 index 0000000..1e77c96 --- /dev/null +++ b/Modules/Automoc.cmake @@ -0,0 +1,158 @@ + +# AUTOMOC4_MOC_HEADERS( header1.h header2.h ...) +# Use this to add more header files to be processed with automoc4. +# +# AUTOMOC4_ADD_EXECUTABLE( src1 src2 ...) +# This macro does the same as ADD_EXECUTABLE, but additionally +# adds automoc4 handling for all source files. +# +# AUTOMOC4_ADD_LIBRARY( src1 src2 ...) +# This macro does the same as ADD_LIBRARY, but additionally +# adds automoc4 handling for all source files. + +# Internal helper macro, may change or be removed anytime: +# _ADD_AUTOMOC4_TARGET( ) +# +# Since version 0.9.88: +# The following two macros are only to be used for KDE4 projects +# and do something which makes sure automoc4 works for KDE. Don't +# use them anywhere else. See kdelibs/cmake/modules/KDE4Macros.cmake. +# _AUTOMOC4_KDE4_PRE_TARGET_HANDLING( ) +# _AUTOMOC4_KDE4_POST_TARGET_HANDLING() + +# Copyright (C) 2007 Matthias Kretz +# Copyright (C) 2008-2009 Alexander Neundorf +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +macro (AUTOMOC4_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 "AUTOMOC4_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_.cpp file using automoc4 + # and add it to the target + if(_headers_to_moc) + set(_automoc4_headers_${_target_NAME} "${_headers_to_moc}") + endif(_headers_to_moc) +endmacro (AUTOMOC4_MOC_HEADERS) + + +macro(_ADD_AUTOMOC4_TARGET _target_NAME _SRCS) + set(_moc_files) + set(_moc_headers) + + # first list all explicitly set headers + foreach(_header_to_moc ${_automoc4_headers_${_target_NAME}} ) + get_filename_component(_abs_header ${_header_to_moc} ABSOLUTE) + list(APPEND _moc_headers ${_abs_header}) + endforeach(_header_to_moc) + + # 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" OR _suffix STREQUAL ".mm") + list(APPEND _moc_files ${_abs_current_FILE}) + endif(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm") + endif(NOT _generated AND NOT _skip) + endforeach (_current_FILE) + + if(_moc_files OR _moc_headers) + set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}.cpp") + get_directory_property(_moc_incs INCLUDE_DIRECTORIES) + get_directory_property(_moc_defs DEFINITIONS) + get_directory_property(_moc_cdefs COMPILE_DEFINITIONS) + + # configure_file replaces _moc_files, _moc_incs, _moc_cdefs and _moc_defs + set(_automocTargetDir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target_NAME}.dir/" ) + set(AM_TARGET_NAME ${_target_NAME}) + configure_file(${CMAKE_ROOT}/Modules/AutomocInfo.cmake.in ${_automocTargetDir}/AutomocInfo.cmake @ONLY) + + add_custom_target(${_target_NAME} + COMMAND ${CMAKE_COMMAND} -E cmake_automoc "${_automocTargetDir}" ) + + set_source_files_properties(${_automoc_source} PROPERTIES GENERATED TRUE) + get_directory_property(_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) + list(APPEND _extra_clean_files "${_automoc_source}") + set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_extra_clean_files}") + set(${_SRCS} ${_automoc_source} ${${_SRCS}}) + endif(_moc_files OR _moc_headers) +endmacro(_ADD_AUTOMOC4_TARGET) + + +macro(AUTOMOC4_ADD_EXECUTABLE _target_NAME) + set(_SRCS ${ARGN}) + + set(_add_executable_param) + foreach(_argName "WIN32" "MACOSX_BUNDLE" "EXCLUDE_FROM_ALL") + list(FIND _SRCS ${_argName} _index) + if(_index GREATER -1) + list(APPEND _add_executable_param ${_argName}) + list(REMOVE_AT _SRCS ${_index}) + endif(_index GREATER -1) + endforeach(_argName) + + _add_automoc4_target("${_target_NAME}_automoc" _SRCS) + add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS}) + add_dependencies(${_target_NAME} "${_target_NAME}_automoc") + +endmacro(AUTOMOC4_ADD_EXECUTABLE) + + +macro(AUTOMOC4_ADD_LIBRARY _target_NAME) + set(_SRCS ${ARGN}) + + set(_add_executable_param) + foreach(_argName "STATIC" "SHARED" "MODULE" "EXCLUDE_FROM_ALL") + list(FIND _SRCS ${_argName} _index) + if(_index GREATER -1) + list(APPEND _add_executable_param ${_argName}) + list(REMOVE_AT _SRCS ${_index}) + endif(_index GREATER -1) + endforeach(_argName) + + _add_automoc4_target("${_target_NAME}_automoc" _SRCS) + add_library(${_target_NAME} ${_add_executable_param} ${_SRCS}) + add_dependencies(${_target_NAME} "${_target_NAME}_automoc") +endmacro(AUTOMOC4_ADD_LIBRARY) + + +macro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING _target _srcs) + _add_automoc4_target("${_target}_automoc" ${_srcs}) +endmacro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING) + + +macro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING _target) + add_dependencies(${_target} "${_target}_automoc") +endmacro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING) diff --git a/Modules/AutomocInfo.cmake.in b/Modules/AutomocInfo.cmake.in new file mode 100644 index 0000000..2dc3aa2 --- /dev/null +++ b/Modules/AutomocInfo.cmake.in @@ -0,0 +1,13 @@ +set(AM_SOURCES "@_moc_files@" ) +set(AM_HEADERS "@_moc_headers@" ) +set(AM_MOC_COMPILE_DEFINITIONS "@_moc_compile_defs@") +set(AM_MOC_DEFINITIONS "@_moc_defs@") +set(AM_MOC_INCLUDES "@_moc_incs@") +set(AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE "@CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE@") +set(AM_CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@/") +set(AM_CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@/") +set(AM_QT_MOC_EXECUTABLE "@QT_MOC_EXECUTABLE@") +set(AM_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") +set(AM_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") +set(AM_QT_VERSION_MAJOR "@QT_VERSION_MAJOR@" ) +set(AM_TARGET_NAME "@_moc_target_name@") diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index a625c47..9710d20 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -10,6 +10,7 @@ See the License for more information. ============================================================================*/ #include "cmAddExecutableCommand.h" +#include "cmQtAutomoc.h" // cmExecutableCommand bool cmAddExecutableCommand @@ -29,6 +30,7 @@ bool cmAddExecutableCommand bool use_macbundle = false; bool excludeFromAll = false; bool importTarget = false; + bool doAutomoc = false; while ( s != args.end() ) { if (*s == "WIN32") @@ -41,6 +43,11 @@ bool cmAddExecutableCommand ++s; use_macbundle = true; } + else if ( *s == "AUTOMOC" ) + { + ++s; + doAutomoc = true; + } else if(*s == "EXCLUDE_FROM_ALL") { ++s; @@ -58,12 +65,18 @@ bool cmAddExecutableCommand } // Special modifiers are not allowed with IMPORTED signature. - if(importTarget && (use_win32 || use_macbundle || excludeFromAll)) + if(importTarget + && (use_win32 || use_macbundle || excludeFromAll || doAutomoc)) { if(use_win32) { this->SetError("may not be given WIN32 for an IMPORTED target."); } + else if(doAutomoc) + { + this->SetError( + "may not be given AUTOMOC for an IMPORTED target."); + } else if(use_macbundle) { this->SetError( @@ -113,6 +126,14 @@ bool cmAddExecutableCommand } std::vector srclists(s, args.end()); + cmQtAutomoc* automoc = 0; + if ( doAutomoc ) + { + automoc = new cmQtAutomoc; + automoc->SetupAutomocTarget(this->Makefile, exename.c_str(), srclists); + } + + cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists, excludeFromAll); if ( use_win32 ) @@ -124,5 +145,12 @@ bool cmAddExecutableCommand tgt->SetProperty("MACOSX_BUNDLE", "ON"); } + if ( automoc ) + { + automoc->AddTargetDependency(this->Makefile, tgt); + delete automoc; + automoc = 0; + } + return true; } diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 5494b2a..1431551 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -1,6 +1,7 @@ #include "cmGlobalGenerator.h" #include "cmLocalGenerator.h" #include "cmMakefile.h" +#include "cmSourceFile.h" #include "cmSystemTools.h" #include "cmQtAutomoc.h" @@ -16,6 +17,131 @@ cmQtAutomoc::cmQtAutomoc() } +void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, + const char* targetName, + std::vector& srcs) +{ + // don't do anything if there is no Qt4: + std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); + if (qtMajorVersion != "4") + { + return; + } + + std::string automocTargetName = targetName; + automocTargetName += "_automoc"; + + std::string targetDir = makefile->GetCurrentOutputDirectory(); + targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory(); + targetDir += "/"; + targetDir += automocTargetName; + targetDir += ".dir/"; + + cmCustomCommandLine currentLine; + currentLine.push_back(makefile->GetCMakeInstance()->GetCMakeCommand()); + currentLine.push_back("-E"); + currentLine.push_back("cmake_automoc"); + currentLine.push_back(targetDir); + + cmCustomCommandLines commandLines; + commandLines.push_back(currentLine); + + std::string workingDirectory = cmSystemTools::CollapseFullPath( + "", makefile->GetCurrentOutputDirectory()); + + std::vector depends; + + cmTarget* target = makefile->AddUtilityCommand(automocTargetName.c_str(), + true, + workingDirectory.c_str(), depends, + commandLines, false, "Automoc target"); + + std::string _moc_files; + std::string _moc_headers; + const char* sepFiles = ""; + const char* sepHeaders = ""; + for(std::vector::const_iterator fileIt = srcs.begin(); + fileIt != srcs.end(); + ++fileIt) + { + std::string absFile = cmSystemTools::CollapseFullPath( + fileIt->c_str(), makefile->GetCurrentDirectory()); + + bool skip = false; + bool generated = false; + cmSourceFile* sf = makefile->GetSource(absFile.c_str()); + if (sf) + { + skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); + generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); + } + + if ((skip==false) && (generated == false)) + { + std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str()); + cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str()); + if (fileType == cmSystemTools::CXX_FILE_FORMAT) + { + _moc_files += sepFiles; + _moc_files += absFile; + sepFiles = ";"; + } + else if (fileType == cmSystemTools::HEADER_FILE_FORMAT) + { + _moc_headers += sepHeaders; + _moc_headers += absFile; + sepHeaders = ";"; + } + } + } + + std::string _moc_incs = makefile->GetProperty("INCLUDE_DIRECTORIES"); + std::string _moc_defs = makefile->GetProperty("DEFINITIONS"); + std::string _moc_compile_defs = makefile->GetProperty("COMPILE_DEFINITIONS"); + // forget the variables added here afterwards again: + cmMakefile::ScopePushPop varScope(makefile); + static_cast(varScope); + + makefile->AddDefinition("_moc_target_name", automocTargetName.c_str()); + makefile->AddDefinition("_moc_incs", _moc_incs.c_str()); + makefile->AddDefinition("_moc_defs", _moc_defs.c_str()); + makefile->AddDefinition("_moc_compile_defs", _moc_compile_defs.c_str()); + makefile->AddDefinition("_moc_files", _moc_files.c_str()); + makefile->AddDefinition("_moc_headers", _moc_headers.c_str()); + + const char* cmakeRoot = makefile->GetDefinition("CMAKE_ROOT"); + std::string inputFile = cmakeRoot; + inputFile += "/Modules/AutomocInfo.cmake.in"; + std::string outputFile = targetDir; + outputFile += "/AutomocInfo.cmake"; + makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(), + false, true, false); + + std::string mocCppFile = makefile->GetCurrentOutputDirectory(); + mocCppFile += "/"; + mocCppFile += automocTargetName; + mocCppFile += ".cpp"; + makefile->GetOrCreateSource(mocCppFile.c_str(), true); + srcs.push_back(mocCppFile); + +} + + +void cmQtAutomoc::AddTargetDependency(cmMakefile* makefile, cmTarget* target) +{ + // don't do anything if there is no Qt4: + std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); + if (qtMajorVersion != "4") + { + return; + } + + std::string automocTargetName = target->GetName(); + automocTargetName += "_automoc"; + target->AddUtility(automocTargetName.c_str()); +} + + bool cmQtAutomoc::Run(const char* targetDirectory) { cmake cm; diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index 891b47a..e573610 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -10,6 +10,12 @@ public: cmQtAutomoc(); bool Run(const char* targetDirectory); + void SetupAutomocTarget(cmMakefile* makefile, + const char* targetName, + std::vector& srcs); + + void AddTargetDependency(cmMakefile* makefile, cmTarget* target); + private: cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, const char* targetDirectory); diff --git a/Source/cmake.cxx b/Source/cmake.cxx index 06229e0..c5eff1c 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -2927,6 +2927,13 @@ const char* cmake::GetCPackCommand() return this->CPackCommand.c_str(); } + +const char* cmake::GetCMakeCommand() +{ + return this->CMakeCommand.c_str(); +} + + void cmake::MarkCliAsUsed(const std::string& variable) { this->UsedCliVariables[variable] = true; diff --git a/Source/cmake.h b/Source/cmake.h index f2a2ae3..09f6c37 100644 --- a/Source/cmake.h +++ b/Source/cmake.h @@ -301,6 +301,7 @@ class cmake */ const char* GetCTestCommand(); const char* GetCPackCommand(); + const char* GetCMakeCommand(); // Do we want debug output during the cmake run. bool GetDebugOutput() { return this->DebugOutput; } -- cgit v0.12 From 83b730cd1aeeafc05473d163e13fb5489817c149 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 10 Aug 2011 19:51:07 +0200 Subject: Add AUTOMOC to the add_library() command Alex --- Source/cmAddLibraryCommand.cxx | 50 ++++++++++++++++++++++++++++++++---------- Source/cmMakefile.cxx | 3 ++- Source/cmMakefile.h | 2 +- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index f522cee..2e0604e 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -12,6 +12,7 @@ #include "cmAddLibraryCommand.h" #include "cmake.h" +#include "cmQtAutomoc.h" // cmLibraryCommand bool cmAddLibraryCommand @@ -31,13 +32,14 @@ bool cmAddLibraryCommand } bool excludeFromAll = false; bool importTarget = false; - + bool doAutomoc = false; + std::vector::const_iterator s = args.begin(); std::string libName = *s; ++s; - + // If the second argument is "SHARED" or "STATIC", then it controls // the type of library. Otherwise, it is treated as a source or // source list name. There may be two keyword arguments, check for them @@ -79,6 +81,11 @@ bool cmAddLibraryCommand ++s; importTarget = true; } + else if (*s == "AUTOMOC") + { + ++s; + doAutomoc = true; + } else { break; @@ -103,16 +110,23 @@ bool cmAddLibraryCommand type = cmTarget::STATIC_LIBRARY; } - // The IMPORTED signature requires a type to be specified explicitly. - if(importTarget && !haveSpecifiedType) - { - this->SetError("called with IMPORTED argument but no library type."); - return false; - } - // Handle imported target creation. if(importTarget) { + // The IMPORTED signature requires a type to be specified explicitly. + if (!haveSpecifiedType) + { + this->SetError("called with IMPORTED argument but no library type."); + return false; + } + + // Don't run automoc on an imported library + if (doAutomoc) + { + this->SetError("cannot be called with AUTOMOC for an IMPORTED library."); + return false; + } + // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(libName.c_str())) { @@ -164,8 +178,22 @@ bool cmAddLibraryCommand ++s; } - this->Makefile->AddLibrary(libName.c_str(), type, srclists, - excludeFromAll); + cmQtAutomoc* automoc = 0; + if ( doAutomoc ) + { + automoc = new cmQtAutomoc; + automoc->SetupAutomocTarget(this->Makefile, libName.c_str(), srclists); + } + + cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists, + excludeFromAll); + + if ( automoc ) + { + automoc->AddTargetDependency(this->Makefile, tgt); + delete automoc; + automoc = 0; + } return true; } diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index a5cdee4..45165e5 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -1886,7 +1886,7 @@ void cmMakefile::AddGlobalLinkInformation(const char* name, cmTarget& target) } -void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, +cmTarget* cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, const std::vector &srcs, bool excludeFromAll) { @@ -1909,6 +1909,7 @@ void cmMakefile::AddLibrary(const char* lname, cmTarget::TargetType type, } target->AddSources(srcs); this->AddGlobalLinkInformation(lname, *target); + return target; } cmTarget* cmMakefile::AddExecutable(const char *exeName, diff --git a/Source/cmMakefile.h b/Source/cmMakefile.h index c01bb5d..618f4f3 100644 --- a/Source/cmMakefile.h +++ b/Source/cmMakefile.h @@ -325,7 +325,7 @@ public: /** * Set the name of the library. */ - void AddLibrary(const char *libname, cmTarget::TargetType type, + cmTarget* AddLibrary(const char *libname, cmTarget::TargetType type, const std::vector &srcs, bool excludeFromAll = false); -- cgit v0.12 From 735a5bb321ff7b92bebe2769e98a1d6317e88d27 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 10 Aug 2011 20:45:22 +0200 Subject: Fix line lengths Alex --- Source/cmQtAutomoc.cxx | 109 +++++++++++++++++++++++++++---------------------- 1 file changed, 60 insertions(+), 49 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 1431551..64f6e5f 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -7,8 +7,6 @@ #include "cmQtAutomoc.h" -#define TRACE_LINE() printf(" %s %d\n", __PRETTY_FUNCTION__, __LINE__) - cmQtAutomoc::cmQtAutomoc() :Verbose(true) ,RunMocFailed(false) @@ -79,7 +77,8 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, if ((skip==false) && (generated == false)) { std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str()); - cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(ext.c_str()); + cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat( + ext.c_str()); if (fileType == cmSystemTools::CXX_FILE_FORMAT) { _moc_files += sepFiles; @@ -200,11 +199,13 @@ bool cmQtAutomoc::ReadAutomocInfoFile(cmMakefile* makefile, this->QtMajorVersion = makefile->GetSafeDefinition("AM_QT_VERSION_MAJOR"); this->Sources = makefile->GetSafeDefinition("AM_SOURCES"); this->Headers = makefile->GetSafeDefinition("AM_HEADERS"); - this->IncludeProjectDirsBefore = makefile->IsOn("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); + this->IncludeProjectDirsBefore = makefile->IsOn( + "AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); this->Srcdir = makefile->GetSafeDefinition("AM_CMAKE_CURRENT_SOURCE_DIR"); this->Builddir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); this->MocExecutable = makefile->GetSafeDefinition("AM_QT_MOC_EXECUTABLE"); - this->MocCompileDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_COMPILE_DEFINITIONS"); + this->MocCompileDefinitionsStr = makefile->GetSafeDefinition( + "AM_MOC_COMPILE_DEFINITIONS"); this->MocDefinitionsStr = makefile->GetSafeDefinition("AM_MOC_DEFINITIONS"); this->MocIncludesStr = makefile->GetSafeDefinition("AM_MOC_INCLUDES"); this->ProjectBinaryDir = makefile->GetSafeDefinition("AM_CMAKE_BINARY_DIR"); @@ -361,13 +362,18 @@ bool cmQtAutomoc::RunAutomocQt4() this->GenerateAll = true; } - // 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_.cpp file is created and included in the _automoc.cpp file. - std::map includedMocs; // key = moc source filepath, value = moc output filepath - std::map notIncludedMocs; // key = moc source filepath, value = moc output filename + // 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_.cpp file is created and included in + // the _automoc.cpp file. + + // key = moc source filepath, value = moc output filepath + std::map includedMocs; + // key = moc source filepath, value = moc output filename + std::map notIncludedMocs; cmsys::RegularExpression mocIncludeRegExp( "[\n][ \t]*#[ \t]*include[ \t]+" @@ -422,8 +428,8 @@ bool cmQtAutomoc::RunAutomocQt4() int matchOffset = 0; if (!mocIncludeRegExp.find(contentsString.c_str())) { - // no moc #include, look whether we need to create a moc from the .h nevertheless - //std::cout << "no moc #include in the .cpp file"; + // no moc #include, look whether we need to create a moc from + // the .h nevertheless const std::string basename = cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); for(std::list::const_iterator ext = @@ -453,8 +459,8 @@ bool cmQtAutomoc::RunAutomocQt4() { const std::string privateHeaderName = absPath+basename+"_p"+(*ext); if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) - && includedMocs.find(privateHeaderName) == includedMocs.end() - && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) + && includedMocs.find(privateHeaderName) == includedMocs.end() + && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) { const std::string currentMoc = "moc_" + basename + "_p.cpp"; const std::string contents = this->ReadAll(privateHeaderName); @@ -479,20 +485,19 @@ bool cmQtAutomoc::RunAutomocQt4() GetFilenameWithoutLastExtension(currentMoc); const bool moc_style = 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, else from the header. - // - // TODO: currently any .moc file name will be used if the source contains + // 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, else from the + // header. // Q_OBJECT if (moc_style || !qObjectRegExp.find(contentsString)) { if (moc_style) { - // basename should be the part of the moc filename used for finding the - // correct header, so we need to remove the moc_ part + // 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); } @@ -513,7 +518,8 @@ bool cmQtAutomoc::RunAutomocQt4() } if (!headerFound) { - // the moc file is in a subdir => look for the header in the same subdir + // the moc file is in a subdir => look for the header in the + // same subdir if (currentMoc.find_first_of('/') != std::string::npos) { const std::string &filepath = absPath @@ -536,20 +542,23 @@ bool cmQtAutomoc::RunAutomocQt4() } if (!headerFound) { - std::cerr << "automoc4: The file \"" << absFilename << - "\" includes the moc file \"" << currentMoc << "\", but neither \"" << - absPath + basename + '{' + this->Join(headerExtensions, ',') + "}\" nor \"" << - filepath + '{' + this->Join(headerExtensions, ',') + '}' << - "\" exist." << std::endl; + std::cerr << "automoc4: 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); } } else { - std::cerr << "automoc4: The file \"" << absFilename << - "\" includes the moc file \"" << currentMoc << "\", but \"" << - absPath + basename + '{' + this->Join(headerExtensions, ',') + '}' << - "\" does not exist." << std::endl; + std::cerr << "automoc4: The file \"" << absFilename + << "\" includes the moc file \"" << currentMoc + << "\", but \"" << absPath << basename << '{' + << this->Join(headerExtensions, ',') << '}' + << "\" does not exist." << std::endl; ::exit(EXIT_FAILURE); } } @@ -578,17 +587,20 @@ bool cmQtAutomoc::RunAutomocQt4() if (includedMocs.find(absFilename) == includedMocs.end() && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) { - // 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 std::string currentMoc = "moc_" + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename) + ".cpp"; + // 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 std::string currentMoc = "moc_" + cmsys::SystemTools:: + GetFilenameWithoutLastExtension(absFilename) + ".cpp"; notIncludedMocs[absFilename] = currentMoc; } } // run moc on all the moc's that are #included in source files - for(std::map::const_iterator it = includedMocs.begin(); + for(std::map::const_iterator + it = includedMocs.begin(); it != includedMocs.end(); ++it) { @@ -605,8 +617,10 @@ bool cmQtAutomoc::RunAutomocQt4() } else { - // run moc on the remaining headers and include them in the _automoc.cpp file - for(std::map::const_iterator it = notIncludedMocs.begin(); + // run moc on the remaining headers and include them in + // the _automoc.cpp file + for(std::map::const_iterator + it = notIncludedMocs.begin(); it != notIncludedMocs.end(); ++it) { @@ -621,8 +635,6 @@ bool cmQtAutomoc::RunAutomocQt4() if (this->RunMocFailed) { - // if any moc process failed we don't want to touch the _automoc.cpp file so that - // automoc4 is rerun until the issue is fixed std::cerr << "returning failed.."<< std::endl; return false; } @@ -638,7 +650,6 @@ bool cmQtAutomoc::RunAutomocQt4() 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) std::fstream outfile; @@ -654,7 +665,6 @@ bool cmQtAutomoc::RunAutomocQt4() bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, const std::string& mocFileName) { - //std::cout << "AutoMoc::generateMoc" << sourceFile << mocFileName << std::endl; const std::string mocFilePath = this->Builddir + mocFileName; int sourceNewerThanMoc = 0; bool success = cmsys::SystemTools::FileTimeCompare(sourceFile.c_str(), @@ -710,10 +720,11 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, std::string output; int retVal = 0; - const bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); + bool result = cmSystemTools::RunSingleCommand(command, &output, &retVal); if (!result || retVal) { - std::cerr << "automoc4: process for " << mocFilePath << " failed:\n" << output << std::endl; + std::cerr << "automoc4: process for " << mocFilePath << " failed:\n" + << output << std::endl; this->RunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath.c_str()); } -- cgit v0.12 From ace121534de464bc7da35694a93cfb8ccc3effb6 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 10 Aug 2011 21:00:53 +0200 Subject: Move code for parsing a cpp-file from the big loop to separate function Alex --- Source/cmQtAutomoc.cxx | 365 ++++++++++++++++++++++++------------------------- Source/cmQtAutomoc.h | 4 + 2 files changed, 186 insertions(+), 183 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 64f6e5f..5bfb928 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -375,33 +375,6 @@ bool cmQtAutomoc::RunAutomocQt4() // key = moc source filepath, value = moc output filename std::map notIncludedMocs; - cmsys::RegularExpression mocIncludeRegExp( - "[\n][ \t]*#[ \t]*include[ \t]+" - "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); - cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); - std::list headerExtensions; -#if defined(_WIN32) - // not case sensitive - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); -#elif defined(__APPLE__) - headerExtensions.push_back(".h"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); - - // 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"); - headerExtensions.push_back(".hpp"); - headerExtensions.push_back(".hxx"); - headerExtensions.push_back(".H"); -#endif std::vector sourceFiles; cmSystemTools::ExpandListArgument(this->Sources, sourceFiles); @@ -415,162 +388,7 @@ bool cmQtAutomoc::RunAutomocQt4() { printf("Checking -%s-\n", absFilename.c_str()); } - - const std::string contentsString = this->ReadAll(absFilename); - if (contentsString.empty()) - { - std::cerr << "automoc4: empty source file: " << absFilename << std::endl; - continue; - } - const std::string absPath = cmsys::SystemTools::GetFilenamePath( - cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - - int matchOffset = 0; - if (!mocIncludeRegExp.find(contentsString.c_str())) - { - // no moc #include, look whether we need to create a moc from - // the .h nevertheless - const std::string basename = - cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) - { - const std::string headername = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(headername.c_str()) - && includedMocs.find(headername) == includedMocs.end() - && notIncludedMocs.find(headername) == notIncludedMocs.end()) - { - const std::string currentMoc = "moc_" + basename + ".cpp"; - const std::string contents = this->ReadAll(headername); - if (qObjectRegExp.find(contents)) - { - //std::cout << "header contains Q_OBJECT macro"; - notIncludedMocs[headername] = currentMoc; - } - break; - } - } - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) - { - const std::string privateHeaderName = absPath+basename+"_p"+(*ext); - if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) - && includedMocs.find(privateHeaderName) == includedMocs.end() - && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) - { - const std::string currentMoc = "moc_" + basename + "_p.cpp"; - const std::string contents = this->ReadAll(privateHeaderName); - if (qObjectRegExp.find(contents)) - { - //std::cout << "header contains Q_OBJECT macro"; - notIncludedMocs[privateHeaderName] = currentMoc; - } - break; - } - } - } - else - { - // for every moc include in the file - do - { - const std::string currentMoc = mocIncludeRegExp.match(1); - //std::cout << "found moc include: " << currentMoc << std::endl; - - std::string basename = cmsys::SystemTools:: - GetFilenameWithoutLastExtension(currentMoc); - const bool moc_style = 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, else from the - // header. - // Q_OBJECT - if (moc_style || !qObjectRegExp.find(contentsString)) - { - if (moc_style) - { - // 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); - } - - bool headerFound = false; - for(std::list::const_iterator ext = - headerExtensions.begin(); - ext != headerExtensions.end(); - ++ext) - { - const std::string &sourceFilePath = absPath + basename + (*ext); - if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) - { - headerFound = true; - includedMocs[sourceFilePath] = currentMoc; - notIncludedMocs.erase(sourceFilePath); - break; - } - } - if (!headerFound) - { - // the moc file is in a subdir => look for the header in the - // same subdir - if (currentMoc.find_first_of('/') != std::string::npos) - { - 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; - notIncludedMocs.erase(sourceFilePath); - break; - } - } - if (!headerFound) - { - std::cerr << "automoc4: 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); - } - } - else - { - std::cerr << "automoc4: The file \"" << absFilename - << "\" includes the moc file \"" << currentMoc - << "\", but \"" << absPath << basename << '{' - << this->Join(headerExtensions, ',') << '}' - << "\" does not exist." << std::endl; - ::exit(EXIT_FAILURE); - } - } - } - else - { - includedMocs[absFilename] = currentMoc; - notIncludedMocs.erase(absFilename); - } - matchOffset += mocIncludeRegExp.end(); - } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); - } + this->ParseCppFile(absFilename, includedMocs, notIncludedMocs); } std::vector headerFiles; @@ -662,6 +480,187 @@ bool cmQtAutomoc::RunAutomocQt4() } +void cmQtAutomoc::ParseCppFile(const std::string& absFilename, + std::map& includedMocs, + std::map& notIncludedMocs) +{ + cmsys::RegularExpression mocIncludeRegExp( + "[\n][ \t]*#[ \t]*include[ \t]+" + "[\"<](([^ \">]+/)?moc_[^ \">/]+\\.cpp|[^ \">]+\\.moc)[\">]"); + cmsys::RegularExpression qObjectRegExp("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); + 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 << "automoc4: empty source file: " << absFilename << std::endl; + return; + } + const std::string absPath = cmsys::SystemTools::GetFilenamePath( + cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; + + int matchOffset = 0; + if (!mocIncludeRegExp.find(contentsString.c_str())) + { + // no moc #include, look whether we need to create a moc from + // the .h nevertheless + const std::string basename = + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFilename); + for(std::list::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string headername = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(headername.c_str()) + && includedMocs.find(headername) == includedMocs.end() + && notIncludedMocs.find(headername) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + ".cpp"; + const std::string contents = this->ReadAll(headername); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[headername] = currentMoc; + } + break; + } + } + for(std::list::const_iterator ext = headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string privateHeaderName = absPath+basename+"_p"+(*ext); + if (cmsys::SystemTools::FileExists(privateHeaderName.c_str()) + && includedMocs.find(privateHeaderName) == includedMocs.end() + && notIncludedMocs.find(privateHeaderName) == notIncludedMocs.end()) + { + const std::string currentMoc = "moc_" + basename + "_p.cpp"; + const std::string contents = this->ReadAll(privateHeaderName); + if (qObjectRegExp.find(contents)) + { + //std::cout << "header contains Q_OBJECT macro"; + notIncludedMocs[privateHeaderName] = currentMoc; + } + break; + } + } + } + else + { + // for every moc include in the file + do + { + const std::string currentMoc = mocIncludeRegExp.match(1); + //std::cout << "found moc include: " << currentMoc << std::endl; + + std::string basename = cmsys::SystemTools:: + GetFilenameWithoutLastExtension(currentMoc); + const bool moc_style = 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, else from the + // header. + // Q_OBJECT + if (moc_style || !qObjectRegExp.find(contentsString)) + { + if (moc_style) + { + // 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); + } + + bool headerFound = false; + for(std::list::const_iterator ext = + headerExtensions.begin(); + ext != headerExtensions.end(); + ++ext) + { + const std::string &sourceFilePath = absPath + basename + (*ext); + if (cmsys::SystemTools::FileExists(sourceFilePath.c_str())) + { + headerFound = true; + includedMocs[sourceFilePath] = currentMoc; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + // the moc file is in a subdir => look for the header in the + // same subdir + if (currentMoc.find_first_of('/') != std::string::npos) + { + 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; + notIncludedMocs.erase(sourceFilePath); + break; + } + } + if (!headerFound) + { + std::cerr << "automoc4: 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); + } + } + else + { + std::cerr << "automoc4: The file \"" << absFilename + << "\" includes the moc file \"" << currentMoc + << "\", but \"" << absPath << basename << '{' + << this->Join(headerExtensions, ',') << '}' + << "\" does not exist." << std::endl; + ::exit(EXIT_FAILURE); + } + } + } + else + { + includedMocs[absFilename] = currentMoc; + notIncludedMocs.erase(absFilename); + } + matchOffset += mocIncludeRegExp.end(); + } while(mocIncludeRegExp.find(contentsString.c_str() + matchOffset)); + } +} + + bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, const std::string& mocFileName) { diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index e573610..edb66f0 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -29,6 +29,10 @@ private: bool RunAutomocQt4(); bool GenerateMoc(const std::string& sourceFile, const std::string& mocFileName); + void ParseCppFile(const std::string& absFilename, + std::map& includedMocs, + std::map& notIncludedMocs); + void Init(); std::string Join(const std::list& lst, char separator); -- cgit v0.12 From 93032953afb5bd939dceb3ce427f4b6fa50e2450 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 10 Aug 2011 23:49:30 +0200 Subject: Initialize verbose based onb the env.var. Alex --- Source/cmQtAutomoc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 5bfb928..2add7c0 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -8,7 +8,7 @@ cmQtAutomoc::cmQtAutomoc() -:Verbose(true) +:Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) ,RunMocFailed(false) ,GenerateAll(false) { -- cgit v0.12 From ddb517d014bf2245b38a0b56c9b7e98e6aaf7988 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 14 Aug 2011 16:43:04 +0200 Subject: Color output when running moc Alex --- Source/cmQtAutomoc.cxx | 30 ++++++++++++++++++++++-------- Source/cmQtAutomoc.h | 1 + 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 2add7c0..6e8c77e 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -4,14 +4,31 @@ #include "cmSourceFile.h" #include "cmSystemTools.h" +# include + #include "cmQtAutomoc.h" cmQtAutomoc::cmQtAutomoc() :Verbose(cmsys::SystemTools::GetEnv("VERBOSE") != 0) +,ColorOutput(true) ,RunMocFailed(false) ,GenerateAll(false) { + + std::string colorEnv = ""; + cmsys::SystemTools::GetEnv("COLOR", colorEnv); + if(!colorEnv.empty()) + { + if(cmSystemTools::IsOn(colorEnv.c_str())) + { + this->ColorOutput = true; + } + else + { + this->ColorOutput = false; + } + } } @@ -678,14 +695,11 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, cmsys::SystemTools::MakeDirectory(mocDir.c_str()); } -/* if (this->Verbose) - { - echoColor("Generating " + mocFilePath + " from " + sourceFile); - } - else - { - echoColor("Generating " + mocFileName); - }*/ + std::string msg = "Generating "; + msg += mocFileName; + cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue + |cmsysTerminal_Color_ForegroundBold, + msg.c_str(), true, this->ColorOutput); std::vector command; command.push_back(this->MocExecutable); diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index edb66f0..af77366 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -61,6 +61,7 @@ private: std::list MocDefinitions; bool Verbose; + bool ColorOutput; bool RunMocFailed; bool GenerateAll; -- cgit v0.12 From 72caf4d1787bc464f68954853a4edc3cf169a5f0 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 14 Aug 2011 17:06:34 +0200 Subject: Add the generated automoc.cpp file to the cleaned files Alex --- Source/cmQtAutomoc.cxx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 6e8c77e..316d824 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -140,6 +140,8 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, makefile->GetOrCreateSource(mocCppFile.c_str(), true); srcs.push_back(mocCppFile); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + mocCppFile.c_str(), false); } -- cgit v0.12 From 58b7fe65453f1d4b25537950de2277af2951fd85 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Sun, 14 Aug 2011 17:17:01 +0200 Subject: Use cout instead of printf() Alex --- Source/cmQtAutomoc.cxx | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 316d824..b03e9cf 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -405,7 +405,7 @@ bool cmQtAutomoc::RunAutomocQt4() const std::string &absFilename = *it; if (this->Verbose) { - printf("Checking -%s-\n", absFilename.c_str()); + std::cout << "AUTOMOC: Checking " << absFilename << std::endl; } this->ParseCppFile(absFilename, includedMocs, notIncludedMocs); } @@ -419,7 +419,7 @@ bool cmQtAutomoc::RunAutomocQt4() const std::string &absFilename = *it; if (this->Verbose) { - printf("Checking -%s-\n", absFilename.c_str()); + std::cout << "AUTOMOC: Checking " << absFilename << std::endl; } if (includedMocs.find(absFilename) == includedMocs.end() && notIncludedMocs.find(absFilename) == notIncludedMocs.end()) @@ -527,7 +527,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, const std::string contentsString = this->ReadAll(absFilename); if (contentsString.empty()) { - std::cerr << "automoc4: empty source file: " << absFilename << std::endl; + std::cerr << "AUTOMOC: empty source file: " << absFilename << std::endl; return; } const std::string absPath = cmsys::SystemTools::GetFilenamePath( @@ -648,7 +648,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } if (!headerFound) { - std::cerr << "automoc4: The file \"" << absFilename + std::cerr << "AUTOMOC: The file \"" << absFilename << "\" includes the moc file \"" << currentMoc << "\", but neither \"" << absPath << basename << '{' << this->Join(headerExtensions, ',') @@ -660,7 +660,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, } else { - std::cerr << "automoc4: The file \"" << absFilename + std::cerr << "AUTOMOC: The file \"" << absFilename << "\" includes the moc file \"" << currentMoc << "\", but \"" << absPath << basename << '{' << this->Join(headerExtensions, ',') << '}' @@ -728,9 +728,9 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, { for(int i=0; iRunMocFailed = true; cmSystemTools::RemoveFile(mocFilePath.c_str()); -- cgit v0.12 From 24d9b7d7452bfd9b3d7cea670a3a5a2e9f5b2f16 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 01:26:02 +0200 Subject: Remove trailing whitespace Alex --- Source/cmAddLibraryCommand.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index 2e0604e..a581ea1 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -92,11 +92,11 @@ bool cmAddLibraryCommand } } - /* ideally we should check whether for the linker language of the target + /* ideally we should check whether for the linker language of the target CMAKE_${LANG}_CREATE_SHARED_LIBRARY is defined and if not default to - STATIC. But at this point we know only the name of the target, but not + STATIC. But at this point we know only the name of the target, but not yet its linker language. */ - if ((type != cmTarget::STATIC_LIBRARY) && + if ((type != cmTarget::STATIC_LIBRARY) && (this->Makefile->GetCMakeInstance()->GetPropertyAsBool( "TARGET_SUPPORTS_SHARED_LIBS") == false)) { @@ -172,9 +172,9 @@ bool cmAddLibraryCommand } std::vector srclists; - while (s != args.end()) + while (s != args.end()) { - srclists.push_back(*s); + srclists.push_back(*s); ++s; } @@ -194,7 +194,7 @@ bool cmAddLibraryCommand delete automoc; automoc = 0; } - + return true; } -- cgit v0.12 From c27607baf860b6c57db84f21a298ad8257ff7153 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 01:27:30 +0200 Subject: Refactor SetupAutomocTarget() so it can be run after creating the target This makes it easier to move it from InitialPass() to some other location, e.g. FinalPass() or something else. Alex --- Source/cmAddExecutableCommand.cxx | 15 +++-------- Source/cmAddLibraryCommand.cxx | 14 +++------- Source/cmQtAutomoc.cxx | 57 +++++++++++++++------------------------ Source/cmQtAutomoc.h | 6 +---- 4 files changed, 28 insertions(+), 64 deletions(-) diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index 9710d20..ef75b3b 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -126,14 +126,6 @@ bool cmAddExecutableCommand } std::vector srclists(s, args.end()); - cmQtAutomoc* automoc = 0; - if ( doAutomoc ) - { - automoc = new cmQtAutomoc; - automoc->SetupAutomocTarget(this->Makefile, exename.c_str(), srclists); - } - - cmTarget* tgt = this->Makefile->AddExecutable(exename.c_str(), srclists, excludeFromAll); if ( use_win32 ) @@ -145,11 +137,10 @@ bool cmAddExecutableCommand tgt->SetProperty("MACOSX_BUNDLE", "ON"); } - if ( automoc ) + if ( doAutomoc ) { - automoc->AddTargetDependency(this->Makefile, tgt); - delete automoc; - automoc = 0; + cmQtAutomoc automoc; + automoc.SetupAutomocTarget(tgt); } return true; diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index a581ea1..f0b2e0d 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -178,21 +178,13 @@ bool cmAddLibraryCommand ++s; } - cmQtAutomoc* automoc = 0; - if ( doAutomoc ) - { - automoc = new cmQtAutomoc; - automoc->SetupAutomocTarget(this->Makefile, libName.c_str(), srclists); - } - cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll); - if ( automoc ) + if ( doAutomoc ) { - automoc->AddTargetDependency(this->Makefile, tgt); - delete automoc; - automoc = 0; + cmQtAutomoc automoc; + automoc.SetupAutomocTarget(tgt); } return true; diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index b03e9cf..6dbc9e1 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -32,10 +32,10 @@ cmQtAutomoc::cmQtAutomoc() } -void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, - const char* targetName, - std::vector& srcs) +void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) { + cmMakefile* makefile = target->GetMakefile(); + const char* targetName = target->GetName(); // don't do anything if there is no Qt4: std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); if (qtMajorVersion != "4") @@ -43,6 +43,7 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, return; } + // create a custom target for running automoc at buildtime: std::string automocTargetName = targetName; automocTargetName += "_automoc"; @@ -66,34 +67,32 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, std::vector depends; - cmTarget* target = makefile->AddUtilityCommand(automocTargetName.c_str(), - true, + cmTarget* mocTarget = makefile->AddUtilityCommand(automocTargetName.c_str(), + true, workingDirectory.c_str(), depends, commandLines, false, "Automoc target"); + target->AddUtility(automocTargetName.c_str()); + // configure a file to get all information to automoc at buildtime: std::string _moc_files; std::string _moc_headers; const char* sepFiles = ""; const char* sepHeaders = ""; - for(std::vector::const_iterator fileIt = srcs.begin(); - fileIt != srcs.end(); + + const std::vector& srcFiles = target->GetSourceFiles(); + + for(std::vector::const_iterator fileIt = srcFiles.begin(); + fileIt != srcFiles.end(); ++fileIt) { - std::string absFile = cmSystemTools::CollapseFullPath( - fileIt->c_str(), makefile->GetCurrentDirectory()); - - bool skip = false; - bool generated = false; - cmSourceFile* sf = makefile->GetSource(absFile.c_str()); - if (sf) - { - skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); - generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); - } + cmSourceFile* sf = *fileIt; + std::string absFile = sf->GetFullPath(); + bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); + bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")); if ((skip==false) && (generated == false)) { - std::string ext = cmSystemTools::GetFilenameExtension(fileIt->c_str()); + std::string ext = sf->GetExtension(); cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat( ext.c_str()); if (fileType == cmSystemTools::CXX_FILE_FORMAT) @@ -137,29 +136,15 @@ void cmQtAutomoc::SetupAutomocTarget(cmMakefile* makefile, mocCppFile += "/"; mocCppFile += automocTargetName; mocCppFile += ".cpp"; - makefile->GetOrCreateSource(mocCppFile.c_str(), true); - srcs.push_back(mocCppFile); + cmSourceFile* mocCppSource = makefile->GetOrCreateSource(mocCppFile.c_str(), + true); + target->AddSourceFile(mocCppSource); makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", mocCppFile.c_str(), false); } -void cmQtAutomoc::AddTargetDependency(cmMakefile* makefile, cmTarget* target) -{ - // don't do anything if there is no Qt4: - std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR"); - if (qtMajorVersion != "4") - { - return; - } - - std::string automocTargetName = target->GetName(); - automocTargetName += "_automoc"; - target->AddUtility(automocTargetName.c_str()); -} - - bool cmQtAutomoc::Run(const char* targetDirectory) { cmake cm; diff --git a/Source/cmQtAutomoc.h b/Source/cmQtAutomoc.h index af77366..4fd9041 100644 --- a/Source/cmQtAutomoc.h +++ b/Source/cmQtAutomoc.h @@ -10,11 +10,7 @@ public: cmQtAutomoc(); bool Run(const char* targetDirectory); - void SetupAutomocTarget(cmMakefile* makefile, - const char* targetName, - std::vector& srcs); - - void AddTargetDependency(cmMakefile* makefile, cmTarget* target); + void SetupAutomocTarget(cmTarget* target); private: cmGlobalGenerator* CreateGlobalGenerator(cmake* cm, -- cgit v0.12 From cbaac2a587d8457b69d832e2c63de8fb755ec64d Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 01:44:13 +0200 Subject: Remove trailing whitespace Alex --- Source/cmGlobalGenerator.cxx | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 2eae01e..f37b054 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -269,7 +269,7 @@ cmGlobalGenerator::EnableLanguage(std::vectorconst& languages, cmOStringStream windowsVersionString; windowsVersionString << osvi.dwMajorVersion << "." << osvi.dwMinorVersion; windowsVersionString.str(); - mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", + mf->AddDefinition("CMAKE_HOST_SYSTEM_VERSION", windowsVersionString.str().c_str()); #endif // Read the DetermineSystem file @@ -618,8 +618,8 @@ void cmGlobalGenerator::SetLanguageEnabledMaps(const char* l, cmMakefile* mf) if (sscanf(linkerPref, "%d", &preference)!=1) { // backward compatibility: before 2.6 LINKER_PREFERENCE - // was either "None" or "Prefered", and only the first character was - // tested. So if there is a custom language out there and it is + // was either "None" or "Prefered", and only the first character was + // tested. So if there is a custom language out there and it is // "Prefered", set its preference high if (linkerPref[0]=='P') { @@ -1019,9 +1019,9 @@ void cmGlobalGenerator::CheckLocalGenerators() if(notFoundMap.size()) { std::string notFoundVars; - for(std::map::const_iterator + for(std::map::const_iterator ii = notFoundMap.begin(); - ii != notFoundMap.end(); + ii != notFoundMap.end(); ++ii) { notFoundVars += ii->first; @@ -1057,7 +1057,7 @@ int cmGlobalGenerator::TryCompile(const char *srcdir, const char *bindir, { this->FirstTimeProgress = 0.95f; } - this->CMakeInstance->UpdateProgress("Configuring", + this->CMakeInstance->UpdateProgress("Configuring", this->FirstTimeProgress); } @@ -1161,7 +1161,7 @@ int cmGlobalGenerator::Build( { outputPtr = &outputBuffer; } - + // should we do a clean first? if (clean) { @@ -1199,7 +1199,7 @@ int cmGlobalGenerator::Build( // now build std::string makeCommand = this->GenerateBuildCommand(makeCommandCSTR, projectName, - extraOptions, target, + extraOptions, target, config, false, fast); if(output) { @@ -1272,8 +1272,8 @@ void cmGlobalGenerator::AddLocalGenerator(cmLocalGenerator *lg) if(this->FirstTimeProgress > 0.95f) { this->FirstTimeProgress = 0.95f; - } - this->CMakeInstance->UpdateProgress("Configuring", + } + this->CMakeInstance->UpdateProgress("Configuring", this->FirstTimeProgress); return; } @@ -1296,8 +1296,8 @@ void cmGlobalGenerator::AddInstallComponent(const char* component) } } -void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, - cmTarget* target, +void cmGlobalGenerator::AddTargetToExports(const char* exportSetName, + cmTarget* target, cmInstallTargetGenerator* archive, cmInstallTargetGenerator* runTime, cmInstallTargetGenerator* library, @@ -1331,7 +1331,7 @@ void cmGlobalGenerator::ClearExportSets() const std::vector* cmGlobalGenerator::GetExportSet( const char* name) const { - std::map >::const_iterator + std::map >::const_iterator exportSetIt = this->ExportSets.find(name); if (exportSetIt != this->ExportSets.end()) { @@ -1443,7 +1443,7 @@ void cmGlobalGenerator::GetEnabledLanguages(std::vector& lang) int cmGlobalGenerator::GetLinkerPreference(const char* lang) { - std::map::const_iterator it = + std::map::const_iterator it = this->LanguageToLinkerPreference.find(lang); if (it != this->LanguageToLinkerPreference.end()) { -- cgit v0.12 From 50cd6cef925a53dfbbb820ae7343981dcf00f36c Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 01:45:05 +0200 Subject: Move automoc processing from add_executable/library to cmGlobalGenerator Now automoc is enabled by setting the AUTOMOC target property to true, instead of using the AUTOMOC keyword in add_executable() or add_library() Alex --- Source/cmAddExecutableCommand.cxx | 20 +------------------- Source/cmAddLibraryCommand.cxx | 23 +---------------------- Source/cmGlobalGenerator.cxx | 32 ++++++++++++++++++++++++++++++++ Source/cmGlobalGenerator.h | 2 ++ 4 files changed, 36 insertions(+), 41 deletions(-) diff --git a/Source/cmAddExecutableCommand.cxx b/Source/cmAddExecutableCommand.cxx index ef75b3b..bac2430 100644 --- a/Source/cmAddExecutableCommand.cxx +++ b/Source/cmAddExecutableCommand.cxx @@ -10,7 +10,6 @@ See the License for more information. ============================================================================*/ #include "cmAddExecutableCommand.h" -#include "cmQtAutomoc.h" // cmExecutableCommand bool cmAddExecutableCommand @@ -30,7 +29,6 @@ bool cmAddExecutableCommand bool use_macbundle = false; bool excludeFromAll = false; bool importTarget = false; - bool doAutomoc = false; while ( s != args.end() ) { if (*s == "WIN32") @@ -43,11 +41,6 @@ bool cmAddExecutableCommand ++s; use_macbundle = true; } - else if ( *s == "AUTOMOC" ) - { - ++s; - doAutomoc = true; - } else if(*s == "EXCLUDE_FROM_ALL") { ++s; @@ -66,17 +59,12 @@ bool cmAddExecutableCommand // Special modifiers are not allowed with IMPORTED signature. if(importTarget - && (use_win32 || use_macbundle || excludeFromAll || doAutomoc)) + && (use_win32 || use_macbundle || excludeFromAll)) { if(use_win32) { this->SetError("may not be given WIN32 for an IMPORTED target."); } - else if(doAutomoc) - { - this->SetError( - "may not be given AUTOMOC for an IMPORTED target."); - } else if(use_macbundle) { this->SetError( @@ -137,11 +125,5 @@ bool cmAddExecutableCommand tgt->SetProperty("MACOSX_BUNDLE", "ON"); } - if ( doAutomoc ) - { - cmQtAutomoc automoc; - automoc.SetupAutomocTarget(tgt); - } - return true; } diff --git a/Source/cmAddLibraryCommand.cxx b/Source/cmAddLibraryCommand.cxx index f0b2e0d..efa29e6 100644 --- a/Source/cmAddLibraryCommand.cxx +++ b/Source/cmAddLibraryCommand.cxx @@ -12,7 +12,6 @@ #include "cmAddLibraryCommand.h" #include "cmake.h" -#include "cmQtAutomoc.h" // cmLibraryCommand bool cmAddLibraryCommand @@ -32,7 +31,6 @@ bool cmAddLibraryCommand } bool excludeFromAll = false; bool importTarget = false; - bool doAutomoc = false; std::vector::const_iterator s = args.begin(); @@ -81,11 +79,6 @@ bool cmAddLibraryCommand ++s; importTarget = true; } - else if (*s == "AUTOMOC") - { - ++s; - doAutomoc = true; - } else { break; @@ -120,13 +113,6 @@ bool cmAddLibraryCommand return false; } - // Don't run automoc on an imported library - if (doAutomoc) - { - this->SetError("cannot be called with AUTOMOC for an IMPORTED library."); - return false; - } - // Make sure the target does not already exist. if(this->Makefile->FindTargetToUse(libName.c_str())) { @@ -178,14 +164,7 @@ bool cmAddLibraryCommand ++s; } - cmTarget* tgt =this->Makefile->AddLibrary(libName.c_str(), type, srclists, - excludeFromAll); - - if ( doAutomoc ) - { - cmQtAutomoc automoc; - automoc.SetupAutomocTarget(tgt); - } + this->Makefile->AddLibrary(libName.c_str(), type, srclists, excludeFromAll); return true; } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index f37b054..3016f5a 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -18,6 +18,7 @@ #include "cmExternalMakefileProjectGenerator.h" #include "cmake.h" #include "cmMakefile.h" +#include "cmQtAutomoc.h" #include "cmSourceFile.h" #include "cmVersion.h" #include "cmExportInstallFileGenerator.h" @@ -832,6 +833,10 @@ void cmGlobalGenerator::Generate() return; } + // Iterate through all targets and set up automoc for those which have + // the AUTOMOC property set + this->CreateAutomocTargets(); + // For each existing cmLocalGenerator unsigned int i; @@ -950,6 +955,33 @@ bool cmGlobalGenerator::CheckTargets() return true; } +//---------------------------------------------------------------------------- +void cmGlobalGenerator::CreateAutomocTargets() +{ + for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) + { + cmTargets& targets = + this->LocalGenerators[i]->GetMakefile()->GetTargets(); + for(cmTargets::iterator ti = targets.begin(); + ti != targets.end(); ++ti) + { + cmTarget& target = ti->second; + if(target.GetType() == cmTarget::EXECUTABLE || + target.GetType() == cmTarget::STATIC_LIBRARY || + target.GetType() == cmTarget::SHARED_LIBRARY || + target.GetType() == cmTarget::MODULE_LIBRARY) + { + if(target.GetPropertyAsBool("AUTOMOC") && !target.IsImported()) + { + cmQtAutomoc automoc; + automoc.SetupAutomocTarget(&target); + } + } + } + } +} + + void cmGlobalGenerator::CheckLocalGenerators() { std::map notFoundMap; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index b7b1bff..88eb8b6 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -282,6 +282,8 @@ protected: virtual bool CheckALLOW_DUPLICATE_CUSTOM_TARGETS(); bool CheckTargets(); + void CreateAutomocTargets(); + // Fill the ProjectMap, this must be called after LocalGenerators // has been populated. -- cgit v0.12 From d045fd4ec5d88658988c8878b313b2bf7924f40f Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 02:00:36 +0200 Subject: Nicer progress message for the automoc target Alex --- Source/cmQtAutomoc.cxx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 6dbc9e1..e8c4baa 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -66,11 +66,13 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) "", makefile->GetCurrentOutputDirectory()); std::vector depends; + std::string automocComment = "Automoc for target "; + automocComment += targetName; cmTarget* mocTarget = makefile->AddUtilityCommand(automocTargetName.c_str(), true, - workingDirectory.c_str(), depends, - commandLines, false, "Automoc target"); + workingDirectory.c_str(), depends, + commandLines, false, automocComment.c_str()); target->AddUtility(automocTargetName.c_str()); // configure a file to get all information to automoc at buildtime: -- cgit v0.12 From bf8ef778a317fd7cd82bcc658fc734bf3f29911e Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 02:10:45 +0200 Subject: Add a test for automoc The files are taken from the Qt examples. They are BSD licensed, so it should be fine. I only edited main.cpp to use both widgets. Alex --- Tests/CMakeLists.txt | 18 ++ Tests/QtAutomoc/CMakeLists.txt | 20 ++ Tests/QtAutomoc/calwidget.cpp | 424 +++++++++++++++++++++++++++++++++++++++++ Tests/QtAutomoc/calwidget.h | 121 ++++++++++++ Tests/QtAutomoc/codeeditor.cpp | 153 +++++++++++++++ Tests/QtAutomoc/codeeditor.h | 99 ++++++++++ Tests/QtAutomoc/main.cpp | 58 ++++++ 7 files changed, 893 insertions(+) create mode 100644 Tests/QtAutomoc/CMakeLists.txt create mode 100644 Tests/QtAutomoc/calwidget.cpp create mode 100644 Tests/QtAutomoc/calwidget.h create mode 100644 Tests/QtAutomoc/codeeditor.cpp create mode 100644 Tests/QtAutomoc/codeeditor.h create mode 100644 Tests/QtAutomoc/main.cpp diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 4bf83b7..30549b6 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -840,6 +840,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/Environment") + IF(NOT QT4_FOUND) + FIND_PACKAGE(Qt4) + IF(QT4_FOUND) + ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutomoc" + "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project QtAutomoc + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") + ENDIF() + ENDIF(NOT QT4_FOUND) + ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/ExternalProject" diff --git a/Tests/QtAutomoc/CMakeLists.txt b/Tests/QtAutomoc/CMakeLists.txt new file mode 100644 index 0000000..4a5ff10 --- /dev/null +++ b/Tests/QtAutomoc/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +project(QtAutomoc) + +find_package(Qt4 REQUIRED) + +include(UseQt4) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +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 ) + +set_target_properties(foo codeeditorLib PROPERTIES AUTOMOC TRUE) + +target_link_libraries(foo codeeditorLib ${QT_LIBRARIES} ) diff --git a/Tests/QtAutomoc/calwidget.cpp b/Tests/QtAutomoc/calwidget.cpp new file mode 100644 index 0000000..24f3b4e --- /dev/null +++ b/Tests/QtAutomoc/calwidget.cpp @@ -0,0 +1,424 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #include + + #include "calwidget.h" + + Window::Window() + { + createPreviewGroupBox(); + createGeneralOptionsGroupBox(); + createDatesGroupBox(); + createTextFormatsGroupBox(); + + QGridLayout *layout = new QGridLayout; + layout->addWidget(previewGroupBox, 0, 0); + layout->addWidget(generalOptionsGroupBox, 0, 1); + layout->addWidget(datesGroupBox, 1, 0); + layout->addWidget(textFormatsGroupBox, 1, 1); + layout->setSizeConstraint(QLayout::SetFixedSize); + setLayout(layout); + + previewLayout->setRowMinimumHeight(0, calendar->sizeHint().height()); + previewLayout->setColumnMinimumWidth(0, calendar->sizeHint().width()); + + setWindowTitle(tr("Calendar Widget")); + } + + void Window::localeChanged(int index) + { + calendar->setLocale(localeCombo->itemData(index).toLocale()); + } + + void Window::firstDayChanged(int index) + { + calendar->setFirstDayOfWeek(Qt::DayOfWeek( + firstDayCombo->itemData(index).toInt())); + } + + void Window::selectionModeChanged(int index) + { + calendar->setSelectionMode(QCalendarWidget::SelectionMode( + selectionModeCombo->itemData(index).toInt())); + } + + void Window::horizontalHeaderChanged(int index) + { + calendar->setHorizontalHeaderFormat(QCalendarWidget::HorizontalHeaderFormat( + horizontalHeaderCombo->itemData(index).toInt())); + } + + void Window::verticalHeaderChanged(int index) + { + calendar->setVerticalHeaderFormat(QCalendarWidget::VerticalHeaderFormat( + verticalHeaderCombo->itemData(index).toInt())); + } + + void Window::selectedDateChanged() + { + currentDateEdit->setDate(calendar->selectedDate()); + } + + void Window::minimumDateChanged(const QDate &date) + { + calendar->setMinimumDate(date); + maximumDateEdit->setDate(calendar->maximumDate()); + } + + void Window::maximumDateChanged(const QDate &date) + { + calendar->setMaximumDate(date); + minimumDateEdit->setDate(calendar->minimumDate()); + } + + void Window::weekdayFormatChanged() + { + QTextCharFormat format; + + format.setForeground(qvariant_cast( + weekdayColorCombo->itemData(weekdayColorCombo->currentIndex()))); + calendar->setWeekdayTextFormat(Qt::Monday, format); + calendar->setWeekdayTextFormat(Qt::Tuesday, format); + calendar->setWeekdayTextFormat(Qt::Wednesday, format); + calendar->setWeekdayTextFormat(Qt::Thursday, format); + calendar->setWeekdayTextFormat(Qt::Friday, format); + } + + void Window::weekendFormatChanged() + { + QTextCharFormat format; + + format.setForeground(qvariant_cast( + weekendColorCombo->itemData(weekendColorCombo->currentIndex()))); + calendar->setWeekdayTextFormat(Qt::Saturday, format); + calendar->setWeekdayTextFormat(Qt::Sunday, format); + } + + void Window::reformatHeaders() + { + QString text = headerTextFormatCombo->currentText(); + QTextCharFormat format; + + if (text == tr("Bold")) { + format.setFontWeight(QFont::Bold); + } else if (text == tr("Italic")) { + format.setFontItalic(true); + } else if (text == tr("Green")) { + format.setForeground(Qt::green); + } + calendar->setHeaderTextFormat(format); + } + + void Window::reformatCalendarPage() + { + if (firstFridayCheckBox->isChecked()) { + QDate firstFriday(calendar->yearShown(), calendar->monthShown(), 1); + while (firstFriday.dayOfWeek() != Qt::Friday) + firstFriday = firstFriday.addDays(1); + QTextCharFormat firstFridayFormat; + firstFridayFormat.setForeground(Qt::blue); + calendar->setDateTextFormat(firstFriday, firstFridayFormat); + } + + //May First in Red takes precedence + if (mayFirstCheckBox->isChecked()) { + const QDate mayFirst(calendar->yearShown(), 5, 1); + QTextCharFormat mayFirstFormat; + mayFirstFormat.setForeground(Qt::red); + calendar->setDateTextFormat(mayFirst, mayFirstFormat); + } + } + + void Window::createPreviewGroupBox() + { + previewGroupBox = new QGroupBox(tr("Preview")); + + calendar = new QCalendarWidget; + calendar->setMinimumDate(QDate(1900, 1, 1)); + calendar->setMaximumDate(QDate(3000, 1, 1)); + calendar->setGridVisible(true); + + connect(calendar, SIGNAL(currentPageChanged(int,int)), + this, SLOT(reformatCalendarPage())); + + previewLayout = new QGridLayout; + previewLayout->addWidget(calendar, 0, 0, Qt::AlignCenter); + previewGroupBox->setLayout(previewLayout); + } + + void Window::createGeneralOptionsGroupBox() + { + generalOptionsGroupBox = new QGroupBox(tr("General Options")); + + localeCombo = new QComboBox; + int curLocaleIndex = -1; + int index = 0; + for (int _lang = QLocale::C; _lang <= QLocale::LastLanguage; ++_lang) { + QLocale::Language lang = static_cast(_lang); + QList countries = QLocale::countriesForLanguage(lang); + for (int i = 0; i < countries.count(); ++i) { + QLocale::Country country = countries.at(i); + QString label = QLocale::languageToString(lang); + label += QLatin1Char('/'); + label += QLocale::countryToString(country); + QLocale locale(lang, country); + if (this->locale().language() == lang && this->locale().country() == country) + curLocaleIndex = index; + localeCombo->addItem(label, locale); + ++index; + } + } + if (curLocaleIndex != -1) + localeCombo->setCurrentIndex(curLocaleIndex); + localeLabel = new QLabel(tr("&Locale")); + localeLabel->setBuddy(localeCombo); + + firstDayCombo = new QComboBox; + firstDayCombo->addItem(tr("Sunday"), Qt::Sunday); + firstDayCombo->addItem(tr("Monday"), Qt::Monday); + firstDayCombo->addItem(tr("Tuesday"), Qt::Tuesday); + firstDayCombo->addItem(tr("Wednesday"), Qt::Wednesday); + firstDayCombo->addItem(tr("Thursday"), Qt::Thursday); + firstDayCombo->addItem(tr("Friday"), Qt::Friday); + firstDayCombo->addItem(tr("Saturday"), Qt::Saturday); + + firstDayLabel = new QLabel(tr("Wee&k starts on:")); + firstDayLabel->setBuddy(firstDayCombo); + + selectionModeCombo = new QComboBox; + selectionModeCombo->addItem(tr("Single selection"), + QCalendarWidget::SingleSelection); + selectionModeCombo->addItem(tr("None"), QCalendarWidget::NoSelection); + + selectionModeLabel = new QLabel(tr("&Selection mode:")); + selectionModeLabel->setBuddy(selectionModeCombo); + + gridCheckBox = new QCheckBox(tr("&Grid")); + gridCheckBox->setChecked(calendar->isGridVisible()); + + navigationCheckBox = new QCheckBox(tr("&Navigation bar")); + navigationCheckBox->setChecked(true); + + horizontalHeaderCombo = new QComboBox; + horizontalHeaderCombo->addItem(tr("Single letter day names"), + QCalendarWidget::SingleLetterDayNames); + horizontalHeaderCombo->addItem(tr("Short day names"), + QCalendarWidget::ShortDayNames); + horizontalHeaderCombo->addItem(tr("None"), + QCalendarWidget::NoHorizontalHeader); + horizontalHeaderCombo->setCurrentIndex(1); + + horizontalHeaderLabel = new QLabel(tr("&Horizontal header:")); + horizontalHeaderLabel->setBuddy(horizontalHeaderCombo); + + verticalHeaderCombo = new QComboBox; + verticalHeaderCombo->addItem(tr("ISO week numbers"), + QCalendarWidget::ISOWeekNumbers); + verticalHeaderCombo->addItem(tr("None"), QCalendarWidget::NoVerticalHeader); + + verticalHeaderLabel = new QLabel(tr("&Vertical header:")); + verticalHeaderLabel->setBuddy(verticalHeaderCombo); + + connect(localeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(localeChanged(int))); + connect(firstDayCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(firstDayChanged(int))); + connect(selectionModeCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(selectionModeChanged(int))); + connect(gridCheckBox, SIGNAL(toggled(bool)), + calendar, SLOT(setGridVisible(bool))); + connect(navigationCheckBox, SIGNAL(toggled(bool)), + calendar, SLOT(setNavigationBarVisible(bool))); + connect(horizontalHeaderCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(horizontalHeaderChanged(int))); + connect(verticalHeaderCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(verticalHeaderChanged(int))); + + QHBoxLayout *checkBoxLayout = new QHBoxLayout; + checkBoxLayout->addWidget(gridCheckBox); + checkBoxLayout->addStretch(); + checkBoxLayout->addWidget(navigationCheckBox); + + QGridLayout *outerLayout = new QGridLayout; + outerLayout->addWidget(localeLabel, 0, 0); + outerLayout->addWidget(localeCombo, 0, 1); + outerLayout->addWidget(firstDayLabel, 1, 0); + outerLayout->addWidget(firstDayCombo, 1, 1); + outerLayout->addWidget(selectionModeLabel, 2, 0); + outerLayout->addWidget(selectionModeCombo, 2, 1); + outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2); + outerLayout->addWidget(horizontalHeaderLabel, 4, 0); + outerLayout->addWidget(horizontalHeaderCombo, 4, 1); + outerLayout->addWidget(verticalHeaderLabel, 5, 0); + outerLayout->addWidget(verticalHeaderCombo, 5, 1); + generalOptionsGroupBox->setLayout(outerLayout); + + firstDayChanged(firstDayCombo->currentIndex()); + selectionModeChanged(selectionModeCombo->currentIndex()); + horizontalHeaderChanged(horizontalHeaderCombo->currentIndex()); + verticalHeaderChanged(verticalHeaderCombo->currentIndex()); + } + + void Window::createDatesGroupBox() + { + datesGroupBox = new QGroupBox(tr("Dates")); + + minimumDateEdit = new QDateEdit; + minimumDateEdit->setDisplayFormat("MMM d yyyy"); + minimumDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + minimumDateEdit->setDate(calendar->minimumDate()); + + minimumDateLabel = new QLabel(tr("&Minimum Date:")); + minimumDateLabel->setBuddy(minimumDateEdit); + + currentDateEdit = new QDateEdit; + currentDateEdit->setDisplayFormat("MMM d yyyy"); + currentDateEdit->setDate(calendar->selectedDate()); + currentDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + + currentDateLabel = new QLabel(tr("&Current Date:")); + currentDateLabel->setBuddy(currentDateEdit); + + maximumDateEdit = new QDateEdit; + maximumDateEdit->setDisplayFormat("MMM d yyyy"); + maximumDateEdit->setDateRange(calendar->minimumDate(), + calendar->maximumDate()); + maximumDateEdit->setDate(calendar->maximumDate()); + + maximumDateLabel = new QLabel(tr("Ma&ximum Date:")); + maximumDateLabel->setBuddy(maximumDateEdit); + + connect(currentDateEdit, SIGNAL(dateChanged(QDate)), + calendar, SLOT(setSelectedDate(QDate))); + connect(calendar, SIGNAL(selectionChanged()), + this, SLOT(selectedDateChanged())); + connect(minimumDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(minimumDateChanged(QDate))); + connect(maximumDateEdit, SIGNAL(dateChanged(QDate)), + this, SLOT(maximumDateChanged(QDate))); + + QGridLayout *dateBoxLayout = new QGridLayout; + dateBoxLayout->addWidget(currentDateLabel, 1, 0); + dateBoxLayout->addWidget(currentDateEdit, 1, 1); + dateBoxLayout->addWidget(minimumDateLabel, 0, 0); + dateBoxLayout->addWidget(minimumDateEdit, 0, 1); + dateBoxLayout->addWidget(maximumDateLabel, 2, 0); + dateBoxLayout->addWidget(maximumDateEdit, 2, 1); + dateBoxLayout->setRowStretch(3, 1); + + datesGroupBox->setLayout(dateBoxLayout); + } + + void Window::createTextFormatsGroupBox() + { + textFormatsGroupBox = new QGroupBox(tr("Text Formats")); + + weekdayColorCombo = createColorComboBox(); + weekdayColorCombo->setCurrentIndex( + weekdayColorCombo->findText(tr("Black"))); + + weekdayColorLabel = new QLabel(tr("&Weekday color:")); + weekdayColorLabel->setBuddy(weekdayColorCombo); + + weekendColorCombo = createColorComboBox(); + weekendColorCombo->setCurrentIndex( + weekendColorCombo->findText(tr("Red"))); + + weekendColorLabel = new QLabel(tr("Week&end color:")); + weekendColorLabel->setBuddy(weekendColorCombo); + + headerTextFormatCombo = new QComboBox; + headerTextFormatCombo->addItem(tr("Bold")); + headerTextFormatCombo->addItem(tr("Italic")); + headerTextFormatCombo->addItem(tr("Plain")); + + headerTextFormatLabel = new QLabel(tr("&Header text:")); + headerTextFormatLabel->setBuddy(headerTextFormatCombo); + + firstFridayCheckBox = new QCheckBox(tr("&First Friday in blue")); + + mayFirstCheckBox = new QCheckBox(tr("May &1 in red")); + + connect(weekdayColorCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(weekdayFormatChanged())); + connect(weekendColorCombo, SIGNAL(currentIndexChanged(int)), + this, SLOT(weekendFormatChanged())); + connect(headerTextFormatCombo, SIGNAL(currentIndexChanged(QString)), + this, SLOT(reformatHeaders())); + connect(firstFridayCheckBox, SIGNAL(toggled(bool)), + this, SLOT(reformatCalendarPage())); + connect(mayFirstCheckBox, SIGNAL(toggled(bool)), + this, SLOT(reformatCalendarPage())); + + QHBoxLayout *checkBoxLayout = new QHBoxLayout; + checkBoxLayout->addWidget(firstFridayCheckBox); + checkBoxLayout->addStretch(); + checkBoxLayout->addWidget(mayFirstCheckBox); + + QGridLayout *outerLayout = new QGridLayout; + outerLayout->addWidget(weekdayColorLabel, 0, 0); + outerLayout->addWidget(weekdayColorCombo, 0, 1); + outerLayout->addWidget(weekendColorLabel, 1, 0); + outerLayout->addWidget(weekendColorCombo, 1, 1); + outerLayout->addWidget(headerTextFormatLabel, 2, 0); + outerLayout->addWidget(headerTextFormatCombo, 2, 1); + outerLayout->addLayout(checkBoxLayout, 3, 0, 1, 2); + textFormatsGroupBox->setLayout(outerLayout); + + weekdayFormatChanged(); + weekendFormatChanged(); + reformatHeaders(); + reformatCalendarPage(); + } + +QComboBox *Window::createColorComboBox() + { + QComboBox *comboBox = new QComboBox; + comboBox->addItem(tr("Red"), Qt::red); + comboBox->addItem(tr("Blue"), Qt::blue); + comboBox->addItem(tr("Black"), Qt::black); + comboBox->addItem(tr("Magenta"), Qt::magenta); + return comboBox; + } + +//#include "moc_calwidget.cpp" diff --git a/Tests/QtAutomoc/calwidget.h b/Tests/QtAutomoc/calwidget.h new file mode 100644 index 0000000..8447389 --- /dev/null +++ b/Tests/QtAutomoc/calwidget.h @@ -0,0 +1,121 @@ + /**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#ifndef WINDOW_H +#define WINDOW_H + +#include + + class QCalendarWidget; + class QCheckBox; + class QComboBox; + class QDate; + class QDateEdit; + class QGridLayout; + class QGroupBox; + class QLabel; + + class Window : public QWidget + { + Q_OBJECT + + public: + Window(); + + private slots: + void localeChanged(int index); + void firstDayChanged(int index); + void selectionModeChanged(int index); + void horizontalHeaderChanged(int index); + void verticalHeaderChanged(int index); + void selectedDateChanged(); + void minimumDateChanged(const QDate &date); + void maximumDateChanged(const QDate &date); + void weekdayFormatChanged(); + void weekendFormatChanged(); + void reformatHeaders(); + void reformatCalendarPage(); + + private: + void createPreviewGroupBox(); + void createGeneralOptionsGroupBox(); + void createDatesGroupBox(); + void createTextFormatsGroupBox(); + QComboBox *createColorComboBox(); + + QGroupBox *previewGroupBox; + QGridLayout *previewLayout; + QCalendarWidget *calendar; + + QGroupBox *generalOptionsGroupBox; + QLabel *localeLabel; + QLabel *firstDayLabel; + QLabel *selectionModeLabel; + QLabel *horizontalHeaderLabel; + QLabel *verticalHeaderLabel; + QComboBox *localeCombo; + QComboBox *firstDayCombo; + QComboBox *selectionModeCombo; + QCheckBox *gridCheckBox; + QCheckBox *navigationCheckBox; + QComboBox *horizontalHeaderCombo; + QComboBox *verticalHeaderCombo; + + QGroupBox *datesGroupBox; + QLabel *currentDateLabel; + QLabel *minimumDateLabel; + QLabel *maximumDateLabel; + QDateEdit *currentDateEdit; + QDateEdit *minimumDateEdit; + QDateEdit *maximumDateEdit; + + QGroupBox *textFormatsGroupBox; + QLabel *weekdayColorLabel; + QLabel *weekendColorLabel; + QLabel *headerTextFormatLabel; + QComboBox *weekdayColorCombo; + QComboBox *weekendColorCombo; + QComboBox *headerTextFormatCombo; + + QCheckBox *firstFridayCheckBox; + QCheckBox *mayFirstCheckBox; + }; + + #endif diff --git a/Tests/QtAutomoc/codeeditor.cpp b/Tests/QtAutomoc/codeeditor.cpp new file mode 100644 index 0000000..01da062 --- /dev/null +++ b/Tests/QtAutomoc/codeeditor.cpp @@ -0,0 +1,153 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #include + + #include "codeeditor.h" + + + CodeEditor::CodeEditor(QWidget *parent) : QPlainTextEdit(parent) + { + lineNumberArea = new LineNumberArea(this); + + connect(this, SIGNAL(blockCountChanged(int)), this, SLOT(updateLineNumberAreaWidth(int))); + connect(this, SIGNAL(updateRequest(QRect,int)), this, SLOT(updateLineNumberArea(QRect,int))); + connect(this, SIGNAL(cursorPositionChanged()), this, SLOT(highlightCurrentLine())); + + updateLineNumberAreaWidth(0); + highlightCurrentLine(); + } + + + + int CodeEditor::lineNumberAreaWidth() + { + int digits = 1; + int max = qMax(1, blockCount()); + while (max >= 10) { + max /= 10; + ++digits; + } + + int space = 3 + fontMetrics().width(QLatin1Char('9')) * digits; + + return space; + } + + + + void CodeEditor::updateLineNumberAreaWidth(int /* newBlockCount */) + { + setViewportMargins(lineNumberAreaWidth(), 0, 0, 0); + } + + + + void CodeEditor::updateLineNumberArea(const QRect &rect, int dy) + { + if (dy) + lineNumberArea->scroll(0, dy); + else + lineNumberArea->update(0, rect.y(), lineNumberArea->width(), rect.height()); + + if (rect.contains(viewport()->rect())) + updateLineNumberAreaWidth(0); + } + + + + void CodeEditor::resizeEvent(QResizeEvent *e) + { + QPlainTextEdit::resizeEvent(e); + + QRect cr = contentsRect(); + lineNumberArea->setGeometry(QRect(cr.left(), cr.top(), lineNumberAreaWidth(), cr.height())); + } + + + + void CodeEditor::highlightCurrentLine() + { + QList extraSelections; + + if (!isReadOnly()) { + QTextEdit::ExtraSelection selection; + + QColor lineColor = QColor(Qt::yellow).lighter(160); + + selection.format.setBackground(lineColor); + selection.format.setProperty(QTextFormat::FullWidthSelection, true); + selection.cursor = textCursor(); + selection.cursor.clearSelection(); + extraSelections.append(selection); + } + + setExtraSelections(extraSelections); + } + + + + void CodeEditor::lineNumberAreaPaintEvent(QPaintEvent *event) + { + QPainter painter(lineNumberArea); + painter.fillRect(event->rect(), Qt::lightGray); + + + QTextBlock block = firstVisibleBlock(); + int blockNumber = block.blockNumber(); + int top = (int) blockBoundingGeometry(block).translated(contentOffset()).top(); + int bottom = top + (int) blockBoundingRect(block).height(); + + while (block.isValid() && top <= event->rect().bottom()) { + if (block.isVisible() && bottom >= event->rect().top()) { + QString number = QString::number(blockNumber + 1); + painter.setPen(Qt::black); + painter.drawText(0, top, lineNumberArea->width(), fontMetrics().height(), + Qt::AlignRight, number); + } + + block = block.next(); + top = bottom; + bottom = top + (int) blockBoundingRect(block).height(); + ++blockNumber; + } + } + +#include "codeeditor.moc" diff --git a/Tests/QtAutomoc/codeeditor.h b/Tests/QtAutomoc/codeeditor.h new file mode 100644 index 0000000..56e9e792 --- /dev/null +++ b/Tests/QtAutomoc/codeeditor.h @@ -0,0 +1,99 @@ + /**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + + #ifndef CODEEDITOR_H + #define CODEEDITOR_H + + #include + #include + + class QPaintEvent; + class QResizeEvent; + class QSize; + class QWidget; + + class LineNumberArea; + + + class CodeEditor : public QPlainTextEdit + { + Q_OBJECT + + public: + CodeEditor(QWidget *parent = 0); + + void lineNumberAreaPaintEvent(QPaintEvent *event); + int lineNumberAreaWidth(); + + protected: + void resizeEvent(QResizeEvent *event); + + private slots: + void updateLineNumberAreaWidth(int newBlockCount); + void highlightCurrentLine(); + void updateLineNumberArea(const QRect &, int); + + private: + QWidget *lineNumberArea; + }; + + + class LineNumberArea : public QWidget + { + public: + LineNumberArea(CodeEditor *editor) : QWidget(editor) { + codeEditor = editor; + } + + QSize sizeHint() const { + return QSize(codeEditor->lineNumberAreaWidth(), 0); + } + + protected: + void paintEvent(QPaintEvent *event) { + codeEditor->lineNumberAreaPaintEvent(event); + } + + private: + CodeEditor *codeEditor; + }; + + + #endif diff --git a/Tests/QtAutomoc/main.cpp b/Tests/QtAutomoc/main.cpp new file mode 100644 index 0000000..7bf4a5d --- /dev/null +++ b/Tests/QtAutomoc/main.cpp @@ -0,0 +1,58 @@ +/**************************************************************************** + ** + ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). + ** All rights reserved. + ** Contact: Nokia Corporation (qt-info@nokia.com) + ** + ** This file is part of the examples of the Qt Toolkit. + ** + ** $QT_BEGIN_LICENSE:BSD$ + ** You may use this file under the terms of the BSD license as follows: + ** + ** "Redistribution and use in source and binary forms, with or without + ** modification, are permitted provided that the following conditions are + ** met: + ** * Redistributions of source code must retain the above copyright + ** notice, this list of conditions and the following disclaimer. + ** * Redistributions in binary form must reproduce the above copyright + ** notice, this list of conditions and the following disclaimer in + ** the documentation and/or other materials provided with the + ** distribution. + ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor + ** the names of its contributors may be used to endorse or promote + ** products derived from this software without specific prior written + ** permission. + ** + ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." + ** $QT_END_LICENSE$ + ** + ****************************************************************************/ + +#include + +#include "codeeditor.h" +#include "calwidget.h" + +int main(int argv, char **args) +{ + QApplication app(argv, args); + + CodeEditor editor; + editor.setWindowTitle(QObject::tr("Code Editor Example")); + editor.show(); + + Window w; + w.show(); + + return app.exec(); +} -- cgit v0.12 From 77a5c6e0d8c995f56fa1248443de0260384acca3 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 22:05:33 +0200 Subject: Add documentation for AUTOMOC, add initialization via CMAKE_AUTOMOC Alex --- Source/cmDocumentVariables.cxx | 9 +++++++++ Source/cmTarget.cxx | 25 ++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Source/cmDocumentVariables.cxx b/Source/cmDocumentVariables.cxx index ebe2988..26125d9 100644 --- a/Source/cmDocumentVariables.cxx +++ b/Source/cmDocumentVariables.cxx @@ -1085,6 +1085,15 @@ void cmDocumentVariables::DefineVariables(cmake* cm) "Variables that Control the Build"); cm->DefineProperty + ("CMAKE_AUTOMOC", cmProperty::VARIABLE, + "Whether to handle moc automatically for Qt targets.", + "This variable is used to initialize the " + "AUTOMOC property on all the targets. " + "See that target property for additional information.", + false, + "Variables that Control the Build"); + + cm->DefineProperty ("CMAKE_DEBUG_POSTFIX", cmProperty::VARIABLE, "See variable CMAKE__POSTFIX.", "This variable is a special case of the more-general " diff --git a/Source/cmTarget.cxx b/Source/cmTarget.cxx index 17a26cc..4969b65 100644 --- a/Source/cmTarget.cxx +++ b/Source/cmTarget.cxx @@ -115,6 +115,28 @@ cmTarget::cmTarget() void cmTarget::DefineProperties(cmake *cm) { cm->DefineProperty + ("AUTOMOC", cmProperty::TARGET, + "Should the target be processed with automoc (for Qt projects).", + "AUTOMOC is a boolean specifying whether CMake will handle " + "the Qt moc preprocessor automatically, i.e. without having to use " + "the QT4_WRAP_CPP() macro. Currently Qt4 is supported. " + "When this property is set to TRUE, CMake will scan the source files " + "at build time and invoke moc accordingly. " + "If an #include statement like #include \"moc_foo.cpp\" is found, " + "the Q_OBJECT class declaration is expected in the header, and moc is " + "run on the header file. " + "If an #include statement like #include \"foo.moc\" is found, " + "then a Q_OBJECT is expected in the current source file and moc " + "is run on the file itself. " + "Additionally, all header files are parsed for Q_OBJECT macros, " + "and if found, moc is also executed on those files. The resulting " + "moc files, which are not included as shown above in any of the source " + "files are included in a generated _automoc.cpp file, " + "which is compiled as part of the target." + "This property is initialized by the value of the variable " + "CMAKE_AUTOMOC if it is set when a target is created."); + + cm->DefineProperty ("BUILD_WITH_INSTALL_RPATH", cmProperty::TARGET, "Should build tree targets have install tree rpaths.", "BUILD_WITH_INSTALL_RPATH is a boolean specifying whether to link " @@ -1118,6 +1140,7 @@ void cmTarget::SetMakefile(cmMakefile* mf) this->SetPropertyDefault("RUNTIME_OUTPUT_DIRECTORY", 0); this->SetPropertyDefault("Fortran_MODULE_DIRECTORY", 0); this->SetPropertyDefault("OSX_ARCHITECTURES", 0); + this->SetPropertyDefault("AUTOMOC", 0); // Collect the set of configuration types. std::vector configNames; @@ -1420,7 +1443,7 @@ bool cmTargetTraceDependencies::IsUtility(std::string const& dep) // the fact that the name matched a target was just a coincidence. if(cmSystemTools::FileIsFullPath(dep.c_str())) { - if(t->GetType() >= cmTarget::EXECUTABLE && + if(t->GetType() >= cmTarget::EXECUTABLE && t->GetType() <= cmTarget::MODULE_LIBRARY) { // This is really only for compatibility so we do not need to -- cgit v0.12 From 2963d0b078bf9302cab37d9def16776bde45dd67 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Tue, 16 Aug 2011 23:48:01 +0200 Subject: Fix logic which decides when to execute automoc test Alex --- Tests/CMakeLists.txt | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 30549b6..7bf4ddb 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -842,22 +842,23 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ IF(NOT QT4_FOUND) FIND_PACKAGE(Qt4) - IF(QT4_FOUND) - ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/QtAutomoc" - "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --build-generator ${CMAKE_TEST_GENERATOR} - --build-project QtAutomoc - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --force-new-ctest-process - --test-command ${CMAKE_CTEST_COMMAND} -V - ) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") - ENDIF() ENDIF(NOT QT4_FOUND) + IF(QT4_FOUND) + ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutomoc" + "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project QtAutomoc + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") + ENDIF() + ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND} --build-and-test "${CMake_SOURCE_DIR}/Tests/ExternalProject" -- cgit v0.12 From 7e6d84568c8c390fc53cbaaf70f6839e3cf4ebd7 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 17 Aug 2011 00:04:47 +0200 Subject: Automoc.cmake is not needed anymore (actually I thought I had already removed it again) Alex --- Modules/Automoc.cmake | 158 -------------------------------------------------- 1 file changed, 158 deletions(-) delete mode 100644 Modules/Automoc.cmake diff --git a/Modules/Automoc.cmake b/Modules/Automoc.cmake deleted file mode 100644 index 1e77c96..0000000 --- a/Modules/Automoc.cmake +++ /dev/null @@ -1,158 +0,0 @@ - -# AUTOMOC4_MOC_HEADERS( header1.h header2.h ...) -# Use this to add more header files to be processed with automoc4. -# -# AUTOMOC4_ADD_EXECUTABLE( src1 src2 ...) -# This macro does the same as ADD_EXECUTABLE, but additionally -# adds automoc4 handling for all source files. -# -# AUTOMOC4_ADD_LIBRARY( src1 src2 ...) -# This macro does the same as ADD_LIBRARY, but additionally -# adds automoc4 handling for all source files. - -# Internal helper macro, may change or be removed anytime: -# _ADD_AUTOMOC4_TARGET( ) -# -# Since version 0.9.88: -# The following two macros are only to be used for KDE4 projects -# and do something which makes sure automoc4 works for KDE. Don't -# use them anywhere else. See kdelibs/cmake/modules/KDE4Macros.cmake. -# _AUTOMOC4_KDE4_PRE_TARGET_HANDLING( ) -# _AUTOMOC4_KDE4_POST_TARGET_HANDLING() - -# Copyright (C) 2007 Matthias Kretz -# Copyright (C) 2008-2009 Alexander Neundorf -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -macro (AUTOMOC4_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 "AUTOMOC4_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_.cpp file using automoc4 - # and add it to the target - if(_headers_to_moc) - set(_automoc4_headers_${_target_NAME} "${_headers_to_moc}") - endif(_headers_to_moc) -endmacro (AUTOMOC4_MOC_HEADERS) - - -macro(_ADD_AUTOMOC4_TARGET _target_NAME _SRCS) - set(_moc_files) - set(_moc_headers) - - # first list all explicitly set headers - foreach(_header_to_moc ${_automoc4_headers_${_target_NAME}} ) - get_filename_component(_abs_header ${_header_to_moc} ABSOLUTE) - list(APPEND _moc_headers ${_abs_header}) - endforeach(_header_to_moc) - - # 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" OR _suffix STREQUAL ".mm") - list(APPEND _moc_files ${_abs_current_FILE}) - endif(_suffix STREQUAL ".cpp" OR _suffix STREQUAL ".cc" OR _suffix STREQUAL ".cxx" OR _suffix STREQUAL ".C" OR _suffix STREQUAL ".mm") - endif(NOT _generated AND NOT _skip) - endforeach (_current_FILE) - - if(_moc_files OR _moc_headers) - set(_automoc_source "${CMAKE_CURRENT_BINARY_DIR}/${_target_NAME}.cpp") - get_directory_property(_moc_incs INCLUDE_DIRECTORIES) - get_directory_property(_moc_defs DEFINITIONS) - get_directory_property(_moc_cdefs COMPILE_DEFINITIONS) - - # configure_file replaces _moc_files, _moc_incs, _moc_cdefs and _moc_defs - set(_automocTargetDir "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target_NAME}.dir/" ) - set(AM_TARGET_NAME ${_target_NAME}) - configure_file(${CMAKE_ROOT}/Modules/AutomocInfo.cmake.in ${_automocTargetDir}/AutomocInfo.cmake @ONLY) - - add_custom_target(${_target_NAME} - COMMAND ${CMAKE_COMMAND} -E cmake_automoc "${_automocTargetDir}" ) - - set_source_files_properties(${_automoc_source} PROPERTIES GENERATED TRUE) - get_directory_property(_extra_clean_files ADDITIONAL_MAKE_CLEAN_FILES) - list(APPEND _extra_clean_files "${_automoc_source}") - set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${_extra_clean_files}") - set(${_SRCS} ${_automoc_source} ${${_SRCS}}) - endif(_moc_files OR _moc_headers) -endmacro(_ADD_AUTOMOC4_TARGET) - - -macro(AUTOMOC4_ADD_EXECUTABLE _target_NAME) - set(_SRCS ${ARGN}) - - set(_add_executable_param) - foreach(_argName "WIN32" "MACOSX_BUNDLE" "EXCLUDE_FROM_ALL") - list(FIND _SRCS ${_argName} _index) - if(_index GREATER -1) - list(APPEND _add_executable_param ${_argName}) - list(REMOVE_AT _SRCS ${_index}) - endif(_index GREATER -1) - endforeach(_argName) - - _add_automoc4_target("${_target_NAME}_automoc" _SRCS) - add_executable(${_target_NAME} ${_add_executable_param} ${_SRCS}) - add_dependencies(${_target_NAME} "${_target_NAME}_automoc") - -endmacro(AUTOMOC4_ADD_EXECUTABLE) - - -macro(AUTOMOC4_ADD_LIBRARY _target_NAME) - set(_SRCS ${ARGN}) - - set(_add_executable_param) - foreach(_argName "STATIC" "SHARED" "MODULE" "EXCLUDE_FROM_ALL") - list(FIND _SRCS ${_argName} _index) - if(_index GREATER -1) - list(APPEND _add_executable_param ${_argName}) - list(REMOVE_AT _SRCS ${_index}) - endif(_index GREATER -1) - endforeach(_argName) - - _add_automoc4_target("${_target_NAME}_automoc" _SRCS) - add_library(${_target_NAME} ${_add_executable_param} ${_SRCS}) - add_dependencies(${_target_NAME} "${_target_NAME}_automoc") -endmacro(AUTOMOC4_ADD_LIBRARY) - - -macro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING _target _srcs) - _add_automoc4_target("${_target}_automoc" ${_srcs}) -endmacro(_AUTOMOC4_KDE4_PRE_TARGET_HANDLING) - - -macro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING _target) - add_dependencies(${_target} "${_target}_automoc") -endmacro(_AUTOMOC4_KDE4_POST_TARGET_HANDLING) -- cgit v0.12 From add30e9008fcb4d5277692958aac7f933539f983 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 17 Aug 2011 00:39:21 +0200 Subject: Fix build: non-void function must return a value Alex --- Source/cmQtAutomoc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index e8c4baa..7e50064 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -168,7 +168,7 @@ bool cmQtAutomoc::Run(const char* targetDirectory) delete gg; gg = NULL; makefile = NULL; - + return true; } -- cgit v0.12 From afb3edc18149f48be6e1690c7d9b1c8f6816a056 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 17 Aug 2011 00:49:12 +0200 Subject: Fix warnings Alex --- Source/cmQtAutomoc.cxx | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 7e50064..df09f37 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -69,10 +69,9 @@ void cmQtAutomoc::SetupAutomocTarget(cmTarget* target) std::string automocComment = "Automoc for target "; automocComment += targetName; - cmTarget* mocTarget = makefile->AddUtilityCommand(automocTargetName.c_str(), - true, - workingDirectory.c_str(), depends, - commandLines, false, automocComment.c_str()); + makefile->AddUtilityCommand(automocTargetName.c_str(), true, + workingDirectory.c_str(), depends, + commandLines, false, automocComment.c_str()); target->AddUtility(automocTargetName.c_str()); // configure a file to get all information to automoc at buildtime: @@ -713,9 +712,11 @@ bool cmQtAutomoc::GenerateMoc(const std::string& sourceFile, if (this->Verbose) { - for(int i=0; i::const_iterator cmdIt = command.begin(); + cmdIt != command.end(); + ++cmdIt) { - std::cout << command[i] << " "; + std::cout << *cmdIt << " "; } std::cout << std::endl; } -- cgit v0.12 From 71c29d11b3d089dbc9fb403ceed7999419615810 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Wed, 17 Aug 2011 17:08:50 +0200 Subject: Fix bootstrap test with automoc Alex --- Source/cmGlobalGenerator.cxx | 2 ++ Source/cmake.cxx | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index 3016f5a..27acf98 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -958,6 +958,7 @@ bool cmGlobalGenerator::CheckTargets() //---------------------------------------------------------------------------- void cmGlobalGenerator::CreateAutomocTargets() { +#ifdef CMAKE_BUILD_WITH_CMAKE for(unsigned int i=0; i < this->LocalGenerators.size(); ++i) { cmTargets& targets = @@ -979,6 +980,7 @@ void cmGlobalGenerator::CreateAutomocTargets() } } } +#endif } diff --git a/Source/cmake.cxx b/Source/cmake.cxx index c5eff1c..99b1844 100644 --- a/Source/cmake.cxx +++ b/Source/cmake.cxx @@ -1573,14 +1573,13 @@ int cmake::ExecuteCMakeCommand(std::vector& args) { return cmake::ExecuteEchoColor(args); } -#endif - else if (args[1] == "cmake_automoc") { cmQtAutomoc automoc; automoc.Run(args[2].c_str()); return 0; } +#endif // Tar files else if (args[1] == "tar" && args.size() > 3) -- cgit v0.12 From 678e12448140017f7b64c6307afb53b500910f46 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 18 Aug 2011 00:16:02 +0200 Subject: Only enable the automoc test after checking that Qt4 works On some systems which contribute nightly builds there were strange errors which seemed to hint that the installed Qt4 is not usable/ not usable with this compiler. So first check whether it works, and only if this was successful, enable the test. Alex --- Tests/CMakeLists.txt | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index 7bf4ddb..b1db40d 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -845,18 +845,37 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ ENDIF(NOT QT4_FOUND) IF(QT4_FOUND) - ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} - --build-and-test - "${CMake_SOURCE_DIR}/Tests/QtAutomoc" - "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --build-generator ${CMAKE_TEST_GENERATOR} - --build-project QtAutomoc - --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} - --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" - --force-new-ctest-process - --test-command ${CMAKE_CTEST_COMMAND} -V - ) - LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") + # test whether the Qt4 which has been found works, on some machines + # which run nightly builds there were errors like "wrong file format" + # for libQtCore.so. So first check it works, and only if it does add + # the automoc test. + INCLUDE(CheckCXXSourceCompiles) + SET(_save_CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES}") + SET(_save_CMAKE_REQUIRED_LIBRARIES "${CMAKE_REQUIRED_LIBRARIES}") + + SET(CMAKE_REQUIRED_INCLUDES ${QT_INCLUDES}) + SET(CMAKE_REQUIRED_LIBRARIES ${QT_QTCORE_LIBRARIES}) + + CHECK_CXX_SOURCE_COMPILES("#include \n int main() {return (qApp == 0 ? 0 : 1); }\n" + QT4_WORKS_FOR_AUTOMOC_TEST) + + SET(CMAKE_REQUIRED_INCLUDES "${_save_CMAKE_REQUIRED_INCLUDES}") + SET(CMAKE_REQUIRED_LIBRARIES "${_save_CMAKE_REQUIRED_LIBRARIES}") + + IF(QT4_WORKS_FOR_AUTOMOC_TEST) + ADD_TEST(QtAutomoc ${CMAKE_CTEST_COMMAND} + --build-and-test + "${CMake_SOURCE_DIR}/Tests/QtAutomoc" + "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --build-generator ${CMAKE_TEST_GENERATOR} + --build-project QtAutomoc + --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} + --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" + --force-new-ctest-process + --test-command ${CMAKE_CTEST_COMMAND} -V + ) + LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") + ENDIF() ENDIF() ADD_TEST(ExternalProject ${CMAKE_CTEST_COMMAND} -- cgit v0.12 From 1879bcc09cb180efec041ccd5b1e42c47b790084 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 18 Aug 2011 18:53:14 +0200 Subject: Fix build: use std::ios::out|ios::trunc instead of std::ios_base::out Alex --- Source/cmQtAutomoc.cxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index df09f37..7dd450e 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -245,7 +245,7 @@ void cmQtAutomoc::WriteOldMocDefinitionsFile(const char* targetDirectory) std::fstream outfile; outfile.open(filename.c_str(), - std::ios_base::out | std::ios_base::trunc); + std::ios::out | std::ios::trunc); outfile << "set(AM_OLD_MOC_DEFINITIONS \"" << this->Join(this->MocDefinitions, ' ') << "\")\n"; @@ -477,7 +477,7 @@ bool cmQtAutomoc::RunAutomocQt4() // source file that includes all remaining moc files (_automoc.cpp file) std::fstream outfile; outfile.open(this->OutMocCppFilename.c_str(), - std::ios_base::out | std::ios_base::trunc); + std::ios::out | std::ios::trunc); outfile << automocSource; outfile.close(); -- cgit v0.12 From 71165e943edb3ba80a0533a640ff6abffb4bcf64 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 18 Aug 2011 19:34:49 +0200 Subject: Silence warning in automoc: use long instead of int Alex --- Source/cmQtAutomoc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index 7dd450e..e5dc3df 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -519,7 +519,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - int matchOffset = 0; + long matchOffset = 0; if (!mocIncludeRegExp.find(contentsString.c_str())) { // no moc #include, look whether we need to create a moc from -- cgit v0.12 From e78ce44b3598807bd401494d484601d9f43bd8b4 Mon Sep 17 00:00:00 2001 From: Alex Neundorf Date: Thu, 18 Aug 2011 19:35:41 +0200 Subject: Fix automoc with VS builds: apply patch from Bill This patch moves the creation of VS GUIDs from the final pass to AddHelperCommands() and should fix the failing automoc tests with VS. Alex --- Source/cmGlobalVisualStudio7Generator.cxx | 12 --------- Source/cmGlobalVisualStudio7Generator.h | 3 --- Source/cmLocalVisualStudio7Generator.cxx | 44 +++++++++++++++---------------- Source/cmLocalVisualStudio7Generator.h | 1 - 4 files changed, 21 insertions(+), 39 deletions(-) diff --git a/Source/cmGlobalVisualStudio7Generator.cxx b/Source/cmGlobalVisualStudio7Generator.cxx index 51b8918..84e7f1b 100644 --- a/Source/cmGlobalVisualStudio7Generator.cxx +++ b/Source/cmGlobalVisualStudio7Generator.cxx @@ -739,18 +739,6 @@ void cmGlobalVisualStudio7Generator entry.Full = ""; } -// make sure "special" targets have GUID's -void cmGlobalVisualStudio7Generator::Configure() -{ - cmGlobalGenerator::Configure(); - this->CreateGUID("ALL_BUILD"); - this->CreateGUID("INSTALL"); - this->CreateGUID("RUN_TESTS"); - this->CreateGUID("EDIT_CACHE"); - this->CreateGUID("REBUILD_CACHE"); - this->CreateGUID("PACKAGE"); -} - //---------------------------------------------------------------------------- void cmGlobalVisualStudio7Generator diff --git a/Source/cmGlobalVisualStudio7Generator.h b/Source/cmGlobalVisualStudio7Generator.h index b6c84e8..7f19d83 100644 --- a/Source/cmGlobalVisualStudio7Generator.h +++ b/Source/cmGlobalVisualStudio7Generator.h @@ -80,9 +80,6 @@ public: void CreateGUID(const char* name); std::string GetGUID(const char* name); - ///! do configure step - virtual void Configure(); - /** Append the subdirectory for the given configuration. */ virtual void AppendDirectoryForConfig(const char* prefix, const char* config, diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index 3e76f59..372e644 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -68,6 +68,27 @@ void cmLocalVisualStudio7Generator::AddHelperCommands() lang.insert("DEF"); lang.insert("Fortran"); this->CreateCustomTargetsAndCommands(lang); + + // Now create GUIDs for targets + cmTargets &tgts = this->Makefile->GetTargets(); + + cmGlobalVisualStudio7Generator* gg = + static_cast(this->GlobalGenerator); + for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) + { + const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT"); + if(path) + { + this->ReadAndStoreExternalGUID( + l->second.GetName(), path); + } + else + { + gg->CreateGUID(l->first.c_str()); + } + } + + this->FixGlobalTargets(); } @@ -2021,29 +2042,6 @@ void cmLocalVisualStudio7Generator::ReadAndStoreExternalGUID( } -void cmLocalVisualStudio7Generator::ConfigureFinalPass() -{ - cmLocalGenerator::ConfigureFinalPass(); - cmTargets &tgts = this->Makefile->GetTargets(); - - cmGlobalVisualStudio7Generator* gg = - static_cast(this->GlobalGenerator); - for(cmTargets::iterator l = tgts.begin(); l != tgts.end(); l++) - { - const char* path = l->second.GetProperty("EXTERNAL_MSPROJECT"); - if(path) - { - this->ReadAndStoreExternalGUID( - l->second.GetName(), path); - } - else - { - gg->CreateGUID(l->first.c_str()); - } - } - -} - //---------------------------------------------------------------------------- std::string cmLocalVisualStudio7Generator ::GetTargetDirectory(cmTarget const& target) const diff --git a/Source/cmLocalVisualStudio7Generator.h b/Source/cmLocalVisualStudio7Generator.h index 4fdbc58..d1b5b00 100644 --- a/Source/cmLocalVisualStudio7Generator.h +++ b/Source/cmLocalVisualStudio7Generator.h @@ -57,7 +57,6 @@ public: void SetVersion8() {this->Version = 8;} void SetVersion9() {this->Version = 9;} void SetPlatformName(const char* n) { this->PlatformName = n;} - virtual void ConfigureFinalPass(); void GetTargetObjectFileDirectories(cmTarget* target, std::vector& dirs); -- cgit v0.12 From b00463f06c80529f02c489872458345790f6cd48 Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 19 Aug 2011 12:30:36 -0400 Subject: QtAutomoc test: Pass QT_QMAKE_EXECUTABLE ...in case qmake is not in the PATH --- Tests/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index b1db40d..9d8a091 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -872,6 +872,7 @@ ${CMake_BINARY_DIR}/bin/cmake -DVERSION=master -P ${CMake_SOURCE_DIR}/Utilities/ --build-makeprogram ${CMAKE_TEST_MAKEPROGRAM} --build-exe-dir "${CMake_BINARY_DIR}/Tests/QtAutomoc" --force-new-ctest-process + --build-options -DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} --test-command ${CMAKE_CTEST_COMMAND} -V ) LIST(APPEND TEST_BUILD_DIRS "${CMake_BINARY_DIR}/Tests/QtAutomoc") -- cgit v0.12 From 920a046015799a14374e5c69072aa14f2723fda0 Mon Sep 17 00:00:00 2001 From: David Cole Date: Fri, 19 Aug 2011 14:16:53 -0400 Subject: QtAutomoc: Eliminate compiler warning --- Source/cmQtAutomoc.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Source/cmQtAutomoc.cxx b/Source/cmQtAutomoc.cxx index e5dc3df..ff96e5b 100644 --- a/Source/cmQtAutomoc.cxx +++ b/Source/cmQtAutomoc.cxx @@ -519,7 +519,7 @@ void cmQtAutomoc::ParseCppFile(const std::string& absFilename, const std::string absPath = cmsys::SystemTools::GetFilenamePath( cmsys::SystemTools::GetRealPath(absFilename.c_str())) + '/'; - long matchOffset = 0; + std::string::size_type matchOffset = 0; if (!mocIncludeRegExp.find(contentsString.c_str())) { // no moc #include, look whether we need to create a moc from -- cgit v0.12