summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Holtermann <sebholt@xwmw.org>2017-03-02 13:06:02 (GMT)
committerSebastian Holtermann <sebholt@xwmw.org>2017-03-06 21:01:02 (GMT)
commit699321bfd5a997aceb64649c83ce78044ce11cc1 (patch)
tree89a59851dbf2e1b0448b82c42e65812e5f132768
parenta28ae16e3cd6d42ab068b5bc0bedf5725a6ce743 (diff)
downloadCMake-699321bfd5a997aceb64649c83ce78044ce11cc1.zip
CMake-699321bfd5a997aceb64649c83ce78044ce11cc1.tar.gz
CMake-699321bfd5a997aceb64649c83ce78044ce11cc1.tar.bz2
Autogen: Add support for generated .qrc files
-rw-r--r--Source/cmQtAutoGeneratorCommon.cxx131
-rw-r--r--Source/cmQtAutoGeneratorCommon.h7
-rw-r--r--Source/cmQtAutoGeneratorInitializer.cxx15
-rw-r--r--Source/cmQtAutoGenerators.cxx66
4 files changed, 142 insertions, 77 deletions
diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGeneratorCommon.cxx
index 5146b1a..dcd61a3 100644
--- a/Source/cmQtAutoGeneratorCommon.cxx
+++ b/Source/cmQtAutoGeneratorCommon.cxx
@@ -24,47 +24,62 @@ static std::string utilStripCR(std::string const& 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(const std::string& fileName,
- std::vector<std::string>& files)
+ std::vector<std::string>& files,
+ std::string* errorMessage)
{
- // Qrc file directory
- std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName));
- if (!qrcDir.empty()) {
- qrcDir += '/';
- }
-
- // Read file into string
+ bool allGood = true;
+ // Read qrc file content into string
std::string qrcContents;
{
- std::ostringstream stream;
- stream << cmsys::ifstream(fileName).rdbuf();
- qrcContents = stream.str();
+ cmsys::ifstream ifs(fileName.c_str());
+ if (ifs) {
+ std::ostringstream osst;
+ osst << ifs.rdbuf();
+ qrcContents = osst.str();
+ } else {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc file not readable:\n"
+ << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ *errorMessage = ost.str();
+ }
+ allGood = false;
+ }
}
-
- cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
- cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
-
- size_t offset = 0;
- while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
- std::string qrcEntry = fileMatchRegex.match(1);
- offset += qrcEntry.size();
- {
- fileReplaceRegex.find(qrcEntry);
- std::string tag = fileReplaceRegex.match(1);
- qrcEntry = qrcEntry.substr(tag.size());
+ if (allGood) {
+ // qrc file directory
+ std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName));
+ if (!qrcDir.empty()) {
+ qrcDir += '/';
}
- if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
- qrcEntry = qrcDir + qrcEntry;
+
+ cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");
+ cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
+
+ size_t offset = 0;
+ while (fileMatchRegex.find(qrcContents.c_str() + offset)) {
+ std::string qrcEntry = fileMatchRegex.match(1);
+ offset += qrcEntry.size();
+ {
+ fileReplaceRegex.find(qrcEntry);
+ std::string tag = fileReplaceRegex.match(1);
+ qrcEntry = qrcEntry.substr(tag.size());
+ }
+ if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str())) {
+ qrcEntry = qrcDir + qrcEntry;
+ }
+ files.push_back(qrcEntry);
}
- files.push_back(qrcEntry);
}
- return true;
+ return allGood;
}
/// @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(const std::string& rccCommand,
const std::string& fileName,
- std::vector<std::string>& files)
+ std::vector<std::string>& files,
+ std::string* errorMessage)
{
if (rccCommand.empty()) {
cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n");
@@ -104,11 +119,14 @@ static bool RccListInputsQt5(const std::string& rccCommand,
CM_NULLPTR, cmSystemTools::OUTPUT_NONE);
}
if (!result || retVal) {
- std::ostringstream err;
- err << "AUTOGEN: error: Rcc list process for " << fileName << " failed:\n"
- << rccStdOut << "\n"
- << rccStdErr << std::endl;
- cmSystemTools::Error(err.str().c_str());
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc list process for " << fileName
+ << " failed:\n"
+ << rccStdOut << "\n"
+ << rccStdErr << "\n";
+ *errorMessage = ost.str();
+ }
return false;
}
@@ -134,10 +152,12 @@ static bool RccListInputsQt5(const std::string& rccCommand,
std::string::size_type pos = eline.find(searchString);
if (pos == std::string::npos) {
- std::ostringstream err;
- err << "AUTOGEN: error: Rcc lists unparsable output " << eline
- << std::endl;
- cmSystemTools::Error(err.str().c_str());
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc lists unparsable output:\n"
+ << cmQtAutoGeneratorCommon::Quoted(eline) << "\n";
+ *errorMessage = ost.str();
+ }
return false;
}
pos += searchString.length();
@@ -154,13 +174,42 @@ static bool RccListInputsQt5(const std::string& rccCommand,
const char* cmQtAutoGeneratorCommon::listSep = "@LSEP@";
+std::string cmQtAutoGeneratorCommon::Quoted(const std::string& text)
+{
+ static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a",
+ "\b", "\\b", "\f", "\\f", "\n", "\\n",
+ "\r", "\\r", "\t", "\\t", "\v", "\\v" };
+
+ std::string res = text;
+ for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep);
+ it += 2) {
+ cmSystemTools::ReplaceString(res, *it, *(it + 1));
+ }
+ res = '"' + res;
+ res += '"';
+ return res;
+}
+
bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion,
const std::string& rccCommand,
const std::string& fileName,
- std::vector<std::string>& files)
+ std::vector<std::string>& files,
+ std::string* errorMessage)
{
- if (qtMajorVersion == "4") {
- return RccListInputsQt4(fileName, files);
+ bool allGood = false;
+ if (cmsys::SystemTools::FileExists(fileName.c_str())) {
+ if (qtMajorVersion == "4") {
+ allGood = RccListInputsQt4(fileName, files, errorMessage);
+ } else {
+ allGood = RccListInputsQt5(rccCommand, fileName, files, errorMessage);
+ }
+ } else {
+ if (errorMessage != CM_NULLPTR) {
+ std::ostringstream ost;
+ ost << "AutoRcc: Error: Rcc file does not exist:\n"
+ << cmQtAutoGeneratorCommon::Quoted(fileName) << "\n";
+ *errorMessage = ost.str();
+ }
}
- return RccListInputsQt5(rccCommand, fileName, files);
+ return allGood;
}
diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGeneratorCommon.h
index 48abacb..ee97b71 100644
--- a/Source/cmQtAutoGeneratorCommon.h
+++ b/Source/cmQtAutoGeneratorCommon.h
@@ -17,13 +17,18 @@ public:
static const char* listSep;
public:
+ /// @brief Returns a the string escaped and enclosed in quotes
+ ///
+ static std::string Quoted(const std::string& text);
+
/// @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(const std::string& qtMajorVersion,
const std::string& rccCommand,
const std::string& fileName,
- std::vector<std::string>& files);
+ std::vector<std::string>& files,
+ std::string* errorMessage = CM_NULLPTR);
};
#endif
diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx
index 0f29e02..2b53982 100644
--- a/Source/cmQtAutoGeneratorInitializer.cxx
+++ b/Source/cmQtAutoGeneratorInitializer.cxx
@@ -490,13 +490,15 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target,
// qrc file entries
{
std::string entriesList = "{";
+ // Read input file list only for non generated .qrc files.
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
+ std::string error;
std::vector<std::string> files;
if (cmQtAutoGeneratorCommon::RccListInputs(
- qtMajorVersion, rccCommand, absFile, files)) {
+ qtMajorVersion, rccCommand, absFile, files, &error)) {
entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep);
} else {
- return;
+ cmSystemTools::Error(error.c_str());
}
}
entriesList += "}";
@@ -690,8 +692,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
#endif
) {
if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) {
- cmQtAutoGeneratorCommon::RccListInputs(
- qtMajorVersion, rccCommand, absFile, depends);
+ {
+ std::string error;
+ if (!cmQtAutoGeneratorCommon::RccListInputs(
+ qtMajorVersion, rccCommand, absFile, depends, &error)) {
+ cmSystemTools::Error(error.c_str());
+ }
+ }
#if defined(_WIN32) && !defined(__CYGWIN__)
// Cannot use PRE_BUILD because the resource files themselves
// may not be sources within the target so VS may not know the
diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx
index 4d14e99..2510066 100644
--- a/Source/cmQtAutoGenerators.cxx
+++ b/Source/cmQtAutoGenerators.cxx
@@ -37,23 +37,9 @@ static const char* SettingsKeyRcc = "AM_RCC_OLD_SETTINGS";
// -- Static functions
-/**
- * @brief Returns a the string escaped and enclosed in quotes
- */
-static std::string Quoted(const std::string& text)
+inline static std::string Quoted(const std::string& text)
{
- static const char* rep[18] = { "\\", "\\\\", "\"", "\\\"", "\a", "\\a",
- "\b", "\\b", "\f", "\\f", "\n", "\\n",
- "\r", "\\r", "\t", "\\t", "\v", "\\v" };
-
- std::string res = text;
- for (const char* const* it = cmArrayBegin(rep); it != cmArrayEnd(rep);
- it += 2) {
- cmSystemTools::ReplaceString(res, *it, *(it + 1));
- }
- res = '"' + res;
- res += '"';
- return res;
+ return cmQtAutoGeneratorCommon::Quoted(text);
}
static void InfoGet(cmMakefile* makefile, const char* key, std::string& value)
@@ -403,7 +389,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
} else {
this->LogError(
"AutoMoc: Error: AUTOMOC_DEPEND_FILTERS list size is not "
- "a multiple of 2");
+ "a multiple of 2 in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -431,8 +418,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
} else {
this->LogError(
- "AutoGen: Error: Uic files/options lists size missmatch in: " +
- filename);
+ "AutoGen: Error: Uic files/options lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -447,7 +434,7 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
std::vector<std::string> rccOptionsVec;
InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec);
InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec);
- if (rccFilesVec.size() != rccOptionsVec.size()) {
+ if (rccFilesVec.size() == rccOptionsVec.size()) {
for (std::vector<std::string>::iterator
fileIt = rccFilesVec.begin(),
optionIt = rccOptionsVec.begin();
@@ -459,8 +446,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
} else {
this->LogError(
- "AutoGen: Error: RCC files/options lists size missmatch in: " +
- filename);
+ "AutoGen: Error: RCC files/options lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -484,8 +471,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile(
}
} else {
this->LogError(
- "AutoGen: Error: RCC sources/inputs lists size missmatch in: " +
- filename);
+ "AutoGen: Error: RCC sources/inputs lists size missmatch in:\n" +
+ Quoted(filename));
return false;
}
}
@@ -1574,13 +1561,30 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile,
// Test if the resources list file is newer than build file
generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile);
if (!generateRcc) {
- // Test if any resource file is newer than the build file
- const std::vector<std::string>& files = this->RccInputs[rccInputFile];
- for (std::vector<std::string>::const_iterator it = files.begin();
- it != files.end(); ++it) {
- if (FileAbsentOrOlder(rccBuildFile, *it)) {
- generateRcc = true;
- break;
+ // Acquire input file list
+ std::vector<std::string> readFiles;
+ const std::vector<std::string>* files = &this->RccInputs[rccInputFile];
+ if (files->empty()) {
+ // Read input file list from qrc file
+ std::string error;
+ if (cmQtAutoGeneratorCommon::RccListInputs(
+ this->QtMajorVersion, this->RccExecutable, rccInputFile,
+ readFiles, &error)) {
+ files = &readFiles;
+ } else {
+ files = CM_NULLPTR;
+ this->LogError(error);
+ this->RunRccFailed = true;
+ }
+ }
+ // Test if any input file is newer than the build file
+ if (files != CM_NULLPTR) {
+ for (std::vector<std::string>::const_iterator it = files->begin();
+ it != files->end(); ++it) {
+ if (FileAbsentOrOlder(rccBuildFile, *it)) {
+ generateRcc = true;
+ break;
+ }
}
}
}