diff options
Diffstat (limited to 'Source/cmQtAutoGenerators.cxx')
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 171 |
1 files changed, 129 insertions, 42 deletions
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index c79f66d..65ea048 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -280,10 +280,10 @@ cmQtAutoGenerators::cmQtAutoGenerators() } // Moc macro filters - this->MocMacroFilters[0].first = "Q_OBJECT"; - this->MocMacroFilters[0].second.compile("[\n][ \t]*Q_OBJECT[^a-zA-Z0-9_]"); - this->MocMacroFilters[1].first = "Q_GADGET"; - this->MocMacroFilters[1].second.compile("[\n][ \t]*Q_GADGET[^a-zA-Z0-9_]"); + this->MocMacroFilters.push_back( + MocMacroFilter("Q_OBJECT", "[\n][ \t]*{?[ \t]*Q_OBJECT[^a-zA-Z0-9_]")); + this->MocMacroFilters.push_back( + MocMacroFilter("Q_GADGET", "[\n][ \t]*{?[ \t]*Q_GADGET[^a-zA-Z0-9_]")); // Precompile regular expressions this->MocRegExpInclude.compile( @@ -364,6 +364,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( return false; } + // -- Meta + InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); + // - Old settings file { this->SettingsFile = cmSystemTools::CollapseFullPath(targetDirectory); @@ -373,9 +376,6 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( this->SettingsFile += ".cmake"; } - // -- Meta - InfoGetConfig(makefile, "AM_CONFIG_SUFFIX", config, this->ConfigSuffix); - // - Files and directories InfoGet(makefile, "AM_CMAKE_SOURCE_DIR", this->ProjectSourceDir); InfoGet(makefile, "AM_CMAKE_BINARY_DIR", this->ProjectBinaryDir); @@ -400,7 +400,6 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_QT_UIC_EXECUTABLE", this->UicExecutable); InfoGet(makefile, "AM_QT_RCC_EXECUTABLE", this->RccExecutable); - InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd); // Check Qt version if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { this->LogError("AutoGen: Error: Unsupported Qt version: " + @@ -425,6 +424,16 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGet(makefile, "AM_MOC_OPTIONS", this->MocOptions); InfoGet(makefile, "AM_MOC_RELAXED_MODE", this->MocRelaxedMode); { + std::vector<std::string> MocMacroNames; + InfoGet(makefile, "AM_MOC_MACRO_NAMES", MocMacroNames); + for (std::vector<std::string>::const_iterator dit = + MocMacroNames.begin(); + dit != MocMacroNames.end(); ++dit) { + this->MocMacroFilters.push_back( + MocMacroFilter(*dit, "[^a-zA-Z0-9_]" + *dit + "[^a-zA-Z0-9_]")); + } + } + { std::vector<std::string> mocDependFilters; InfoGet(makefile, "AM_MOC_DEPEND_FILTERS", mocDependFilters); // Insert Q_PLUGIN_METADATA dependency filter @@ -450,6 +459,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( return false; } } + InfoGet(makefile, "AM_MOC_PREDEFS_CMD", this->MocPredefsCmd); } // - Uic @@ -634,9 +644,7 @@ bool cmQtAutoGenerators::SettingsFileWrite() void cmQtAutoGenerators::Init(cmMakefile* makefile) { // Mocs compilation file - this->MocCompFileRel = "mocs_compilation"; - this->MocCompFileRel += this->ConfigSuffix; - this->MocCompFileRel += ".cpp"; + this->MocCompFileRel = "mocs_compilation.cpp"; this->MocCompFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocCompFileRel); @@ -647,7 +655,9 @@ void cmQtAutoGenerators::Init(cmMakefile* makefile) // Moc predefs file if (!this->MocPredefsCmd.empty()) { - this->MocPredefsFileRel = "moc_predefs.h"; + this->MocPredefsFileRel = "moc_predefs"; + this->MocPredefsFileRel += this->ConfigSuffix; + this->MocPredefsFileRel += ".h"; this->MocPredefsFileAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->MocPredefsFileRel); } @@ -722,10 +732,10 @@ bool cmQtAutoGenerators::RunAutogen() // 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 mocs_compilation_$<CONFIG>.cpp file anymore. + // may not be included in the mocs_compilation.cpp file anymore. // OTOH if there's a header containing Q_OBJECT where no corresponding // moc file is included anywhere a moc_<filename>.cpp file is created and - // included in the mocs_compilation_$<CONFIG>.cpp file. + // included in the mocs_compilation.cpp file. // Create AUTOGEN include directory { @@ -798,8 +808,10 @@ bool cmQtAutoGenerators::RunAutogen() bool cmQtAutoGenerators::MocRequired(const std::string& contentText, std::string* macroName) { - for (unsigned int ii = 0; ii != cmArraySize(this->MocMacroFilters); ++ii) { - MocMacroFilter& filter = this->MocMacroFilters[ii]; + for (std::vector<MocMacroFilter>::iterator fit = + this->MocMacroFilters.begin(); + fit != this->MocMacroFilters.end(); ++fit) { + MocMacroFilter& filter = *fit; // Run a simple find string operation before the expensive // regular expression check if (contentText.find(filter.first) != std::string::npos) { @@ -1253,7 +1265,9 @@ bool cmQtAutoGenerators::MocGenerateAll( if (!this->MocPredefsCmd.empty()) { if (this->MocSettingsChanged || FileAbsentOrOlder(this->MocPredefsFileAbs, this->SettingsFile)) { - this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel); + if (this->Verbose) { + this->LogBold("Generating MOC predefs " + this->MocPredefsFileRel); + } std::string output; { @@ -1340,7 +1354,9 @@ bool cmQtAutoGenerators::MocGenerateAll( if (this->FileDiffers(this->MocCompFileAbs, automocSource)) { // Actually write mocs compilation file - this->LogBold("Generating MOC compilation " + this->MocCompFileRel); + if (this->Verbose) { + this->LogBold("Generating MOC compilation " + this->MocCompFileRel); + } if (!this->FileWrite("AutoMoc", this->MocCompFileAbs, automocSource)) { return false; } @@ -1391,7 +1407,9 @@ bool cmQtAutoGenerators::MocGenerateFile( } if (generateMoc) { // Log - this->LogBold("Generating MOC source " + mocFileRel); + if (this->Verbose) { + this->LogBold("Generating MOC source " + mocFileRel); + } // Make sure the parent directory exists if (this->MakeParentDirectory("AutoMoc", mocFileAbs)) { @@ -1446,31 +1464,62 @@ bool cmQtAutoGenerators::MocGenerateFile( bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, const std::string& sourceFile, - const std::string& includeString) + const std::string& searchPath, + const std::string& searchFile) { bool success = false; - // Search in vicinity of the source + std::vector<std::string> testFiles; + // Collect search paths list { - std::string testPath = SubDirPrefix(sourceFile); - testPath += includeString; - if (cmsys::SystemTools::FileExists(testPath.c_str())) { - absFile = cmsys::SystemTools::GetRealPath(testPath); + const std::string searchFileFull = searchPath + searchFile; + // Vicinity of the source + { + const std::string sourcePath = SubDirPrefix(sourceFile); + testFiles.push_back(sourcePath + searchFile); + if (!searchPath.empty()) { + testFiles.push_back(sourcePath + searchFileFull); + } + } + // AUTOUIC search paths + if (!this->UicSearchPaths.empty()) { + for (std::vector<std::string>::const_iterator iit = + this->UicSearchPaths.begin(); + iit != this->UicSearchPaths.end(); ++iit) { + testFiles.push_back(*iit + "/" + searchFile); + } + if (!searchPath.empty()) { + for (std::vector<std::string>::const_iterator iit = + this->UicSearchPaths.begin(); + iit != this->UicSearchPaths.end(); ++iit) { + testFiles.push_back(*iit + "/" + searchFileFull); + } + } + } + } + + // Search for the .ui file! + for (std::vector<std::string>::const_iterator iit = testFiles.begin(); + iit != testFiles.end(); ++iit) { + const std::string& testFile = *iit; + if (cmsys::SystemTools::FileExists(testFile.c_str())) { + absFile = cmsys::SystemTools::GetRealPath(testFile); success = true; + break; } } - // Search in include directories + + // Log error if (!success) { - for (std::vector<std::string>::const_iterator iit = - this->UicSearchPaths.begin(); - iit != this->UicSearchPaths.end(); ++iit) { - const std::string fullPath = ((*iit) + '/' + includeString); - if (cmsys::SystemTools::FileExists(fullPath.c_str())) { - absFile = cmsys::SystemTools::GetRealPath(fullPath); - success = true; - break; - } + std::ostringstream ost; + ost << "AutoUic: Error: " << Quoted(sourceFile) << "\n"; + ost << "Could not find " << Quoted(searchFile) << " in\n"; + for (std::vector<std::string>::const_iterator iit = testFiles.begin(); + iit != testFiles.end(); ++iit) { + ost << " " << Quoted(*iit) << "\n"; } + this->LogError(ost.str()); } + return success; } @@ -1500,16 +1549,14 @@ bool cmQtAutoGenerators::UicGenerateAll( const std::string uiBasePath = SubDirPrefix(*uit); const std::string uiBaseName = cmsys::SystemTools::GetFilenameWithoutLastExtension(*uit).substr(3); - const std::string searchFileName = uiBasePath + uiBaseName + ".ui"; + const std::string uiFileName = uiBaseName + ".ui"; std::string uiInputFile; - if (UicFindIncludedFile(uiInputFile, source, searchFileName)) { + if (UicFindIncludedFile(uiInputFile, source, uiBasePath, uiFileName)) { std::string uiOutputFile = uiBasePath + "ui_" + uiBaseName + ".h"; cmSystemTools::ReplaceString(uiOutputFile, "..", "__"); uiGenMap[uiInputFile] = uiOutputFile; testMap[uiInputFile] = uiOutputFile; } else { - this->LogError("AutoUic: Error: " + Quoted(sit->first) + - "\nCould not find " + Quoted(searchFileName)); return false; } } @@ -1567,7 +1614,9 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, } if (generateUic) { // Log - this->LogBold("Generating UIC header " + uicFileRel); + if (this->Verbose) { + this->LogBold("Generating UIC header " + uicFileRel); + } // Make sure the parent directory exists if (this->MakeParentDirectory("AutoUic", uicFileAbs)) { @@ -1673,10 +1722,10 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, { bool rccGenerated = false; bool generateRcc = this->RccSettingsChanged; - const std::string rccBuildFile = cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile); + // Check if regeneration is required if (!generateRcc) { // Test if the resources list file is newer than build file generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile); @@ -1709,9 +1758,12 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, } } } + // Regenerate on demand if (generateRcc) { // Log - this->LogBold("Generating RCC source " + rccOutputFile); + if (this->Verbose) { + this->LogBold("Generating RCC source " + rccOutputFile); + } // Make sure the parent directory exists if (this->MakeParentDirectory("AutoRcc", rccBuildFile)) { @@ -1764,6 +1816,41 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, this->RccRunFailed = true; } } + // For a multi configuration generator generate a wrapper file + if (!this->ConfigSuffix.empty() && !this->RccRunFailed) { + // Wrapper file name + const std::string cppSuffix = ".cpp"; + const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size(); + const std::string wrapperFileRel = + rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix; + const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath( + this->AutogenBuildDir, wrapperFileRel); + // Wrapper file content + std::string content = + "// This is an autogenerated configuration wrapper file. Do not edit.\n" + "#include \""; + content += cmsys::SystemTools::GetFilenameName(rccBuildFile); + content += "\"\n"; + // Write content to file + if (this->FileDiffers(wrapperFileAbs, content)) { + // Write new wrapper file if the content differs + if (this->Verbose) { + this->LogBold("Generating RCC wrapper " + wrapperFileRel); + } + if (!this->FileWrite("AutoRcc", wrapperFileAbs, content)) { + // Error + rccGenerated = false; + this->RccRunFailed = true; + } + } else if (rccGenerated) { + // Only touch wrapper file if the content matches + if (this->Verbose) { + this->LogInfo("Touching RCC wrapper " + wrapperFileRel); + } + cmSystemTools::Touch(wrapperFileAbs, false); + } + } + return rccGenerated; } |