diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2017-09-01 12:28:26 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2017-09-07 16:03:13 (GMT) |
commit | 9468e926b0fb01b2f11b9d4c9c13f7ad64b328e2 (patch) | |
tree | 0bc182683aecaea39e2d5f6afda0475d675b8a2b | |
parent | 2ba1b2812290e962e33aa884989b7f57d43b8491 (diff) | |
download | CMake-9468e926b0fb01b2f11b9d4c9c13f7ad64b328e2.zip CMake-9468e926b0fb01b2f11b9d4c9c13f7ad64b328e2.tar.gz CMake-9468e926b0fb01b2f11b9d4c9c13f7ad64b328e2.tar.bz2 |
Autogen: Refactor logging
-rw-r--r-- | Source/cmQtAutoGen.cxx | 14 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 587 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 37 |
3 files changed, 373 insertions, 265 deletions
diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index cdd41ca..95cd122 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -102,8 +102,8 @@ static bool RccListInputsQt4(const std::string& fileName, } else { if (errorMessage != nullptr) { std::ostringstream ost; - ost << "AutoRcc: Error: Rcc file not readable:\n" - << cmQtAutoGen::Quoted(fileName) << "\n"; + ost << "rcc file not readable:\n" + << " " << cmQtAutoGen::Quoted(fileName) << "\n"; *errorMessage = ost.str(); } allGood = false; @@ -145,7 +145,7 @@ static bool RccListInputsQt5(const std::string& rccCommand, std::string* errorMessage) { if (rccCommand.empty()) { - cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n"); + cmSystemTools::Error("rcc executable not available"); return false; } @@ -184,7 +184,7 @@ static bool RccListInputsQt5(const std::string& rccCommand, if (!result || retVal) { if (errorMessage != nullptr) { std::ostringstream ost; - ost << "AutoRcc: Error: Rcc list process for " << fileName + ost << "rcc list process for " << cmQtAutoGen::Quoted(fileName) << " failed:\n" << rccStdOut << "\n" << rccStdErr << "\n"; @@ -217,7 +217,7 @@ static bool RccListInputsQt5(const std::string& rccCommand, if (pos == std::string::npos) { if (errorMessage != nullptr) { std::ostringstream ost; - ost << "AutoRcc: Error: Rcc lists unparsable output:\n" + ost << "rcc lists unparsable output:\n" << cmQtAutoGen::Quoted(eline) << "\n"; *errorMessage = ost.str(); } @@ -311,8 +311,8 @@ bool cmQtAutoGen::RccListInputs(const std::string& qtMajorVersion, } else { if (errorMessage != nullptr) { std::ostringstream ost; - ost << "AutoRcc: Error: Rcc file does not exist:\n" - << cmQtAutoGen::Quoted(fileName) << "\n"; + ost << "rcc file does not exist:\n" + << " " << cmQtAutoGen::Quoted(fileName) << "\n"; *errorMessage = ost.str(); } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 2df44d1..221a1ac 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -36,11 +36,6 @@ static const char* SettingsKeyRcc = "AM_RCC_SETTINGS_HASH"; // -- Static functions -inline static std::string Quoted(const std::string& text) -{ - return cmQtAutoGen::Quoted(text); -} - static std::string QuotedCommand(const std::vector<std::string>& command) { std::string res; @@ -48,7 +43,7 @@ static std::string QuotedCommand(const std::vector<std::string>& command) if (!res.empty()) { res.push_back(' '); } - const std::string cesc = Quoted(item); + const std::string cesc = cmQtAutoGen::Quoted(item); if (item.empty() || (cesc.size() > (item.size() + 2)) || (cesc.find(' ') != std::string::npos)) { res += cesc; @@ -175,27 +170,36 @@ bool cmQtAutoGenerators::Run(const std::string& targetDirectory, bool cmQtAutoGenerators::MocDependFilterPush(const std::string& key, const std::string& regExp) { - bool success = false; + std::string error; if (!key.empty()) { if (!regExp.empty()) { KeyRegExp filter; filter.Key = key; if (filter.RegExp.compile(regExp)) { this->MocDependFilters.push_back(std::move(filter)); - success = true; } else { - this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Compiling " - "regular expression failed.\n Key: " + - Quoted(key) + "\n RegExp.: " + Quoted(regExp)); + error = "Regular expression compiling failed"; } } else { - this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Regular " - "expression is empty"); + error = "Regular expression is empty"; } } else { - this->LogError("AutoMoc: Error in AUTOMOC_DEPEND_FILTERS: Key is empty"); + error = "Key is empty"; } - return success; + if (!error.empty()) { + std::string emsg = "AUTOMOC_DEPEND_FILTERS: "; + emsg += error; + emsg += "\n"; + emsg += " Key: "; + emsg += cmQtAutoGen::Quoted(key); + emsg += "\n"; + emsg += " RegExp: "; + emsg += cmQtAutoGen::Quoted(regExp); + emsg += "\n"; + this->LogError(cmQtAutoGen::MOC, emsg); + return false; + } + return true; } bool cmQtAutoGenerators::ReadAutogenInfoFile( @@ -268,7 +272,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( filename += "/AutogenInfo.cmake"; if (!makefile->ReadListFile(filename.c_str())) { - this->LogError("AutoGen: Error processing file: " + filename); + this->LogFileError(cmQtAutoGen::GEN, filename, "File processing failed"); return false; } @@ -293,7 +297,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( InfoGetBool("AM_CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE"); this->AutogenBuildDir = InfoGet("AM_BUILD_DIR"); if (this->AutogenBuildDir.empty()) { - this->LogError("AutoGen: Error: Missing autogen build directory "); + this->LogFileError(cmQtAutoGen::GEN, filename, + "Autogen build directory missing"); return false; } this->Sources = InfoGetList("AM_SOURCES"); @@ -308,8 +313,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // Check Qt version if ((this->QtMajorVersion != "4") && (this->QtMajorVersion != "5")) { - this->LogError("AutoGen: Error: Unsupported Qt version: " + - Quoted(this->QtMajorVersion)); + this->LogFileError(cmQtAutoGen::GEN, filename, "Unsupported Qt version: " + + cmQtAutoGen::Quoted(this->QtMajorVersion)); return false; } @@ -356,10 +361,9 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( } } } else { - this->LogError( - "AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not " - "a multiple of 2 in:\n" + - Quoted(filename)); + this->LogFileError( + cmQtAutoGen::MOC, filename, + "AUTOMOC_DEPEND_FILTERS list size is not a multiple of 2"); return false; } } @@ -372,22 +376,23 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( this->UicSearchPaths = InfoGetList("AM_UIC_SEARCH_PATHS"); this->UicTargetOptions = InfoGetConfigList("AM_UIC_TARGET_OPTIONS"); { - auto uicFiles = InfoGetList("AM_UIC_OPTIONS_FILES"); - auto uicOptions = InfoGetLists("AM_UIC_OPTIONS_OPTIONS"); + auto sources = InfoGetList("AM_UIC_OPTIONS_FILES"); + auto options = InfoGetLists("AM_UIC_OPTIONS_OPTIONS"); // Compare list sizes - if (uicFiles.size() == uicOptions.size()) { - auto fitEnd = uicFiles.cend(); - auto fit = uicFiles.begin(); - auto oit = uicOptions.begin(); + if (sources.size() == options.size()) { + auto fitEnd = sources.cend(); + auto fit = sources.begin(); + auto oit = options.begin(); while (fit != fitEnd) { this->UicOptions[*fit] = std::move(*oit); ++fit; ++oit; } } else { - this->LogError( - "AutoGen: Error: Uic files/options lists size missmatch in:\n" + - Quoted(filename)); + std::ostringstream ost; + ost << "files/options lists sizes missmatch (" << sources.size() << "/" + << options.size() << ")"; + this->LogFileError(cmQtAutoGen::UIC, filename, ost.str()); return false; } } @@ -403,26 +408,23 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( if (sources.size() != builds.size()) { std::ostringstream ost; - ost << "AutoRcc: Error: sources/builds list sizes missmatch (" - << sources.size() << "/" << builds.size() << ")" - << " in\n " << Quoted(filename); - this->LogError(ost.str()); + ost << "sources, builds lists sizes missmatch (" << sources.size() << "/" + << builds.size() << ")"; + this->LogFileError(cmQtAutoGen::RCC, filename, ost.str()); return false; } if (sources.size() != options.size()) { std::ostringstream ost; - ost << "AutoRcc: Error: sources/options list sizes missmatch (" - << sources.size() << "/" << options.size() << ")" - << " in\n " << Quoted(filename); - this->LogError(ost.str()); + ost << "sources, options lists sizes missmatch (" << sources.size() + << "/" << options.size() << ")"; + this->LogFileError(cmQtAutoGen::RCC, filename, ost.str()); return false; } if (sources.size() != inputs.size()) { std::ostringstream ost; - ost << "AutoRcc: Error: sources/inputs list sizes missmatch (" - << sources.size() << "/" << inputs.size() << ")" - << " in\n " << Quoted(filename); - this->LogError(ost.str()); + ost << "sources, inputs lists sizes missmatch (" << sources.size() << "/" + << inputs.size() << ")"; + this->LogFileError(cmQtAutoGen::RCC, filename, ost.str()); return false; } @@ -535,8 +537,8 @@ bool cmQtAutoGenerators::SettingsFileWrite() // Only write if any setting changed if (this->AnySettingsChanged()) { if (this->Verbose) { - this->LogInfo("AutoGen: Writing settings file " + - Quoted(this->SettingsFile)); + this->LogInfo(cmQtAutoGen::GEN, "Writing settings file " + + cmQtAutoGen::Quoted(this->SettingsFile)); } // Compose settings file content std::string settings; @@ -555,8 +557,8 @@ bool cmQtAutoGenerators::SettingsFileWrite() } // Write settings file if (!this->FileWrite(cmQtAutoGen::GEN, this->SettingsFile, settings)) { - this->LogError("AutoGen: Error: Could not write old settings file " + - Quoted(this->SettingsFile)); + this->LogFileError(cmQtAutoGen::GEN, this->SettingsFile, + "File writing failed"); // Remove old settings file to trigger a full rebuild on the next run cmSystemTools::RemoveFile(this->SettingsFile); success = false; @@ -662,8 +664,8 @@ bool cmQtAutoGenerators::RunAutogen() const std::string incDirAbs = cmSystemTools::CollapseCombinedPath( this->AutogenBuildDir, this->AutogenIncludeDir); if (!cmSystemTools::MakeDirectory(incDirAbs)) { - this->LogError("AutoGen: Error: Could not create include directory " + - Quoted(incDirAbs)); + this->LogFileError(cmQtAutoGen::GEN, incDirAbs, + "Could not create directory"); return false; } } @@ -759,13 +761,14 @@ void cmQtAutoGenerators::MocFindDepends( if (this->MocFindIncludedFile(incFile, sourcePath, match)) { mocDepends[absFilename].insert(incFile); if (this->Verbose) { - this->LogInfo("AutoMoc: Found dependency:\n " + - Quoted(absFilename) + "\n " + Quoted(incFile)); + this->LogInfo(cmQtAutoGen::MOC, "Found dependency:\n " + + cmQtAutoGen::Quoted(absFilename) + "\n " + + cmQtAutoGen::Quoted(incFile)); } } else { - this->LogWarning("AutoMoc: Warning: " + Quoted(absFilename) + - "\n" + "Could not find dependency file " + - Quoted(match)); + this->LogFileWarning(cmQtAutoGen::MOC, absFilename, + "Could not find dependency file " + + cmQtAutoGen::Quoted(match)); } } contentChars += filter.RegExp.end(); @@ -826,15 +829,10 @@ bool cmQtAutoGenerators::ParseSourceFile( this->UicParseContent(absFilename, contentText, uisIncluded); } } else { - std::ostringstream ost; - ost << "AutoGen: Warning: The file is empty:\n" - << Quoted(absFilename) << "\n"; - this->LogWarning(ost.str()); + this->LogFileWarning(cmQtAutoGen::GEN, absFilename, "The file is empty"); } } else { - std::ostringstream ost; - ost << "AutoGen: Error: Could not read file:\n" << Quoted(absFilename); - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::GEN, absFilename, "Could not read file"); } return success; } @@ -844,7 +842,7 @@ void cmQtAutoGenerators::UicParseContent( std::map<std::string, std::vector<std::string>>& uisIncluded) { if (this->Verbose) { - this->LogInfo("AutoUic: Checking " + absFilename); + this->LogInfo(cmQtAutoGen::UIC, "Checking " + absFilename); } const char* contentChars = contentText.c_str(); @@ -856,6 +854,36 @@ void cmQtAutoGenerators::UicParseContent( } } +std::string cmQtAutoGenerators::MocMacroNamesString() const +{ + std::string res; + const auto itB = this->MocMacroFilters.cbegin(); + const auto itE = this->MocMacroFilters.cend(); + const auto itL = itE - 1; + auto itC = itB; + for (; itC != itE; ++itC) { + // Separator + if (itC != itB) { + if (itC != itL) { + res += ", "; + } else { + res += " or "; + } + } + // Key + res += itC->Key; + } + return res; +} + +std::string cmQtAutoGenerators::MocHeaderSuffixesString() const +{ + std::string res = ".{"; + res += cmJoin(this->HeaderExtensions, ","); + res += "}"; + return res; +} + /** * @return True on success */ @@ -865,15 +893,15 @@ bool cmQtAutoGenerators::MocParseSourceContent( std::map<std::string, std::set<std::string>>& mocDepends, bool relaxed) { if (this->Verbose) { - this->LogInfo("AutoMoc: Checking " + absFilename); + this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename); } - const std::string scannedFileAbsPath = SubDirPrefix(absFilename); - const std::string scannedFileBasename = + const std::string scanFileDir = SubDirPrefix(absFilename); + const std::string scanFileBase = cmSystemTools::GetFilenameWithoutLastExtension(absFilename); - std::string macroName; - const bool requiresMoc = this->MocRequired(contentText, ¯oName); + std::string selfMacroName; + const bool selfRequiresMoc = this->MocRequired(contentText, &selfMacroName); bool ownDotMocIncluded = false; std::string ownMocUnderscoreInclude; std::string ownMocUnderscoreHeader; @@ -887,8 +915,8 @@ bool cmQtAutoGenerators::MocParseSourceContent( while (this->MocRegExpInclude.find(contentChars)) { const std::string incString = this->MocRegExpInclude.match(1); // Basename of the moc include - const std::string incSubDir(SubDirPrefix(incString)); - const std::string incBasename = + const std::string incDir(SubDirPrefix(incString)); + const std::string incBase = cmSystemTools::GetFilenameWithoutLastExtension(incString); // If the moc include is of the moc_foo.cpp style we expect @@ -896,110 +924,123 @@ bool cmQtAutoGenerators::MocParseSourceContent( // If the moc include is of the foo.moc style we need to look for // a Q_OBJECT macro in the current source file, if it contains the // macro we generate the moc file from the source file. - if (cmHasLiteralPrefix(incBasename, "moc_")) { + if (cmHasLiteralPrefix(incBase, "moc_")) { // Include: moc_FOO.cxx // Remove the moc_ part - const std::string incRealBasename = incBasename.substr(4); + const std::string incRealBase = incBase.substr(4); const std::string headerToMoc = - this->MocFindHeader(scannedFileAbsPath, incSubDir + incRealBasename); + this->MocFindHeader(scanFileDir, incDir + incRealBase); if (!headerToMoc.empty()) { if (!this->MocSkip(headerToMoc)) { // Register moc job mocsIncluded[headerToMoc] = incString; this->MocFindDepends(headerToMoc, contentText, mocDepends); // Store meta information for relaxed mode - if (relaxed && (incRealBasename == scannedFileBasename)) { + if (relaxed && (incRealBase == scanFileBase)) { ownMocUnderscoreInclude = incString; ownMocUnderscoreHeader = headerToMoc; } } } else { std::ostringstream ost; - ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) - << ", but could not find header " - << Quoted(incRealBasename + ".{" + - cmJoin(this->HeaderExtensions, ",") + "}"); - this->LogError(ost.str()); + ost << "The file includes the moc file " + << cmQtAutoGen::Quoted(incString) + << ", but could not find header "; + ost << cmQtAutoGen::Quoted(incRealBase + + this->MocHeaderSuffixesString()); + this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str()); return false; } } else { // Include: FOO.moc + bool ownDotMoc = (incBase == scanFileBase); std::string fileToMoc; if (relaxed) { // Mode: Relaxed - if (requiresMoc && (incBasename == scannedFileBasename)) { + if (selfRequiresMoc && ownDotMoc) { // Include self fileToMoc = absFilename; ownDotMocIncluded = true; } else { // In relaxed mode try to find a header instead but issue a warning const std::string headerToMoc = - this->MocFindHeader(scannedFileAbsPath, incSubDir + incBasename); + this->MocFindHeader(scanFileDir, incDir + incBase); if (!headerToMoc.empty()) { if (!this->MocSkip(headerToMoc)) { // This is for KDE4 compatibility: fileToMoc = headerToMoc; - if (!requiresMoc && (incBasename == scannedFileBasename)) { - std::ostringstream ost; - ost - << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) - << ", but does not contain a Q_OBJECT or Q_GADGET macro.\n" - << "Running moc on " << Quoted(headerToMoc) << "!\n" - << "Include " << Quoted("moc_" + incBasename + ".cpp") - << " for a compatibility with strict mode (see " - "CMAKE_AUTOMOC_RELAXED_MODE).\n"; - this->LogWarning(ost.str()); + + auto quoted_inc = cmQtAutoGen::Quoted(incString); + auto quoted_header = cmQtAutoGen::Quoted(headerToMoc); + auto quoted_base = + cmQtAutoGen::Quoted("moc_" + incBase + ".cpp"); + if (!selfRequiresMoc) { + if (ownDotMoc) { + std::ostringstream ost; + ost << "The file includes the moc file " << quoted_inc + << ", but does not contain a " + << this->MocMacroNamesString() << " macro.\n" + << "Running moc on\n" + << " " << quoted_header << "!\n" + << "Better include " << quoted_base + << " for a compatibility with strict mode.\n" + "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n"; + this->LogFileWarning(cmQtAutoGen::MOC, absFilename, + ost.str()); + } else if (!ownDotMoc) { + std::ostringstream ost; + ost << "The file includes the moc file " << quoted_inc + << " instead of " << quoted_base << ".\n"; + ost << "Running moc on\n" + << " " << quoted_header << "!\n" + << "Better include " << quoted_base + << " for compatibility with strict mode.\n" + "(CMAKE_AUTOMOC_RELAXED_MODE warning)\n"; + this->LogFileWarning(cmQtAutoGen::MOC, absFilename, + ost.str()); + } } else { - std::ostringstream ost; - ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) - << " instead of " - << Quoted("moc_" + incBasename + ".cpp") << ".\n" - << "Running moc on " << Quoted(headerToMoc) << "!\n" - << "Include " << Quoted("moc_" + incBasename + ".cpp") - << " for compatibility with strict mode (see " - "CMAKE_AUTOMOC_RELAXED_MODE).\n"; - this->LogWarning(ost.str()); + if (!ownDotMoc) { + // Handled further down + } } } } else { std::ostringstream ost; - ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) + ost << "The file includes the moc file " + << cmQtAutoGen::Quoted(incString) << ", which seems to be the moc file from a different " "source file. CMake also could not find a matching " "header."; - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str()); return false; } } } else { // Mode: Strict - if (incBasename == scannedFileBasename) { + if (ownDotMoc) { // Include self fileToMoc = absFilename; ownDotMocIncluded = true; // Accept but issue a warning if moc isn't required - if (!requiresMoc) { + if (!selfRequiresMoc) { std::ostringstream ost; - ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) - << ", but does not contain a Q_OBJECT or Q_GADGET " - "macro."; - this->LogWarning(ost.str()); + ost << "The file includes the moc file " + << cmQtAutoGen::Quoted(incString) + << ", but does not contain a " << this->MocMacroNamesString() + << " macro."; + this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str()); } } else { // Don't allow FOO.moc include other than self in strict mode std::ostringstream ost; - ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" - << "The file includes the moc file " << Quoted(incString) + ost << "The file includes the moc file " + << cmQtAutoGen::Quoted(incString) << ", which seems to be the moc file from a different " "source file. This is not supported. Include " - << Quoted(scannedFileBasename + ".moc") + << cmQtAutoGen::Quoted(scanFileBase + ".moc") << " to run moc on this source file."; - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str()); return false; } } @@ -1013,24 +1054,26 @@ bool cmQtAutoGenerators::MocParseSourceContent( } } - if (requiresMoc && !ownDotMocIncluded) { - // In this case, check whether the scanned file itself contains a Q_OBJECT. + if (selfRequiresMoc && !ownDotMocIncluded) { + // In this case, check whether the scanned file itself contains a + // Q_OBJECT. // If this is the case, the moc_foo.cpp should probably be generated from // foo.cpp instead of foo.h, because otherwise it won't build. // But warn, since this is not how it is supposed to be used. if (relaxed && !ownMocUnderscoreInclude.empty()) { // This is for KDE4 compatibility: std::ostringstream ost; - ost << "AutoMoc: Warning: " << Quoted(absFilename) << "\n" - << "The file contains a " << macroName + ost << "The file contains a " << selfMacroName << " macro, but does not include " - << Quoted(scannedFileBasename + ".moc") << ", but instead includes " - << Quoted(ownMocUnderscoreInclude) << ".\n" - << "Running moc on " << Quoted(absFilename) << "!\n" - << "Better include " << Quoted(scannedFileBasename + ".moc") - << " for compatibility with strict mode (see " - "CMAKE_AUTOMOC_RELAXED_MODE)."; - this->LogWarning(ost.str()); + << cmQtAutoGen::Quoted(scanFileBase + ".moc") + << ". Instead it includes " + << cmQtAutoGen::Quoted(ownMocUnderscoreInclude) << ".\n" + << "Running moc on\n" + << " " << cmQtAutoGen::Quoted(absFilename) << "!\n" + << "Better include " << cmQtAutoGen::Quoted(scanFileBase + ".moc") + << " for compatibility with strict mode.\n" + "(CMAKE_AUTOMOC_RELAXED_MODE warning)"; + this->LogFileWarning(cmQtAutoGen::MOC, absFilename, ost.str()); // Use scanned source file instead of scanned header file as moc source mocsIncluded[absFilename] = ownMocUnderscoreInclude; @@ -1040,13 +1083,12 @@ bool cmQtAutoGenerators::MocParseSourceContent( } else { // Otherwise always error out since it will not compile: std::ostringstream ost; - ost << "AutoMoc: Error: " << Quoted(absFilename) << "\n" - << "The file contains a " << macroName + ost << "The file contains a " << selfMacroName << " macro, but does not include " - << Quoted(scannedFileBasename + ".moc") << "!\n" + << cmQtAutoGen::Quoted(scanFileBase + ".moc") << "!\n" << "Consider adding the include or enabling SKIP_AUTOMOC for this " "file."; - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::MOC, absFilename, ost.str()); return false; } } @@ -1061,7 +1103,7 @@ void cmQtAutoGenerators::MocParseHeaderContent( { // Log if (this->Verbose) { - this->LogInfo("AutoMoc: Checking " + absFilename); + this->LogInfo(cmQtAutoGen::MOC, "Checking " + absFilename); } if (this->MocRequired(contentText)) { // Register moc job @@ -1128,10 +1170,8 @@ bool cmQtAutoGenerators::ParseHeaders( this->UicParseContent(headerName, contentText, uisIncluded); } } else { - std::ostringstream ost; - ost << "AutoGen: Error: Could not read header file:\n" - << Quoted(headerName); - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::GEN, headerName, + "Could not read header file"); success = false; break; } @@ -1155,14 +1195,12 @@ bool cmQtAutoGenerators::MocGenerateAll( std::map<std::string, std::string> mergedMocs(mocsIncluded); mergedMocs.insert(mocsNotIncluded.begin(), mocsNotIncluded.end()); if (this->NameCollisionTest(mergedMocs, collisions)) { - std::ostringstream ost; - ost << "AutoMoc: Error: " - "The same moc file will be generated " - "from different sources.\n" - "To avoid this error either\n" - "- rename the source files or\n" - "- do not include the (moc_NAME.cpp|NAME.moc) file"; - this->LogErrorNameCollision(ost.str(), collisions); + std::string msg = "The same moc file will be generated " + "from different sources.\n" + "To avoid this error either\n" + " - rename the source files or\n" + " - do not include the (moc_NAME.cpp|NAME.moc) file"; + this->LogNameCollisionError(cmQtAutoGen::MOC, msg, collisions); return false; } } @@ -1190,14 +1228,9 @@ bool cmQtAutoGenerators::MocGenerateAll( cmd.insert(cmd.end(), this->MocOptions.begin(), this->MocOptions.end()); // Execute command - if (!this->RunCommand(cmd, output, false)) { - { - std::ostringstream ost; - ost << "AutoMoc: Error: moc predefs generation command failed\n"; - ost << "AutoMoc: Command:\n" << QuotedCommand(cmd) << "\n"; - ost << "AutoMoc: Command output:\n" << output << "\n"; - this->LogError(ost.str()); - } + if (!this->RunCommand(cmd, output)) { + this->LogCommandError(cmQtAutoGen::MOC, + "moc_predefs generation failed", cmd, output); return false; } } @@ -1213,7 +1246,8 @@ bool cmQtAutoGenerators::MocGenerateAll( } else { // Touch to update the time stamp if (this->Verbose) { - this->LogInfo("Touching MOC predefs " + this->MocPredefsFileRel); + this->LogInfo(cmQtAutoGen::MOC, + "Touching moc_predefs " + this->MocPredefsFileRel); } cmSystemTools::Touch(this->MocPredefsFileAbs, false); } @@ -1276,7 +1310,8 @@ bool cmQtAutoGenerators::MocGenerateAll( } else if (mocCompFileGenerated) { // Only touch mocs compilation file if (this->Verbose) { - this->LogInfo("Touching MOC compilation " + this->MocCompFileRel); + this->LogInfo(cmQtAutoGen::MOC, + "Touching mocs compilation " + this->MocCompFileRel); } cmSystemTools::Touch(this->MocCompFileAbs, false); } @@ -1353,15 +1388,9 @@ bool cmQtAutoGenerators::MocGenerateFile( // Success mocGenerated = true; } else { - // Command failed - { - std::ostringstream ost; - ost << "AutoMoc: Error: moc process failed for\n"; - ost << Quoted(mocFileRel) << "\n"; - ost << "AutoMoc: Command:\n" << QuotedCommand(cmd) << "\n"; - ost << "AutoMoc: Command output:\n" << output << "\n"; - this->LogError(ost.str()); - } + this->LogCommandError(cmQtAutoGen::MOC, "moc failed for\n " + + cmQtAutoGen::Quoted(sourceFile), + cmd, output); cmSystemTools::RemoveFile(mocFileAbs); this->MocRunFailed = true; } @@ -1420,12 +1449,11 @@ bool cmQtAutoGenerators::UicFindIncludedFile(std::string& absFile, // Log error if (!success) { std::ostringstream ost; - ost << "AutoUic: Error: " << Quoted(sourceFile) << "\n"; - ost << "Could not find " << Quoted(searchFile) << " in\n"; + ost << "Could not find " << cmQtAutoGen::Quoted(searchFile) << " in\n"; for (const std::string& testFile : testFiles) { - ost << " " << Quoted(testFile) << "\n"; + ost << " " << cmQtAutoGen::Quoted(testFile) << "\n"; } - this->LogError(ost.str()); + this->LogFileError(cmQtAutoGen::UIC, sourceFile, ost.str()); } return success; @@ -1475,11 +1503,10 @@ bool cmQtAutoGenerators::UicGenerateAll( { std::multimap<std::string, std::string> collisions; if (this->NameCollisionTest(testMap, collisions)) { - std::ostringstream ost; - ost << "AutoUic: Error: The same ui_NAME.h file will be generated " - "from different sources.\n" - "To avoid this error rename the source files.\n"; - this->LogErrorNameCollision(ost.str(), collisions); + std::string msg = "The same ui_NAME.h file will be generated " + "from different sources.\n" + "To avoid this error rename the source files.\n"; + this->LogNameCollisionError(cmQtAutoGen::UIC, msg, collisions); return false; } } @@ -1549,12 +1576,11 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, // Command failed { std::ostringstream ost; - ost << "AutoUic: Error: uic process failed for\n"; - ost << Quoted(uicFileRel) << " needed by\n"; - ost << Quoted(realName) << "\n"; - ost << "AutoUic: Command:\n" << QuotedCommand(cmd) << "\n"; - ost << "AutoUic: Command output:\n" << output << "\n"; - this->LogError(ost.str()); + ost << "uic failed for\n" + << " " << cmQtAutoGen::Quoted(uiInputFile) << "\n" + << "needed by\n" + << " " << cmQtAutoGen::Quoted(realName); + this->LogCommandError(cmQtAutoGen::UIC, ost.str(), cmd, output); } cmSystemTools::RemoveFile(uicFileAbs); this->UicRunFailed = true; @@ -1622,7 +1648,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) files = &readFiles; } else { files = nullptr; - this->LogError(error); + this->LogFileError(cmQtAutoGen::RCC, rccJob.QrcFile, error); this->RccRunFailed = true; } } @@ -1659,15 +1685,9 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) // Success rccGenerated = true; } else { - // Command failed - { - std::ostringstream ost; - ost << "AutoRcc: Error: rcc process failed for\n"; - ost << Quoted(rccFileRel) << "\n"; - ost << "AutoRcc: Command:\n" << QuotedCommand(cmd) << "\n"; - ost << "AutoRcc: Command output:\n" << output << "\n"; - this->LogError(ost.str()); - } + this->LogCommandError(cmQtAutoGen::RCC, "rcc failed for\n " + + cmQtAutoGen::Quoted(rccJob.QrcFile), + cmd, output); cmSystemTools::RemoveFile(rccFileAbs); this->RccRunFailed = true; } @@ -1702,7 +1722,8 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) } else if (rccGenerated) { // Only touch wrapper file if the content matches if (this->Verbose) { - this->LogInfo("Touching RCC wrapper " + wrapperFileRel); + this->LogInfo(cmQtAutoGen::RCC, + "Touching RCC wrapper " + wrapperFileRel); } cmSystemTools::Touch(wrapperFileAbs, false); } @@ -1711,25 +1732,6 @@ bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) return rccGenerated; } -void cmQtAutoGenerators::LogErrorNameCollision( - const std::string& message, - const std::multimap<std::string, std::string>& collisions) const -{ - std::ostringstream ost; - // Add message - if (!message.empty()) { - ost << message; - if (message[message.size() - 1] != '\n') { - ost << '\n'; - } - } - // Append collision list - for (const auto& item : collisions) { - ost << " " << item.first << " : " << item.second << '\n'; - } - this->LogError(ost.str()); -} - void cmQtAutoGenerators::LogBold(const std::string& message) const { cmSystemTools::MakefileColorEcho(cmsysTerminal_Color_ForegroundBlue | @@ -1737,41 +1739,137 @@ void cmQtAutoGenerators::LogBold(const std::string& message) const message.c_str(), true, this->ColorOutput); } -void cmQtAutoGenerators::LogInfo(const std::string& message) const +void cmQtAutoGenerators::LogInfo(cmQtAutoGen::GeneratorType genType, + const std::string& message) const { - std::string msg(message); - if (!msg.empty()) { - if (msg[msg.size() - 1] != '\n') { - msg.push_back('\n'); - } - cmSystemTools::Stdout(msg.c_str(), msg.size()); + std::string msg = cmQtAutoGen::GeneratorName(genType); + msg += ": "; + msg += message; + if (msg.back() != '\n') { + msg.push_back('\n'); } + cmSystemTools::Stdout(msg.c_str(), msg.size()); } -void cmQtAutoGenerators::LogWarning(const std::string& message) const +void cmQtAutoGenerators::LogWarning(cmQtAutoGen::GeneratorType genType, + const std::string& message) const { - std::string msg(message); - if (!msg.empty()) { - if (msg[msg.size() - 1] != '\n') { - msg.push_back('\n'); - } - // Append empty line + std::string msg = cmQtAutoGen::GeneratorName(genType); + msg += " warning:"; + if (message.find('\n') == std::string::npos) { + // Single line message + msg.push_back(' '); + } else { + // Multi line message + msg.push_back('\n'); + } + // Message + msg += message; + if (msg.back() != '\n') { msg.push_back('\n'); - cmSystemTools::Stdout(msg.c_str(), msg.size()); } + msg += "\n"; + cmSystemTools::Stdout(msg.c_str(), msg.size()); } -void cmQtAutoGenerators::LogError(const std::string& message) const +void cmQtAutoGenerators::LogFileWarning(cmQtAutoGen::GeneratorType genType, + const std::string& filename, + const std::string& message) const { - std::string msg(message); - if (!msg.empty()) { - if (msg[msg.size() - 1] != '\n') { - msg.push_back('\n'); + std::string emsg = " "; + emsg += cmQtAutoGen::Quoted(filename); + emsg += "\n"; + // Message + emsg += message; + this->LogWarning(genType, emsg); +} + +void cmQtAutoGenerators::LogError(cmQtAutoGen::GeneratorType genType, + const std::string& message) const +{ + std::string msg; + msg.push_back('\n'); + msg = cmQtAutoGen::GeneratorName(genType); + msg += " error:"; + if (message.find('\n') == std::string::npos) { + // Single line message + msg.push_back(' '); + } else { + // Multi line message + msg.push_back('\n'); + } + // Message + msg += message; + if (msg.back() != '\n') { + msg.push_back('\n'); + } + msg += "\n"; + cmSystemTools::Stderr(msg.c_str(), msg.size()); +} + +void cmQtAutoGenerators::LogFileError(cmQtAutoGen::GeneratorType genType, + const std::string& filename, + const std::string& message) const +{ + std::string emsg = " "; + emsg += cmQtAutoGen::Quoted(filename); + emsg += "\n"; + // Message + emsg += message; + this->LogError(genType, emsg); +} + +void cmQtAutoGenerators::LogNameCollisionError( + cmQtAutoGen::GeneratorType genType, const std::string& message, + const std::multimap<std::string, std::string>& collisions) const +{ + std::string emsg; + // Add message + if (!message.empty()) { + emsg += message; + if (emsg.back() != '\n') { + emsg.push_back('\n'); } - // Append empty line + } + // Append collision list + for (const auto& item : collisions) { + emsg += " "; + emsg += item.first; + emsg += " -> "; + emsg += item.second; + emsg += "\n"; + } + this->LogError(genType, emsg); +} + +void cmQtAutoGenerators::LogCommandError( + cmQtAutoGen::GeneratorType genType, const std::string& message, + const std::vector<std::string>& command, const std::string& output) const +{ + std::string msg; + msg.push_back('\n'); + msg += cmQtAutoGen::GeneratorName(genType); + msg += " subprocess error: "; + msg += message; + if (msg.back() != '\n') { + msg.push_back('\n'); + } + msg.push_back('\n'); + msg += "Command\n"; + msg += "-------\n"; + msg += QuotedCommand(command); + if (msg.back() != '\n') { + msg.push_back('\n'); + } + msg.push_back('\n'); + msg += "Output\n"; + msg += "------\n"; + msg += output; + if (msg.back() != '\n') { msg.push_back('\n'); - cmSystemTools::Stderr(msg.c_str(), msg.size()); } + msg += "\n"; + cmSystemTools::Stderr(msg.c_str(), msg.size()); } /** @@ -1832,10 +1930,8 @@ bool cmQtAutoGenerators::MakeParentDirectory( if (!dirName.empty()) { success = cmSystemTools::MakeDirectory(dirName); if (!success) { - std::string error = cmQtAutoGen::GeneratorName(genType); - error += ": Error: Parent directory creation failed for "; - error += Quoted(filename); - this->LogError(error); + this->LogFileError(genType, filename, + "Could not create parent directory"); } } return success; @@ -1867,20 +1963,14 @@ bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::GeneratorType genType, outfile << content; // Check for write errors if (!outfile.good()) { - error = cmQtAutoGen::GeneratorName(genType); - error += ": Error: File writing failed\n"; - error += " "; - error += Quoted(filename); + error = "File writing failed"; } } else { - error = cmQtAutoGen::GeneratorName(genType); - error += ": Error: Opening file for writing failed\n"; - error += " "; - error += Quoted(filename); + error = "Opening file for writing failed"; } } if (!error.empty()) { - this->LogError(error); + this->LogFileError(genType, filename, error); return false; } return true; @@ -1891,17 +1981,18 @@ bool cmQtAutoGenerators::FileWrite(cmQtAutoGen::GeneratorType genType, * @return True on success */ bool cmQtAutoGenerators::RunCommand(const std::vector<std::string>& command, - std::string& output, bool verbose) const + std::string& output) const { // Log command if (this->Verbose) { - this->LogInfo(QuotedCommand(command)); + std::string qcmd = QuotedCommand(command); + qcmd.push_back('\n'); + cmSystemTools::Stdout(qcmd.c_str(), qcmd.size()); } // Execute command int retVal = 0; bool res = cmSystemTools::RunSingleCommand( - command, &output, &output, &retVal, nullptr, - verbose ? cmSystemTools::OUTPUT_MERGE : cmSystemTools::OUTPUT_NONE); + command, &output, &output, &retVal, nullptr, cmSystemTools::OUTPUT_NONE); return (res && (retVal == 0)); } diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index d7f4f63..1bacd49 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -112,6 +112,9 @@ private: const std::string& fileName, const std::string& contentText, std::map<std::string, std::vector<std::string>>& includedUis); + std::string MocMacroNamesString() const; + std::string MocHeaderSuffixesString() const; + bool MocParseSourceContent( const std::string& absFilename, const std::string& contentText, std::map<std::string, std::string>& mocsIncluded, @@ -146,15 +149,29 @@ private: bool RccGenerateAll(); bool RccGenerateFile(const RccJob& rccJob); - // -- Logging - void LogErrorNameCollision( - const std::string& message, - const std::multimap<std::string, std::string>& collisions) const; + // -- Log info void LogBold(const std::string& message) const; - void LogInfo(const std::string& message) const; - void LogWarning(const std::string& message) const; - void LogError(const std::string& message) const; - void LogCommand(const std::vector<std::string>& command) const; + void LogInfo(cmQtAutoGen::GeneratorType genType, + const std::string& message) const; + // -- Log warning + void LogWarning(cmQtAutoGen::GeneratorType genType, + const std::string& message) const; + void LogFileWarning(cmQtAutoGen::GeneratorType genType, + const std::string& filename, + const std::string& message) const; + // -- Log error + void LogError(cmQtAutoGen::GeneratorType genType, + const std::string& message) const; + void LogFileError(cmQtAutoGen::GeneratorType genType, + const std::string& filename, + const std::string& message) const; + void LogCommandError(cmQtAutoGen::GeneratorType genType, + const std::string& message, + const std::vector<std::string>& command, + const std::string& output) const; + void LogNameCollisionError( + cmQtAutoGen::GeneratorType genType, const std::string& message, + const std::multimap<std::string, std::string>& collisions) const; // -- Utility bool NameCollisionTest( @@ -169,8 +186,8 @@ private: bool FileWrite(cmQtAutoGen::GeneratorType genType, const std::string& filename, const std::string& content); - bool RunCommand(const std::vector<std::string>& command, std::string& output, - bool verbose = true) const; + bool RunCommand(const std::vector<std::string>& command, + std::string& output) const; bool FindHeader(std::string& header, const std::string& testBasePath) const; |