diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2017-11-19 11:22:49 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2017-11-19 12:12:42 (GMT) |
commit | ab9d5896ae43789872fca2e83d556912abb60254 (patch) | |
tree | d18add395533b65ee0c04c59cf823553a82aaa33 | |
parent | 2a85b5ac768cde4a9bbe98551528c8bae1e268a8 (diff) | |
download | CMake-ab9d5896ae43789872fca2e83d556912abb60254.zip CMake-ab9d5896ae43789872fca2e83d556912abb60254.tar.gz CMake-ab9d5896ae43789872fca2e83d556912abb60254.tar.bz2 |
Autogen: Detect rcc feature once during configuration
We used to detect the `rcc` features before every `rcc` list invocation
wich resulted in `rcc` be called twice for every listing operation.
Now we detect the `rcc` list capabilities once during configuration and
pass it to the cmake_autorcc target in the info file.
-rw-r--r-- | Modules/AutoRccInfo.cmake.in | 4 | ||||
-rw-r--r-- | Source/cmQtAutoGen.cxx | 91 | ||||
-rw-r--r-- | Source/cmQtAutoGen.h | 6 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 98 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.h | 3 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorRcc.cxx | 8 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorRcc.h | 2 |
7 files changed, 109 insertions, 103 deletions
diff --git a/Modules/AutoRccInfo.cmake.in b/Modules/AutoRccInfo.cmake.in index 7b13b9e..5457a6f 100644 --- a/Modules/AutoRccInfo.cmake.in +++ b/Modules/AutoRccInfo.cmake.in @@ -7,5 +7,5 @@ set(ARCC_CMAKE_CURRENT_SOURCE_DIR "@CMAKE_CURRENT_SOURCE_DIR@/") set(ARCC_CMAKE_CURRENT_BINARY_DIR "@CMAKE_CURRENT_BINARY_DIR@/") set(ARCC_BUILD_DIR @_build_dir@) # Qt environment -set(ARCC_QT_VERSION_MAJOR @_qt_version_major@) -set(ARCC_QT_RCC_EXECUTABLE @_qt_rcc_executable@) +set(ARCC_RCC_EXECUTABLE @_qt_rcc_executable@) +set(ARCC_RCC_LIST_OPTIONS @_qt_rcc_list_options@) diff --git a/Source/cmQtAutoGen.cxx b/Source/cmQtAutoGen.cxx index 9dc77ac..b9dd392 100644 --- a/Source/cmQtAutoGen.cxx +++ b/Source/cmQtAutoGen.cxx @@ -80,16 +80,6 @@ void MergeOptions(std::vector<std::string>& baseOpts, baseOpts.insert(baseOpts.end(), extraOpts.begin(), extraOpts.end()); } -static std::string utilStripCR(std::string const& line) -{ - // Strip CR characters rcc may have printed (possibly more than one!). - std::string::size_type cr = line.find('\r'); - if (cr != std::string::npos) { - return line.substr(0, cr); - } - return line; -} - /// @brief Reads the resource files list from from a .qrc file - Qt4 version /// @return True if the .qrc file was successfully parsed static bool RccListInputsQt4(std::string const& fileName, @@ -107,10 +97,10 @@ static bool RccListInputsQt4(std::string const& fileName, qrcContents = osst.str(); } else { if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "rcc file not readable:\n" - << " " << cmQtAutoGen::Quoted(fileName) << "\n"; - *errorMessage = ost.str(); + std::string& err = *errorMessage; + err = "rcc file not readable:\n "; + err += cmQtAutoGen::Quoted(fileName); + err += "\n"; } allGood = false; } @@ -146,6 +136,7 @@ static bool RccListInputsQt4(std::string const& fileName, /// @brief Reads the resource files list from from a .qrc file - Qt5 version /// @return True if the .qrc file was successfully parsed static bool RccListInputsQt5(std::string const& rccCommand, + std::vector<std::string> const& rccListOptions, std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage) @@ -155,24 +146,6 @@ static bool RccListInputsQt5(std::string const& rccCommand, return false; } - // Read rcc features - bool hasDashDashList = false; - { - std::vector<std::string> command; - command.push_back(rccCommand); - command.push_back("--help"); - std::string rccStdOut; - std::string rccStdErr; - int retVal = 0; - bool result = cmSystemTools::RunSingleCommand( - command, &rccStdOut, &rccStdErr, &retVal, nullptr, - cmSystemTools::OUTPUT_NONE, 0.0, cmProcessOutput::Auto); - if (result && retVal == 0 && - rccStdOut.find("--list") != std::string::npos) { - hasDashDashList = true; - } - } - std::string const fileDir = cmSystemTools::GetFilenamePath(fileName); std::string const fileNameName = cmSystemTools::GetFilenameName(fileName); @@ -184,7 +157,8 @@ static bool RccListInputsQt5(std::string const& rccCommand, { std::vector<std::string> command; command.push_back(rccCommand); - command.push_back(hasDashDashList ? "--list" : "-list"); + command.insert(command.end(), rccListOptions.begin(), + rccListOptions.end()); command.push_back(fileNameName); result = cmSystemTools::RunSingleCommand( command, &rccStdOut, &rccStdErr, &retVal, fileDir.c_str(), @@ -192,22 +166,32 @@ static bool RccListInputsQt5(std::string const& rccCommand, } if (!result || retVal) { if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "rcc list process failed for\n " << cmQtAutoGen::Quoted(fileName) - << "\n" - << rccStdOut << "\n" - << rccStdErr << "\n"; - *errorMessage = ost.str(); + std::string& err = *errorMessage; + err = "rcc list process failed for:\n "; + err += cmQtAutoGen::Quoted(fileName); + err += "\n"; + err += rccStdOut; + err += "\n"; + err += rccStdErr; + err += "\n"; } return false; } + // Lambda to strip CR characters + auto StripCR = [](std::string& line) { + std::string::size_type cr = line.find('\r'); + if (cr != std::string::npos) { + line = line.substr(0, cr); + } + }; + // Parse rcc std output { std::istringstream ostr(rccStdOut); std::string oline; while (std::getline(ostr, oline)) { - oline = utilStripCR(oline); + StripCR(oline); if (!oline.empty()) { files.push_back(oline); } @@ -218,17 +202,17 @@ static bool RccListInputsQt5(std::string const& rccCommand, std::istringstream estr(rccStdErr); std::string eline; while (std::getline(estr, eline)) { - eline = utilStripCR(eline); + StripCR(eline); if (cmHasLiteralPrefix(eline, "RCC: Error in")) { static std::string searchString = "Cannot find file '"; std::string::size_type pos = eline.find(searchString); if (pos == std::string::npos) { if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "rcc lists unparsable output:\n" - << cmQtAutoGen::Quoted(eline) << "\n"; - *errorMessage = ost.str(); + std::string& err = *errorMessage; + err = "rcc lists unparsable output:\n"; + err += cmQtAutoGen::Quoted(eline); + err += "\n"; } return false; } @@ -349,25 +333,26 @@ void cmQtAutoGen::RccMergeOptions(std::vector<std::string>& baseOpts, MergeOptions(baseOpts, newOpts, valueOpts, isQt5); } -bool cmQtAutoGen::RccListInputs(std::string const& qtMajorVersion, - std::string const& rccCommand, +bool cmQtAutoGen::RccListInputs(std::string const& rccCommand, + std::vector<std::string> const& rccListOptions, std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage) { bool allGood = false; if (cmSystemTools::FileExists(fileName.c_str())) { - if (qtMajorVersion == "4") { + if (rccListOptions.empty()) { allGood = RccListInputsQt4(fileName, files, errorMessage); } else { - allGood = RccListInputsQt5(rccCommand, fileName, files, errorMessage); + allGood = RccListInputsQt5(rccCommand, rccListOptions, fileName, files, + errorMessage); } } else { if (errorMessage != nullptr) { - std::ostringstream ost; - ost << "rcc file does not exist:\n" - << " " << cmQtAutoGen::Quoted(fileName) << "\n"; - *errorMessage = ost.str(); + std::string& err = *errorMessage; + err = "rcc resource file does not exist:\n "; + err += cmQtAutoGen::Quoted(fileName); + err += "\n"; } } return allGood; diff --git a/Source/cmQtAutoGen.h b/Source/cmQtAutoGen.h index acc092f..e769e93 100644 --- a/Source/cmQtAutoGen.h +++ b/Source/cmQtAutoGen.h @@ -61,9 +61,9 @@ public: /// @brief Reads the resource files list from from a .qrc file /// @arg fileName Must be the absolute path of the .qrc file - /// @return True if the rcc file was successfully parsed - static bool RccListInputs(std::string const& qtMajorVersion, - std::string const& rccCommand, + /// @return True if the rcc file was successfully read + static bool RccListInputs(std::string const& rccCommand, + std::vector<std::string> const& rccListOptions, std::string const& fileName, std::vector<std::string>& files, std::string* errorMessage = nullptr); diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 5edddaa..b265f28 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -14,6 +14,7 @@ #include "cmMakefile.h" #include "cmOutputConverter.h" #include "cmPolicies.h" +#include "cmProcessOutput.h" #include "cmSourceFile.h" #include "cmSourceGroup.h" #include "cmState.h" @@ -190,40 +191,6 @@ static bool StaticLibraryCycle(cmGeneratorTarget const* targetOrigin, return cycle; } -static std::string RccGetExecutable(cmGeneratorTarget const* target, - std::string const& qtMajorVersion) -{ - std::string rccExec; - std::string err; - - cmLocalGenerator* localGen = target->GetLocalGenerator(); - if (qtMajorVersion == "5") { - cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt5::rcc"); - if (tgt != nullptr) { - rccExec = SafeString(tgt->ImportedGetLocation("")); - } else { - err = "AUTORCC: Qt5::rcc target not found"; - } - } else if (qtMajorVersion == "4") { - cmGeneratorTarget* tgt = localGen->FindGeneratorTargetToUse("Qt4::rcc"); - if (tgt != nullptr) { - rccExec = SafeString(tgt->ImportedGetLocation("")); - } else { - err = "AUTORCC: Qt4::rcc target not found"; - } - } else { - err = "The AUTORCC feature supports only Qt 4 and Qt 5"; - } - - if (!err.empty()) { - err += " ("; - err += target->GetName(); - err += ")"; - cmSystemTools::Error(err.c_str()); - } - return rccExec; -} - cmQtAutoGeneratorInitializer::cmQtAutoGeneratorInitializer( cmGeneratorTarget* target, bool mocEnabled, bool uicEnabled, bool rccEnabled, std::string const& qtVersionMajor) @@ -368,6 +335,56 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets() this->Target->AddIncludeDirectory(includeDir, true); } + // Acquire rcc executable and features + if (this->RccEnabled) { + { + std::string err; + if (this->QtVersionMajor == "5") { + cmGeneratorTarget* tgt = + localGen->FindGeneratorTargetToUse("Qt5::rcc"); + if (tgt != nullptr) { + this->RccExecutable = SafeString(tgt->ImportedGetLocation("")); + } else { + err = "AUTORCC: Qt5::rcc target not found"; + } + } else if (QtVersionMajor == "4") { + cmGeneratorTarget* tgt = + localGen->FindGeneratorTargetToUse("Qt4::rcc"); + if (tgt != nullptr) { + this->RccExecutable = SafeString(tgt->ImportedGetLocation("")); + } else { + err = "AUTORCC: Qt4::rcc target not found"; + } + } else { + err = "The AUTORCC feature supports only Qt 4 and Qt 5"; + } + if (!err.empty()) { + err += " ("; + err += this->Target->GetName(); + err += ")"; + cmSystemTools::Error(err.c_str()); + } + } + // Detect if rcc supports (-)-list + if (!this->RccExecutable.empty() && (this->QtVersionMajor == "5")) { + std::vector<std::string> command; + command.push_back(this->RccExecutable); + command.push_back("--help"); + std::string rccStdOut; + std::string rccStdErr; + int retVal = 0; + bool result = cmSystemTools::RunSingleCommand( + command, &rccStdOut, &rccStdErr, &retVal, nullptr, + cmSystemTools::OUTPUT_NONE, 0.0, cmProcessOutput::Auto); + if (result && retVal == 0 && + rccStdOut.find("--list") != std::string::npos) { + this->RccListOptions.push_back("--list"); + } else { + this->RccListOptions.push_back("-list"); + } + } + } + // Extract relevant source files std::vector<std::string> generatedSources; std::vector<std::string> generatedHeaders; @@ -548,8 +565,6 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets() // Process qrc files if (!this->Qrcs.empty()) { const bool QtV5 = (this->QtVersionMajor == "5"); - std::string const rcc = - RccGetExecutable(this->Target, this->QtVersionMajor); // Target rcc options std::vector<std::string> optionsTarget; cmSystemTools::ExpandListArgument( @@ -673,9 +688,9 @@ void cmQtAutoGeneratorInitializer::InitCustomTargets() // Add the resource files to the dependencies { std::string error; - if (cmQtAutoGen::RccListInputs(this->QtVersionMajor, rcc, - qrc.QrcFile, qrc.Resources, - &error)) { + if (cmQtAutoGen::RccListInputs(this->RccExecutable, + this->RccListOptions, qrc.QrcFile, + qrc.Resources, &error)) { for (std::string const& fileName : qrc.Resources) { // Add resource file to the custom command dependencies ccDepends.push_back(fileName); @@ -881,8 +896,9 @@ void cmQtAutoGeneratorInitializer::SetupCustomTargets() } } if (this->RccEnabled) { - AddDefinitionEscaped(makefile, "_qt_rcc_executable", - RccGetExecutable(this->Target, this->QtVersionMajor)); + AddDefinitionEscaped(makefile, "_qt_rcc_executable", this->RccExecutable); + AddDefinitionEscaped(makefile, "_qt_rcc_list_options", + this->RccListOptions); } // Create info directory on demand diff --git a/Source/cmQtAutoGeneratorInitializer.h b/Source/cmQtAutoGeneratorInitializer.h index 9eebbd6..e06e1c4 100644 --- a/Source/cmQtAutoGeneratorInitializer.h +++ b/Source/cmQtAutoGeneratorInitializer.h @@ -65,8 +65,11 @@ private: bool MocEnabled; bool UicEnabled; bool RccEnabled; + // Qt std::string QtVersionMajor; std::string QtVersionMinor; + std::string RccExecutable; + std::vector<std::string> RccListOptions; // Configurations std::string ConfigDefault; std::vector<std::string> ConfigsList; diff --git a/Source/cmQtAutoGeneratorRcc.cxx b/Source/cmQtAutoGeneratorRcc.cxx index 573f04c..3c9f1a8 100644 --- a/Source/cmQtAutoGeneratorRcc.cxx +++ b/Source/cmQtAutoGeneratorRcc.cxx @@ -78,8 +78,8 @@ bool cmQtAutoGeneratorRcc::InfoFileRead(cmMakefile* makefile) this->AutogenBuildDir = InfoGet("ARCC_BUILD_DIR"); // - Qt environment - this->QtMajorVersion = InfoGet("ARCC_QT_VERSION_MAJOR"); - this->RccExecutable = InfoGet("ARCC_QT_RCC_EXECUTABLE"); + this->RccExecutable = InfoGet("ARCC_RCC_EXECUTABLE"); + this->RccListOptions = InfoGetList("ARCC_RCC_LIST_OPTIONS"); // - Job this->QrcFile = InfoGet("ARCC_SOURCE"); @@ -135,6 +135,8 @@ void cmQtAutoGeneratorRcc::SettingsFileRead(cmMakefile* makefile) std::string str; str += this->RccExecutable; str += sep; + str += cmJoin(this->RccListOptions, ";"); + str += sep; str += this->QrcFile; str += sep; str += this->RccFile; @@ -307,7 +309,7 @@ bool cmQtAutoGeneratorRcc::RccGenerate() } else { // Read input file list from qrc file std::string error; - if (cmQtAutoGen::RccListInputs(this->QtMajorVersion, this->RccExecutable, + if (cmQtAutoGen::RccListInputs(this->RccExecutable, this->RccListOptions, this->QrcFile, readFiles, &error)) { files = &readFiles; } else { diff --git a/Source/cmQtAutoGeneratorRcc.h b/Source/cmQtAutoGeneratorRcc.h index 804d117..0e3f690 100644 --- a/Source/cmQtAutoGeneratorRcc.h +++ b/Source/cmQtAutoGeneratorRcc.h @@ -44,8 +44,8 @@ private: std::string AutogenBuildDir; cmFilePathChecksum FilePathChecksum; // -- Qt environment - std::string QtMajorVersion; std::string RccExecutable; + std::vector<std::string> RccListOptions; // -- Job std::string QrcFile; std::string RccFile; |