diff options
Diffstat (limited to 'Source/cmQtAutoRcc.cxx')
-rw-r--r-- | Source/cmQtAutoRcc.cxx | 444 |
1 files changed, 212 insertions, 232 deletions
diff --git a/Source/cmQtAutoRcc.cxx b/Source/cmQtAutoRcc.cxx index 20885df93b..3af81ad38a 100644 --- a/Source/cmQtAutoRcc.cxx +++ b/Source/cmQtAutoRcc.cxx @@ -1,148 +1,135 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoRcc.h" -#include "cmQtAutoGen.h" -#include <sstream> +#include <algorithm> +#include <string> +#include <vector> #include "cmAlgorithms.h" #include "cmCryptoHash.h" #include "cmDuration.h" +#include "cmFileLock.h" #include "cmFileLockResult.h" -#include "cmMakefile.h" +#include "cmFileTime.h" #include "cmProcessOutput.h" +#include "cmQtAutoGen.h" +#include "cmQtAutoGenerator.h" +#include "cmStringAlgorithms.h" #include "cmSystemTools.h" -// -- Class methods - -cmQtAutoRcc::cmQtAutoRcc() = default; +namespace { -cmQtAutoRcc::~cmQtAutoRcc() = default; +/** \class cmQtAutoRccT + * \brief AUTORCC generator + */ +class cmQtAutoRccT : public cmQtAutoGenerator +{ +public: + cmQtAutoRccT(); + ~cmQtAutoRccT() override; + + cmQtAutoRccT(cmQtAutoRccT const&) = delete; + cmQtAutoRccT& operator=(cmQtAutoRccT const&) = delete; + +private: + // -- Utility + bool IsMultiConfig() const { return MultiConfig_; } + std::string MultiConfigOutput() const; + + // -- Abstract processing interface + bool InitFromInfo(InfoT const& info) override; + bool Process() override; + // -- Settings file + bool SettingsFileRead(); + bool SettingsFileWrite(); + // -- Tests + bool TestQrcRccFiles(bool& generate); + bool TestResources(bool& generate); + bool TestInfoFile(); + // -- Generation + bool GenerateRcc(); + bool GenerateWrapper(); + +private: + // -- Config settings + bool MultiConfig_ = false; + // -- Directories + std::string AutogenBuildDir_; + std::string IncludeDir_; + // -- Qt environment + std::string RccExecutable_; + cmFileTime RccExecutableTime_; + std::vector<std::string> RccListOptions_; + // -- Job + std::string LockFile_; + cmFileLock LockFileLock_; + std::string QrcFile_; + std::string QrcFileName_; + std::string QrcFileDir_; + cmFileTime QrcFileTime_; + std::string RccPathChecksum_; + std::string RccFileName_; + std::string RccFileOutput_; + std::string RccFilePublic_; + cmFileTime RccFileTime_; + std::string Reason; + std::vector<std::string> Options_; + std::vector<std::string> Inputs_; + // -- Settings file + std::string SettingsFile_; + std::string SettingsString_; + bool SettingsChanged_ = false; + bool BuildFileChanged_ = false; +}; + +cmQtAutoRccT::cmQtAutoRccT() + : cmQtAutoGenerator(GenT::RCC) +{ +} +cmQtAutoRccT::~cmQtAutoRccT() = default; -bool cmQtAutoRcc::Init(cmMakefile* makefile) +bool cmQtAutoRccT::InitFromInfo(InfoT const& info) { - // -- Utility lambdas - auto InfoGet = [makefile](std::string const& key) { - return makefile->GetSafeDefinition(key); - }; - auto InfoGetList = - [makefile](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(makefile->GetSafeDefinition(key), list); - return list; - }; - auto InfoGetConfig = [makefile, - this](std::string const& key) -> std::string { - const char* valueConf = nullptr; - { - std::string keyConf = key; - keyConf += '_'; - keyConf += InfoConfig(); - valueConf = makefile->GetDefinition(keyConf); - } - if (valueConf == nullptr) { - return makefile->GetSafeDefinition(key); - } - return std::string(valueConf); - }; - auto InfoGetConfigList = - [&InfoGetConfig](std::string const& key) -> std::vector<std::string> { - std::vector<std::string> list; - cmSystemTools::ExpandListArgument(InfoGetConfig(key), list); - return list; - }; - auto LogInfoError = [this](std::string const& msg) -> bool { - std::ostringstream err; - err << "In " << Quoted(this->InfoFile()) << ":\n" << msg; - this->Log().Error(GenT::RCC, err.str()); + // -- Required settings + if (!info.GetBool("MULTI_CONFIG", MultiConfig_, true) || + !info.GetString("BUILD_DIR", AutogenBuildDir_, true) || + !info.GetStringConfig("INCLUDE_DIR", IncludeDir_, true) || + !info.GetString("RCC_EXECUTABLE", RccExecutable_, true) || + !info.GetArray("RCC_LIST_OPTIONS", RccListOptions_, false) || + !info.GetString("LOCK_FILE", LockFile_, true) || + !info.GetStringConfig("SETTINGS_FILE", SettingsFile_, true) || + !info.GetString("SOURCE", QrcFile_, true) || + !info.GetString("OUTPUT_CHECKSUM", RccPathChecksum_, true) || + !info.GetString("OUTPUT_NAME", RccFileName_, true) || + !info.GetArray("OPTIONS", Options_, false) || + !info.GetArray("INPUTS", Inputs_, false)) { return false; - }; - - // -- Read info file - if (!makefile->ReadListFile(InfoFile())) { - return LogInfoError("File processing failed."); - } - - // - Configurations - Logger_.RaiseVerbosity(InfoGet("ARCC_VERBOSITY")); - MultiConfig_ = makefile->IsOn("ARCC_MULTI_CONFIG"); - - // - Directories - AutogenBuildDir_ = InfoGet("ARCC_BUILD_DIR"); - if (AutogenBuildDir_.empty()) { - return LogInfoError("Build directory empty."); - } - - IncludeDir_ = InfoGetConfig("ARCC_INCLUDE_DIR"); - if (IncludeDir_.empty()) { - return LogInfoError("Include directory empty."); } - // - Rcc executable - RccExecutable_ = InfoGet("ARCC_RCC_EXECUTABLE"); - if (!RccExecutableTime_.Load(RccExecutable_)) { - std::string error = "The rcc executable "; - error += Quoted(RccExecutable_); - error += " does not exist."; - return LogInfoError(error); - } - RccListOptions_ = InfoGetList("ARCC_RCC_LIST_OPTIONS"); - - // - Job - LockFile_ = InfoGet("ARCC_LOCK_FILE"); - QrcFile_ = InfoGet("ARCC_SOURCE"); + // -- Derive information QrcFileName_ = cmSystemTools::GetFilenameName(QrcFile_); QrcFileDir_ = cmSystemTools::GetFilenamePath(QrcFile_); - RccPathChecksum_ = InfoGet("ARCC_OUTPUT_CHECKSUM"); - RccFileName_ = InfoGet("ARCC_OUTPUT_NAME"); - Options_ = InfoGetConfigList("ARCC_OPTIONS"); - Inputs_ = InfoGetList("ARCC_INPUTS"); - - // - Settings file - SettingsFile_ = InfoGetConfig("ARCC_SETTINGS_FILE"); + RccFilePublic_ = + cmStrCat(AutogenBuildDir_, '/', RccPathChecksum_, '/', RccFileName_); - // - Validity checks - if (LockFile_.empty()) { - return LogInfoError("Lock file name missing."); - } - if (SettingsFile_.empty()) { - return LogInfoError("Settings file name missing."); - } - if (AutogenBuildDir_.empty()) { - return LogInfoError("Autogen build directory missing."); - } - if (RccExecutable_.empty()) { - return LogInfoError("rcc executable missing."); - } - if (QrcFile_.empty()) { - return LogInfoError("rcc input file missing."); - } - if (RccFileName_.empty()) { - return LogInfoError("rcc output file missing."); - } - - // Init derived information - // ------------------------ - - RccFilePublic_ = AutogenBuildDir_; - RccFilePublic_ += '/'; - RccFilePublic_ += RccPathChecksum_; - RccFilePublic_ += '/'; - RccFilePublic_ += RccFileName_; - - // Compute rcc output file name + // rcc output file name if (IsMultiConfig()) { - RccFileOutput_ = IncludeDir_; - RccFileOutput_ += '/'; - RccFileOutput_ += MultiConfigOutput(); + RccFileOutput_ = cmStrCat(IncludeDir_, '/', MultiConfigOutput()); } else { RccFileOutput_ = RccFilePublic_; } + // -- Checks + if (!RccExecutableTime_.Load(RccExecutable_)) { + return info.LogError(cmStrCat( + "The rcc executable ", MessagePath(RccExecutable_), " does not exist.")); + } + return true; } -bool cmQtAutoRcc::Process() +bool cmQtAutoRccT::Process() { if (!SettingsFileRead()) { return false; @@ -175,48 +162,38 @@ bool cmQtAutoRcc::Process() return SettingsFileWrite(); } -std::string cmQtAutoRcc::MultiConfigOutput() const +std::string cmQtAutoRccT::MultiConfigOutput() const { - static std::string const suffix = "_CMAKE_"; - std::string res; - res += RccPathChecksum_; - res += '/'; - res += AppendFilenameSuffix(RccFileName_, suffix); - return res; + return cmStrCat(RccPathChecksum_, '/', + AppendFilenameSuffix(RccFileName_, "_CMAKE_")); } -bool cmQtAutoRcc::SettingsFileRead() +bool cmQtAutoRccT::SettingsFileRead() { // Compose current settings strings { - cmCryptoHash crypt(cmCryptoHash::AlgoSHA256); - std::string const sep(" ~~~ "); - { - std::string str; - str += RccExecutable_; - str += sep; - str += cmJoin(RccListOptions_, ";"); - str += sep; - str += QrcFile_; - str += sep; - str += RccPathChecksum_; - str += sep; - str += RccFileName_; - str += sep; - str += cmJoin(Options_, ";"); - str += sep; - str += cmJoin(Inputs_, ";"); - str += sep; - SettingsString_ = crypt.HashString(str); - } + cmCryptoHash cryptoHash(cmCryptoHash::AlgoSHA256); + auto cha = [&cryptoHash](cm::string_view value) { + cryptoHash.Append(value); + cryptoHash.Append(";"); + }; + cha(RccExecutable_); + std::for_each(RccListOptions_.begin(), RccListOptions_.end(), cha); + cha(QrcFile_); + cha(RccPathChecksum_); + cha(RccFileName_); + std::for_each(Options_.begin(), Options_.end(), cha); + std::for_each(Inputs_.begin(), Inputs_.end(), cha); + SettingsString_ = cryptoHash.FinalizeHex(); } // Make sure the settings file exists if (!cmSystemTools::FileExists(SettingsFile_, true)) { // Touch the settings file to make sure it exists if (!cmSystemTools::Touch(SettingsFile_, true)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file creation failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching the settings file ", + MessagePath(SettingsFile_), " failed.")); return false; } } @@ -226,7 +203,9 @@ bool cmQtAutoRcc::SettingsFileRead() // Make sure the lock file exists if (!cmSystemTools::FileExists(LockFile_, true)) { if (!cmSystemTools::Touch(LockFile_, true)) { - Log().ErrorFile(GenT::RCC, LockFile_, "Lock file creation failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching the lock file ", MessagePath(LockFile_), + " failed.")); return false; } } @@ -234,8 +213,9 @@ bool cmQtAutoRcc::SettingsFileRead() cmFileLockResult lockResult = LockFileLock_.Lock(LockFile_, static_cast<unsigned long>(-1)); if (!lockResult.IsOk()) { - Log().ErrorFile(GenT::RCC, LockFile_, - "File lock failed: " + lockResult.GetOutputMessage()); + Log().Error(GenT::RCC, + cmStrCat("Locking of the lock file ", MessagePath(LockFile_), + " failed.\n", lockResult.GetOutputMessage())); return false; } } @@ -251,8 +231,10 @@ bool cmQtAutoRcc::SettingsFileRead() if (SettingsChanged_) { std::string error; if (!FileWrite(SettingsFile_, "", &error)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file clearing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Clearing of the settings file ", + MessagePath(SettingsFile_), " failed.\n", + error)); return false; } } @@ -264,21 +246,21 @@ bool cmQtAutoRcc::SettingsFileRead() return true; } -bool cmQtAutoRcc::SettingsFileWrite() +bool cmQtAutoRccT::SettingsFileWrite() { // Only write if any setting changed if (SettingsChanged_) { if (Log().Verbose()) { - Log().Info(GenT::RCC, "Writing settings file " + Quoted(SettingsFile_)); + Log().Info(GenT::RCC, + "Writing settings file " + MessagePath(SettingsFile_)); } // Write settings file - std::string content = "rcc:"; - content += SettingsString_; - content += '\n'; + std::string content = cmStrCat("rcc:", SettingsString_, '\n'); std::string error; if (!FileWrite(SettingsFile_, content, &error)) { - Log().ErrorFile(GenT::RCC, SettingsFile_, - "Settings file writing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Writing of the settings file ", + MessagePath(SettingsFile_), " failed.\n", error)); // Remove old settings file to trigger a full rebuild on the next run cmSystemTools::RemoveFile(SettingsFile_); return false; @@ -291,25 +273,22 @@ bool cmQtAutoRcc::SettingsFileWrite() } /// Do basic checks if rcc generation is required -bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) +bool cmQtAutoRccT::TestQrcRccFiles(bool& generate) { // Test if the rcc input file exists if (!QrcFileTime_.Load(QrcFile_)) { - std::string error; - error = "The resources file "; - error += Quoted(QrcFile_); - error += " does not exist"; - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().Error(GenT::RCC, + cmStrCat("The resources file ", MessagePath(QrcFile_), + " does not exist")); return false; } // Test if the rcc output file exists if (!RccFileTime_.Load(RccFileOutput_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it doesn't exist, from "; - Reason += Quoted(QrcFile_); + Reason = + cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it doesn't exist, from ", MessagePath(QrcFile_)); } generate = true; return true; @@ -318,10 +297,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the settings changed if (SettingsChanged_) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because the rcc settings changed, from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because the rcc settings changed, from ", + MessagePath(QrcFile_)); } generate = true; return true; @@ -330,12 +308,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the .qrc file if (RccFileTime_.Older(QrcFileTime_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than "; - Reason += Quoted(QrcFile_); - Reason += ", from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it is older than ", MessagePath(QrcFile_), + ", from ", MessagePath(QrcFile_)); } generate = true; return true; @@ -344,10 +319,9 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) // Test if the rcc output file is older than the rcc executable if (RccFileTime_.Older(RccExecutableTime_)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than the rcc executable, from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it is older than the rcc executable, from ", + MessagePath(QrcFile_)); } generate = true; return true; @@ -356,14 +330,16 @@ bool cmQtAutoRcc::TestQrcRccFiles(bool& generate) return true; } -bool cmQtAutoRcc::TestResources(bool& generate) +bool cmQtAutoRccT::TestResources(bool& generate) { // Read resource files list if (Inputs_.empty()) { std::string error; RccLister const lister(RccExecutable_, RccListOptions_); if (!lister.list(QrcFile_, Inputs_, error, Log().Verbose())) { - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().Error( + GenT::RCC, + cmStrCat("Listing of ", MessagePath(QrcFile_), " failed.\n", error)); return false; } } @@ -373,22 +349,18 @@ bool cmQtAutoRcc::TestResources(bool& generate) // Check if the resource file exists cmFileTime fileTime; if (!fileTime.Load(resFile)) { - std::string error; - error = "Could not find the resource file\n "; - error += Quoted(resFile); - error += '\n'; - Log().ErrorFile(GenT::RCC, QrcFile_, error); + Log().Error(GenT::RCC, + cmStrCat("The resource file ", MessagePath(resFile), + " listed in ", MessagePath(QrcFile_), + " does not exist.")); return false; } // Check if the resource file is newer than the rcc output file if (RccFileTime_.Older(fileTime)) { if (Log().Verbose()) { - Reason = "Generating "; - Reason += Quoted(RccFileOutput_); - Reason += ", because it is older than "; - Reason += Quoted(resFile); - Reason += ", from "; - Reason += Quoted(QrcFile_); + Reason = cmStrCat("Generating ", MessagePath(RccFileOutput_), + ", because it is older than ", MessagePath(resFile), + ", from ", MessagePath(QrcFile_)); } generate = true; break; @@ -397,20 +369,21 @@ bool cmQtAutoRcc::TestResources(bool& generate) return true; } -bool cmQtAutoRcc::TestInfoFile() +bool cmQtAutoRccT::TestInfoFile() { // Test if the rcc output file is older than the info file if (RccFileTime_.Older(InfoFileTime())) { if (Log().Verbose()) { - std::string reason = "Touching "; - reason += Quoted(RccFileOutput_); - reason += " because it is older than "; - reason += Quoted(InfoFile()); - Log().Info(GenT::RCC, reason); + Log().Info(GenT::RCC, + cmStrCat("Touching ", MessagePath(RccFileOutput_), + " because it is older than ", + MessagePath(InfoFile()))); } // Touch build file if (!cmSystemTools::Touch(RccFileOutput_, false)) { - Log().ErrorFile(GenT::RCC, RccFileOutput_, "Build file touch failed"); + Log().Error( + GenT::RCC, + cmStrCat("Touching ", MessagePath(RccFileOutput_), " failed.")); return false; } BuildFileChanged_ = true; @@ -419,12 +392,13 @@ bool cmQtAutoRcc::TestInfoFile() return true; } -bool cmQtAutoRcc::GenerateRcc() +bool cmQtAutoRccT::GenerateRcc() { // Make parent directory if (!MakeParentDirectory(RccFileOutput_)) { - Log().ErrorFile(GenT::RCC, RccFileOutput_, - "Could not create parent directory"); + Log().Error(GenT::RCC, + cmStrCat("Could not create parent directory of ", + MessagePath(RccFileOutput_))); return false; } @@ -438,13 +412,9 @@ bool cmQtAutoRcc::GenerateRcc() // Log reason and command if (Log().Verbose()) { - std::string msg = Reason; - if (!msg.empty() && (msg.back() != '\n')) { - msg += '\n'; - } - msg += QuotedCommand(cmd); - msg += '\n'; - Log().Info(GenT::RCC, msg); + Log().Info(GenT::RCC, + cmStrCat(Reason, cmHasSuffix(Reason, '\n') ? "" : "\n", + QuotedCommand(cmd), '\n')); } std::string rccStdOut; @@ -455,13 +425,11 @@ bool cmQtAutoRcc::GenerateRcc() cmSystemTools::OUTPUT_NONE, cmDuration::zero(), cmProcessOutput::Auto); if (!result || (retVal != 0)) { // rcc process failed - { - std::string err = "The rcc process failed to compile\n "; - err += Quoted(QrcFile_); - err += "\ninto\n "; - err += Quoted(RccFileOutput_); - Log().ErrorCommand(GenT::RCC, err, cmd, rccStdOut + rccStdErr); - } + Log().ErrorCommand(GenT::RCC, + cmStrCat("The rcc process failed to compile\n ", + MessagePath(QrcFile_), "\ninto\n ", + MessagePath(RccFileOutput_)), + cmd, rccStdOut + rccStdErr); cmSystemTools::RemoveFile(RccFileOutput_); return false; } @@ -476,17 +444,15 @@ bool cmQtAutoRcc::GenerateRcc() return true; } -bool cmQtAutoRcc::GenerateWrapper() +bool cmQtAutoRccT::GenerateWrapper() { // Generate a wrapper source file on demand if (IsMultiConfig()) { // Wrapper file content - std::string content; - content += "// This is an autogenerated configuration wrapper file.\n"; - content += "// Changes will be overwritten.\n"; - content += "#include <"; - content += MultiConfigOutput(); - content += ">\n"; + std::string content = + cmStrCat("// This is an autogenerated configuration wrapper file.\n", + "// Changes will be overwritten.\n", "#include <", + MultiConfigOutput(), ">\n"); // Compare with existing file content bool fileDiffers = true; @@ -499,25 +465,39 @@ bool cmQtAutoRcc::GenerateWrapper() if (fileDiffers) { // Write new wrapper file if (Log().Verbose()) { - Log().Info(GenT::RCC, "Generating RCC wrapper file " + RccFilePublic_); + Log().Info(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + MessagePath(RccFilePublic_))); } std::string error; if (!FileWrite(RccFilePublic_, content, &error)) { - Log().ErrorFile(GenT::RCC, RccFilePublic_, - "RCC wrapper file writing failed. " + error); + Log().Error(GenT::RCC, + cmStrCat("Generating RCC wrapper file ", + MessagePath(RccFilePublic_), " failed.\n", + error)); return false; } } else if (BuildFileChanged_) { // Just touch the wrapper file if (Log().Verbose()) { - Log().Info(GenT::RCC, "Touching RCC wrapper file " + RccFilePublic_); + Log().Info( + GenT::RCC, + cmStrCat("Touching RCC wrapper file ", MessagePath(RccFilePublic_))); } if (!cmSystemTools::Touch(RccFilePublic_, false)) { - Log().ErrorFile(GenT::RCC, RccFilePublic_, - "RCC wrapper file touch failed."); + Log().Error(GenT::RCC, + cmStrCat("Touching RCC wrapper file ", + MessagePath(RccFilePublic_), " failed.")); return false; } } } return true; } + +} // End of unnamed namespace + +bool cmQtAutoRcc(cm::string_view infoFile, cm::string_view config) +{ + return cmQtAutoRccT().Run(infoFile, config); +} |