summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2017-11-19 11:22:49 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2017-11-19 12:12:42 (GMT)
commitab9d5896ae43789872fca2e83d556912abb60254 (patch)
treed18add395533b65ee0c04c59cf823553a82aaa33
parent2a85b5ac768cde4a9bbe98551528c8bae1e268a8 (diff)
downloadCMake-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.in4
-rw-r--r--Source/cmQtAutoGen.cxx91
-rw-r--r--Source/cmQtAutoGen.h6
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx98
-rw-r--r--Source/cmQtAutoGeneratorInitializer.h3
-rw-r--r--Source/cmQtAutoGeneratorRcc.cxx8
-rw-r--r--Source/cmQtAutoGeneratorRcc.h2
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;