diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2017-03-02 13:06:02 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2017-03-06 21:01:02 (GMT) |
commit | 699321bfd5a997aceb64649c83ce78044ce11cc1 (patch) | |
tree | 89a59851dbf2e1b0448b82c42e65812e5f132768 /Source | |
parent | a28ae16e3cd6d42ab068b5bc0bedf5725a6ce743 (diff) | |
download | CMake-699321bfd5a997aceb64649c83ce78044ce11cc1.zip CMake-699321bfd5a997aceb64649c83ce78044ce11cc1.tar.gz CMake-699321bfd5a997aceb64649c83ce78044ce11cc1.tar.bz2 |
Autogen: Add support for generated .qrc files
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmQtAutoGeneratorCommon.cxx | 131 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorCommon.h | 7 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 15 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 66 |
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; + } } } } |