From 47dbe9267eea47e7be656da409a9ee8ced691422 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Tue, 28 Feb 2017 12:08:26 +0100 Subject: Autogen: Add cmQtAutogeneratorCommon class with shared types and functions --- Source/CMakeLists.txt | 2 + Source/cmQtAutoGeneratorCommon.cxx | 166 ++++++++++++++++++++++++++++ Source/cmQtAutoGeneratorCommon.h | 29 +++++ Source/cmQtAutoGeneratorInitializer.cxx | 186 +++++--------------------------- Source/cmQtAutoGenerators.cxx | 12 ++- 5 files changed, 229 insertions(+), 166 deletions(-) create mode 100644 Source/cmQtAutoGeneratorCommon.cxx create mode 100644 Source/cmQtAutoGeneratorCommon.h diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 76b98fc..5f2cbc3 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -344,6 +344,8 @@ set(SRCS cmPropertyDefinitionMap.h cmPropertyMap.cxx cmPropertyMap.h + cmQtAutoGeneratorCommon.cxx + cmQtAutoGeneratorCommon.h cmQtAutoGeneratorInitializer.cxx cmQtAutoGeneratorInitializer.h cmQtAutoGenerators.cxx diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGeneratorCommon.cxx new file mode 100644 index 0000000..c42f71d --- /dev/null +++ b/Source/cmQtAutoGeneratorCommon.cxx @@ -0,0 +1,166 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#include "cmQtAutoGeneratorCommon.h" +#include "cmAlgorithms.h" +#include "cmSystemTools.h" + +#include +#include + +#include + +// - Static functions + +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 != line.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(const std::string& fileName, + std::vector& files) +{ + // Qrc file directory + std::string qrcDir(cmsys::SystemTools::GetFilenamePath(fileName)); + if (!qrcDir.empty()) { + qrcDir += '/'; + } + + // Read file into string + std::string qrcContents; + { + std::ostringstream stream; + stream << cmsys::ifstream(fileName).rdbuf(); + qrcContents = stream.str(); + } + + cmsys::RegularExpression fileMatchRegex("(]*>)"); + + 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); + } + return true; +} + +/// @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& files) +{ + if (rccCommand.empty()) { + cmSystemTools::Error("AutoRcc: Error: rcc executable not available\n"); + return false; + } + + // Read rcc features + bool hasDashDashList = false; + { + std::vector 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, + CM_NULLPTR, cmSystemTools::OUTPUT_NONE); + if (result && retVal == 0 && + rccStdOut.find("--list") != std::string::npos) { + hasDashDashList = true; + } + } + + // Run rcc list command + bool result = false; + int retVal = 0; + std::string rccStdOut; + std::string rccStdErr; + { + std::vector command; + command.push_back(rccCommand); + command.push_back(hasDashDashList ? "--list" : "-list"); + command.push_back(fileName); + result = + cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, + 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()); + return false; + } + + // Parse rcc std output + { + std::istringstream ostr(rccStdOut); + std::string oline; + while (std::getline(ostr, oline)) { + oline = utilStripCR(oline); + if (!oline.empty()) { + files.push_back(oline); + } + } + } + // Parse rcc error output + { + std::istringstream estr(rccStdErr); + std::string eline; + while (std::getline(estr, eline)) { + eline = utilStripCR(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) { + std::ostringstream err; + err << "AUTOGEN: error: Rcc lists unparsable output " << eline + << std::endl; + cmSystemTools::Error(err.str().c_str()); + return false; + } + pos += searchString.length(); + std::string::size_type sz = eline.size() - pos - 1; + files.push_back(eline.substr(pos, sz)); + } + } + } + + return true; +} + +// - Class definitions + +const char* cmQtAutoGeneratorCommon::listSep = "@list_sep@"; + +bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion, + const std::string& rccCommand, + const std::string& fileName, + std::vector& files) +{ + if (qtMajorVersion == "4") { + return RccListInputsQt4(fileName, files); + } + return RccListInputsQt5(rccCommand, fileName, files); +} diff --git a/Source/cmQtAutoGeneratorCommon.h b/Source/cmQtAutoGeneratorCommon.h new file mode 100644 index 0000000..48abacb --- /dev/null +++ b/Source/cmQtAutoGeneratorCommon.h @@ -0,0 +1,29 @@ +/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying + file Copyright.txt or https://cmake.org/licensing for details. */ +#ifndef cmQtAutoGeneratorCommon_h +#define cmQtAutoGeneratorCommon_h + +#include // IWYU pragma: keep +#include +#include + +class cmGeneratorTarget; +class cmLocalGenerator; + +class cmQtAutoGeneratorCommon +{ + // - Types and statics +public: + static const char* listSep; + +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(const std::string& qtMajorVersion, + const std::string& rccCommand, + const std::string& fileName, + std::vector& files); +}; + +#endif diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index a45b3d5..3a7951a 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -1,6 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGeneratorInitializer.h" +#include "cmQtAutoGeneratorCommon.h" #include "cmAlgorithms.h" #include "cmCustomCommandLines.h" @@ -44,16 +45,6 @@ static void utilCopyTargetProperty(cmTarget* destinationTarget, } } -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 != line.npos) { - return line.substr(0, cr); - } - return line; -} - static std::string GetSafeProperty(cmGeneratorTarget const* target, const char* key) { @@ -361,7 +352,8 @@ static void UicSetupAutoTarget( uiFileFiles.push_back(absFile); { std::string opts = sf->GetProperty("AUTOUIC_OPTIONS"); - cmSystemTools::ReplaceString(opts, ";", "@list_sep@"); + cmSystemTools::ReplaceString(opts, ";", + cmQtAutoGeneratorCommon::listSep); uiFileOptions.push_back(opts); } } @@ -469,146 +461,12 @@ static void RccMergeOptions(std::vector& opts, opts.insert(opts.end(), extraOpts.begin(), extraOpts.end()); } -/// @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(cmSourceFile* sf, cmGeneratorTarget const* target, - std::vector& depends) -{ - const std::string rccCommand = RccGetExecutable(target, "5"); - if (rccCommand.empty()) { - cmSystemTools::Error("AUTOGEN: error: rcc executable not available\n"); - return false; - } - - bool hasDashDashList = false; - // Read rcc features - { - std::vector 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, - CM_NULLPTR, cmSystemTools::OUTPUT_NONE); - if (result && retVal == 0 && - rccStdOut.find("--list") != std::string::npos) { - hasDashDashList = true; - } - } - // Run rcc list command - std::vector command; - command.push_back(rccCommand); - command.push_back(hasDashDashList ? "--list" : "-list"); - - std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); - command.push_back(absFile); - - std::string rccStdOut; - std::string rccStdErr; - int retVal = 0; - bool result = - cmSystemTools::RunSingleCommand(command, &rccStdOut, &rccStdErr, &retVal, - CM_NULLPTR, cmSystemTools::OUTPUT_NONE); - if (!result || retVal) { - std::ostringstream err; - err << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath() - << " failed:\n" - << rccStdOut << "\n" - << rccStdErr << std::endl; - cmSystemTools::Error(err.str().c_str()); - return false; - } - - // Parse rcc list output - { - std::istringstream ostr(rccStdOut); - std::string oline; - while (std::getline(ostr, oline)) { - oline = utilStripCR(oline); - if (!oline.empty()) { - depends.push_back(oline); - } - } - } - - { - std::istringstream estr(rccStdErr); - std::string eline; - while (std::getline(estr, eline)) { - eline = utilStripCR(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) { - std::ostringstream err; - err << "AUTOGEN: error: Rcc lists unparsable output " << eline - << std::endl; - cmSystemTools::Error(err.str().c_str()); - return false; - } - pos += searchString.length(); - std::string::size_type sz = eline.size() - pos - 1; - depends.push_back(eline.substr(pos, sz)); - } - } - } - - return true; -} - -/// @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(cmSourceFile* sf, - std::vector& depends) -{ - // Read file into string - std::string qrcContents; - { - std::ostringstream stream; - stream << cmsys::ifstream(sf->GetFullPath().c_str()).rdbuf(); - qrcContents = stream.str(); - } - - cmsys::RegularExpression fileMatchRegex("(]*>)"); - - 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 = sf->GetLocation().GetDirectory() + "/" + qrcEntry; - } - depends.push_back(qrcEntry); - } - return true; -} - -/// @brief Reads the resource files list from from a .qrc file -/// @return True if the rcc file was successfully parsed -static bool RccListInputs(const std::string& qtMajorVersion, cmSourceFile* sf, - cmGeneratorTarget const* target, - std::vector& depends) -{ - if (qtMajorVersion == "5") { - return RccListInputsQt5(sf, target, depends); - } - return RccListInputsQt4(sf, depends); -} - static void RccSetupAutoTarget(cmGeneratorTarget const* target, const std::string& qtMajorVersion) { cmMakefile* makefile = target->Target->GetMakefile(); const bool qtMajorVersion5 = (qtMajorVersion == "5"); + const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); std::vector _rcc_files; std::vector _rcc_inputs; std::vector rccFileFiles; @@ -636,9 +494,10 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, { std::string entriesList; if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { - std::vector depends; - if (RccListInputs(qtMajorVersion, sf, target, depends)) { - entriesList = cmJoin(depends, "@list_sep@"); + std::vector files; + if (cmQtAutoGeneratorCommon::RccListInputs( + qtMajorVersion, rccCommand, absFile, files)) { + entriesList = cmJoin(files, cmQtAutoGeneratorCommon::listSep); } else { return; } @@ -657,19 +516,19 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, // Only store non empty options lists if (!rccOptions.empty()) { rccFileFiles.push_back(absFile); - rccFileOptions.push_back(cmJoin(rccOptions, "@list_sep@")); + rccFileOptions.push_back( + cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep)); } } } } } + AddDefinitionEscaped(makefile, "_qt_rcc_executable", rccCommand); AddDefinitionEscaped(makefile, "_rcc_files", _rcc_files); AddDefinitionEscaped(makefile, "_rcc_inputs", _rcc_inputs); AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles); AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions); - AddDefinitionEscaped(makefile, "_qt_rcc_executable", - RccGetExecutable(target, qtMajorVersion)); } void cmQtAutoGeneratorInitializer::InitializeAutogenSources( @@ -696,6 +555,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( const std::string workingDirectory = cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); const std::string qtMajorVersion = GetQtMajorVersion(target); + const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); std::vector autogenOutputFiles; // Remove old settings on cleanup @@ -825,20 +685,22 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( target->AddSource(rccOutputFile); // Register rcc output file as generated autogenOutputFiles.push_back(rccOutputFile); - } - if (lg->GetGlobalGenerator()->GetName() == "Ninja" + + if (lg->GetGlobalGenerator()->GetName() == "Ninja" #if defined(_WIN32) && !defined(__CYGWIN__) - || usePRE_BUILD + || usePRE_BUILD #endif - ) { - if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { - RccListInputs(qtMajorVersion, sf, target, depends); + ) { + if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { + cmQtAutoGeneratorCommon::RccListInputs( + qtMajorVersion, rccCommand, absFile, depends); #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 - // target needs to re-build at all. - usePRE_BUILD = false; + // Cannot use PRE_BUILD because the resource files themselves + // may not be sources within the target so VS may not know the + // target needs to re-build at all. + usePRE_BUILD = false; #endif + } } } } diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index c83f9a9..bc9c511 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1,6 +1,7 @@ /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmQtAutoGenerators.h" +#include "cmQtAutoGeneratorCommon.h" #include #include @@ -178,7 +179,7 @@ static std::string JoinOptionsMap( for (std::map::const_iterator it = opts.begin(); it != opts.end(); ++it) { if (it != opts.begin()) { - result += "@list_sep@"; + result += cmQtAutoGeneratorCommon::listSep; } result += it->first; result += "==="; @@ -424,7 +425,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( fileIt = uicFilesVec.begin(), optionIt = uicOptionsVec.begin(); fileIt != uicFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + cmSystemTools::ReplaceString(*optionIt, + cmQtAutoGeneratorCommon::listSep, ";"); this->UicOptions[*fileIt] = *optionIt; } } else { @@ -453,7 +455,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( for (std::vector::iterator fileIt = rccFilesVec.begin(), optionIt = rccOptionsVec.begin(); fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, "@list_sep@", ";"); + cmSystemTools::ReplaceString(*optionIt, + cmQtAutoGeneratorCommon::listSep, ";"); this->RccOptions[*fileIt] = *optionIt; } } @@ -475,7 +478,8 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( fileIt = this->RccSources.begin(), inputIt = rccInputLists.begin(); fileIt != this->RccSources.end(); ++fileIt, ++inputIt) { - cmSystemTools::ReplaceString(*inputIt, "@list_sep@", ";"); + cmSystemTools::ReplaceString(*inputIt, + cmQtAutoGeneratorCommon::listSep, ";"); std::vector rccInputFiles; cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); this->RccInputs[*fileIt] = rccInputFiles; -- cgit v0.12 From 0d9a5baa0e96fb2d14838ebeb6a86eec62acf100 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Tue, 28 Feb 2017 12:34:35 +0100 Subject: Autogen: Remove unused variables --- Source/cmQtAutoGeneratorInitializer.cxx | 3 --- 1 file changed, 3 deletions(-) diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 3a7951a..151f39c 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -135,15 +135,12 @@ static void SetupSourceFiles(cmGeneratorTarget const* target, std::vector& mocSkipList, std::vector& uicSkipList) { - cmMakefile* makefile = target->Target->GetMakefile(); - std::vector srcFiles; target->GetConfigCommonSourceFiles(srcFiles); const bool mocTarget = target->GetPropertyAsBool("AUTOMOC"); const bool uicTarget = target->GetPropertyAsBool("AUTOUIC"); - cmFilePathChecksum fpathCheckSum(makefile); for (std::vector::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; -- cgit v0.12 From a28ae16e3cd6d42ab068b5bc0bedf5725a6ce743 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 12:32:47 +0100 Subject: Autogen: Embrace qrc file lists in braces in AutogenInfo.cmake This allows empty .qrc files in any list position. --- Source/cmQtAutoGeneratorCommon.cxx | 2 +- Source/cmQtAutoGeneratorInitializer.cxx | 5 ++-- Source/cmQtAutoGenerators.cxx | 50 ++++++++++++++++++--------------- 3 files changed, 31 insertions(+), 26 deletions(-) diff --git a/Source/cmQtAutoGeneratorCommon.cxx b/Source/cmQtAutoGeneratorCommon.cxx index c42f71d..5146b1a 100644 --- a/Source/cmQtAutoGeneratorCommon.cxx +++ b/Source/cmQtAutoGeneratorCommon.cxx @@ -152,7 +152,7 @@ static bool RccListInputsQt5(const std::string& rccCommand, // - Class definitions -const char* cmQtAutoGeneratorCommon::listSep = "@list_sep@"; +const char* cmQtAutoGeneratorCommon::listSep = "@LSEP@"; bool cmQtAutoGeneratorCommon::RccListInputs(const std::string& qtMajorVersion, const std::string& rccCommand, diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 151f39c..0f29e02 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -489,16 +489,17 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, _rcc_files.push_back(absFile); // qrc file entries { - std::string entriesList; + std::string entriesList = "{"; if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { std::vector files; if (cmQtAutoGeneratorCommon::RccListInputs( qtMajorVersion, rccCommand, absFile, files)) { - entriesList = cmJoin(files, cmQtAutoGeneratorCommon::listSep); + entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep); } else { return; } } + entriesList += "}"; _rcc_inputs.push_back(entriesList); } // rcc options for this qrc file diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index bc9c511..4d14e99 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -441,49 +441,53 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // - Rcc if (this->RccEnabled()) { InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources); + // File options { std::vector rccFilesVec; std::vector rccOptionsVec; InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec); InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec); if (rccFilesVec.size() != rccOptionsVec.size()) { + for (std::vector::iterator + fileIt = rccFilesVec.begin(), + optionIt = rccOptionsVec.begin(); + fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { + // Replace item separator + cmSystemTools::ReplaceString(*optionIt, + cmQtAutoGeneratorCommon::listSep, ";"); + this->RccOptions[*fileIt] = *optionIt; + } + } else { this->LogError( "AutoGen: Error: RCC files/options lists size missmatch in: " + filename); return false; } - for (std::vector::iterator fileIt = rccFilesVec.begin(), - optionIt = rccOptionsVec.begin(); - fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { - cmSystemTools::ReplaceString(*optionIt, - cmQtAutoGeneratorCommon::listSep, ";"); - this->RccOptions[*fileIt] = *optionIt; - } } + // File lists { std::vector rccInputLists; InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists); - - // qrc files in the end of the list may have been empty - if (rccInputLists.size() < this->RccSources.size()) { - rccInputLists.resize(this->RccSources.size()); - } - if (this->RccSources.size() != rccInputLists.size()) { + if (this->RccSources.size() == rccInputLists.size()) { + for (std::vector::iterator + fileIt = this->RccSources.begin(), + inputIt = rccInputLists.begin(); + fileIt != this->RccSources.end(); ++fileIt, ++inputIt) { + // Remove braces + *inputIt = inputIt->substr(1, inputIt->size() - 2); + // Replace item separator + cmSystemTools::ReplaceString(*inputIt, + cmQtAutoGeneratorCommon::listSep, ";"); + std::vector rccInputFiles; + cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); + this->RccInputs[*fileIt] = rccInputFiles; + } + } else { this->LogError( "AutoGen: Error: RCC sources/inputs lists size missmatch in: " + filename); return false; } - for (std::vector::iterator - fileIt = this->RccSources.begin(), - inputIt = rccInputLists.begin(); - fileIt != this->RccSources.end(); ++fileIt, ++inputIt) { - cmSystemTools::ReplaceString(*inputIt, - cmQtAutoGeneratorCommon::listSep, ";"); - std::vector rccInputFiles; - cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); - this->RccInputs[*fileIt] = rccInputFiles; - } } } -- cgit v0.12 From 699321bfd5a997aceb64649c83ce78044ce11cc1 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 14:06:02 +0100 Subject: Autogen: Add support for generated .qrc files --- Source/cmQtAutoGeneratorCommon.cxx | 131 ++++++++++++++++++++++---------- Source/cmQtAutoGeneratorCommon.h | 7 +- Source/cmQtAutoGeneratorInitializer.cxx | 15 +++- 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& files) + std::vector& 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("(]*>)"); - - 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("(]*>)"); + + 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& files) + std::vector& 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& files) + std::vector& 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& files); + std::vector& 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 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 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::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& files = this->RccInputs[rccInputFile]; - for (std::vector::const_iterator it = files.begin(); - it != files.end(); ++it) { - if (FileAbsentOrOlder(rccBuildFile, *it)) { - generateRcc = true; - break; + // Acquire input file list + std::vector readFiles; + const std::vector* 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::const_iterator it = files->begin(); + it != files->end(); ++it) { + if (FileAbsentOrOlder(rccBuildFile, *it)) { + generateRcc = true; + break; + } } } } -- cgit v0.12 From e3af6bec6733fb21206998c0c8f155e6d13b4367 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 14:32:33 +0100 Subject: Autogen: Initializer cleanups --- Source/cmQtAutoGeneratorInitializer.cxx | 143 ++++++++++++++++---------------- 1 file changed, 70 insertions(+), 73 deletions(-) diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 2b53982..2829c8a 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -129,18 +129,17 @@ static void AddDefinitionEscaped(cmMakefile* makefile, const char* key, key, cmOutputConverter::EscapeForCMake(cmJoin(values, ";")).c_str()); } -static void SetupSourceFiles(cmGeneratorTarget const* target, +static void AcquireScanFiles(cmGeneratorTarget const* target, std::vector& mocUicSources, std::vector& mocUicHeaders, std::vector& mocSkipList, std::vector& uicSkipList) { - std::vector srcFiles; - target->GetConfigCommonSourceFiles(srcFiles); - const bool mocTarget = target->GetPropertyAsBool("AUTOMOC"); const bool uicTarget = target->GetPropertyAsBool("AUTOUIC"); + std::vector srcFiles; + target->GetConfigCommonSourceFiles(srcFiles); for (std::vector::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; @@ -478,47 +477,44 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, for (std::vector::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; - if (sf->GetExtension() == "qrc") { - const bool skip = - cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) || - cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")); - if (!skip) { - const std::string absFile = - cmsys::SystemTools::GetRealPath(sf->GetFullPath()); - // qrc file - _rcc_files.push_back(absFile); - // 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 files; - if (cmQtAutoGeneratorCommon::RccListInputs( - qtMajorVersion, rccCommand, absFile, files, &error)) { - entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep); - } else { - cmSystemTools::Error(error.c_str()); - } + if ((sf->GetExtension() == "qrc") && + !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) && + !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { + const std::string absFile = + cmsys::SystemTools::GetRealPath(sf->GetFullPath()); + // qrc file + _rcc_files.push_back(absFile); + // 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 files; + if (cmQtAutoGeneratorCommon::RccListInputs( + qtMajorVersion, rccCommand, absFile, files, &error)) { + entriesList += cmJoin(files, cmQtAutoGeneratorCommon::listSep); + } else { + cmSystemTools::Error(error.c_str()); } - entriesList += "}"; - _rcc_inputs.push_back(entriesList); } - // rcc options for this qrc file - { - // Merged target and file options - std::vector rccOptions(rccOptionsTarget); - if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) { - std::vector optsVec; - cmSystemTools::ExpandListArgument(prop, optsVec); - RccMergeOptions(rccOptions, optsVec, qtMajorVersion5); - } - // Only store non empty options lists - if (!rccOptions.empty()) { - rccFileFiles.push_back(absFile); - rccFileOptions.push_back( - cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep)); - } + entriesList += "}"; + _rcc_inputs.push_back(entriesList); + } + // rcc options for this qrc file + { + // Merged target and file options + std::vector rccOptions(rccOptionsTarget); + if (const char* prop = sf->GetProperty("AUTORCC_OPTIONS")) { + std::vector optsVec; + cmSystemTools::ExpandListArgument(prop, optsVec); + RccMergeOptions(rccOptions, optsVec, qtMajorVersion5); + } + // Only store non empty options lists + if (!rccOptions.empty()) { + rccFileFiles.push_back(absFile); + rccFileOptions.push_back( + cmJoin(rccOptions, cmQtAutoGeneratorCommon::listSep)); } } } @@ -550,6 +546,9 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( cmMakefile* makefile = target->Target->GetMakefile(); // Create a custom target for running generators at buildtime + const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); + const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); + const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); const std::string autogenTargetName = GetAutogenTargetName(target); const std::string autogenBuildDir = GetAutogenTargetBuildDir(target); const std::string workingDirectory = @@ -571,8 +570,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", autogenBuildDir.c_str(), false); - if (target->GetPropertyAsBool("AUTOMOC") || - target->GetPropertyAsBool("AUTOUIC")) { + if (mocEnabled || uicEnabled) { // Create autogen target includes directory and // add it to the origin target INCLUDE_DIRECTORIES const std::string incsDir = autogenBuildDir + "include"; @@ -580,7 +578,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( target->AddIncludeDirectory(incsDir, true); } - if (target->GetPropertyAsBool("AUTOMOC")) { + if (mocEnabled) { // Register moc compilation file as generated autogenOutputFiles.push_back(autogenBuildDir + "moc_compilation.cpp"); } @@ -608,13 +606,13 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( std::string autogenComment; { std::vector toolNames; - if (target->GetPropertyAsBool("AUTOMOC")) { + if (mocEnabled) { toolNames.push_back("MOC"); } - if (target->GetPropertyAsBool("AUTOUIC")) { + if (uicEnabled) { toolNames.push_back("UIC"); } - if (target->GetPropertyAsBool("AUTORCC")) { + if (rccEnabled) { toolNames.push_back("RCC"); } @@ -655,7 +653,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( } #endif - if (target->GetPropertyAsBool("AUTORCC")) { + if (rccEnabled) { cmFilePathChecksum fpathCheckSum(makefile); std::vector srcFiles; target->GetConfigCommonSourceFiles(srcFiles); @@ -767,38 +765,37 @@ void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget( std::map configMocDefines; std::map configUicOptions; { - // create a custom target for running generators at buildtime: + const bool mocEnabled = target->GetPropertyAsBool("AUTOMOC"); + const bool uicEnabled = target->GetPropertyAsBool("AUTOUIC"); + const bool rccEnabled = target->GetPropertyAsBool("AUTORCC"); const std::string autogenTargetName = GetAutogenTargetName(target); const std::string qtMajorVersion = GetQtMajorVersion(target); - AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName); - AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName()); - AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion); - std::vector _sources; std::vector _headers; - std::vector mocSkipList; - std::vector uicSkipList; - if (target->GetPropertyAsBool("AUTOMOC") || - target->GetPropertyAsBool("AUTOUIC") || - target->GetPropertyAsBool("AUTORCC")) { - SetupSourceFiles(target, _sources, _headers, mocSkipList, uicSkipList); + if (mocEnabled || uicEnabled || rccEnabled) { + std::vector mocSkipList; + std::vector uicSkipList; + AcquireScanFiles(target, _sources, _headers, mocSkipList, uicSkipList); + if (mocEnabled) { + MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, + mocSkipList, configMocIncludes, configMocDefines); + } + if (uicEnabled) { + UicSetupAutoTarget(target, qtMajorVersion, uicSkipList, + configUicOptions); + } + if (rccEnabled) { + RccSetupAutoTarget(target, qtMajorVersion); + } } + + AddDefinitionEscaped(makefile, "_autogen_target_name", autogenTargetName); + AddDefinitionEscaped(makefile, "_origin_target_name", target->GetName()); + AddDefinitionEscaped(makefile, "_qt_version_major", qtMajorVersion); AddDefinitionEscaped(makefile, "_sources", _sources); AddDefinitionEscaped(makefile, "_headers", _headers); - - if (target->GetPropertyAsBool("AUTOMOC")) { - MocSetupAutoTarget(target, autogenTargetName, qtMajorVersion, - mocSkipList, configMocIncludes, configMocDefines); - } - if (target->GetPropertyAsBool("AUTOUIC")) { - UicSetupAutoTarget(target, qtMajorVersion, uicSkipList, - configUicOptions); - } - if (target->GetPropertyAsBool("AUTORCC")) { - RccSetupAutoTarget(target, qtMajorVersion); - } } // Generate config file -- cgit v0.12 From ea3bc1e5b04fd420c4627e520af2e913b88e1100 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 16:26:26 +0100 Subject: Autogen: Add AUTOMOC/UIC support for generated source files Closes #16186 Closes #14379 --- Source/cmQtAutoGeneratorInitializer.cxx | 214 ++++++++++++++++++-------------- 1 file changed, 122 insertions(+), 92 deletions(-) diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 2829c8a..94cc981 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -45,6 +45,11 @@ static void utilCopyTargetProperty(cmTarget* destinationTarget, } } +inline static bool PropertyEnabled(cmSourceFile* sourceFile, const char* key) +{ + return cmSystemTools::IsOn(sourceFile->GetPropertyForUser(key)); +} + static std::string GetSafeProperty(cmGeneratorTarget const* target, const char* key) { @@ -150,18 +155,12 @@ static void AcquireScanFiles(cmGeneratorTarget const* target, !(fileType == cmSystemTools::HEADER_FILE_FORMAT)) { continue; } - if (cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { - continue; - } const std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); // Skip flags - const bool skipAll = - cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")); - const bool mocSkip = - skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC")); - const bool uicSkip = - skipAll || cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")); + const bool skipAll = PropertyEnabled(sf, "SKIP_AUTOGEN"); + const bool mocSkip = skipAll || PropertyEnabled(sf, "SKIP_AUTOMOC"); + const bool uicSkip = skipAll || PropertyEnabled(sf, "SKIP_AUTOUIC"); // Add file name to skip lists. // Do this even when the file is not added to the sources/headers lists // because the file name may be extracted from an other file when @@ -478,8 +477,8 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; if ((sf->GetExtension() == "qrc") && - !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) && - !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { + !PropertyEnabled(sf, "SKIP_AUTOGEN") && + !PropertyEnabled(sf, "SKIP_AUTORCC")) { const std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); // qrc file @@ -488,7 +487,7 @@ static void RccSetupAutoTarget(cmGeneratorTarget const* target, { std::string entriesList = "{"; // Read input file list only for non generated .qrc files. - if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { + if (!PropertyEnabled(sf, "GENERATED")) { std::string error; std::vector files; if (cmQtAutoGeneratorCommon::RccListInputs( @@ -555,7 +554,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( cmSystemTools::CollapseFullPath("", makefile->GetCurrentBinaryDirectory()); const std::string qtMajorVersion = GetQtMajorVersion(target); const std::string rccCommand = RccGetExecutable(target, qtMajorVersion); - std::vector autogenOutputFiles; + std::vector autogenDepends; + std::vector autogenProvides; // Remove old settings on cleanup { @@ -565,31 +565,6 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( false); } - // Create autogen target build directory and add it to the clean files - cmSystemTools::MakeDirectory(autogenBuildDir); - makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", - autogenBuildDir.c_str(), false); - - if (mocEnabled || uicEnabled) { - // Create autogen target includes directory and - // add it to the origin target INCLUDE_DIRECTORIES - const std::string incsDir = autogenBuildDir + "include"; - cmSystemTools::MakeDirectory(incsDir); - target->AddIncludeDirectory(incsDir, true); - } - - if (mocEnabled) { - // Register moc compilation file as generated - autogenOutputFiles.push_back(autogenBuildDir + "moc_compilation.cpp"); - } - - // Initialize autogen target dependencies - std::vector depends; - if (const char* autogenDepends = - target->GetProperty("AUTOGEN_TARGET_DEPENDS")) { - cmSystemTools::ExpandListArgument(autogenDepends, depends); - } - // Compose command lines cmCustomCommandLines commandLines; { @@ -628,6 +603,24 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( autogenComment = "Automatic " + tools + " for target " + target->GetName(); } + // Create autogen target build directory and add it to the clean files + cmSystemTools::MakeDirectory(autogenBuildDir); + makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES", + autogenBuildDir.c_str(), false); + + // Create autogen target includes directory and + // add it to the origin target INCLUDE_DIRECTORIES + if (mocEnabled || uicEnabled) { + const std::string incsDir = autogenBuildDir + "include"; + cmSystemTools::MakeDirectory(incsDir); + target->AddIncludeDirectory(incsDir, true); + } + + // Register moc compilation file as generated + if (mocEnabled) { + autogenProvides.push_back(autogenBuildDir + "moc_compilation.cpp"); + } + #if defined(_WIN32) && !defined(__CYGWIN__) bool usePRE_BUILD = false; cmGlobalGenerator* gg = lg->GetGlobalGenerator(); @@ -639,72 +632,100 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // This also works around a VS 11 bug that may skip updating the target: // https://connect.microsoft.com/VisualStudio/feedback/details/769495 usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7; - if (usePRE_BUILD) { - // If the autogen target depends on an other target - // don't use PRE_BUILD - for (std::vector::iterator it = depends.begin(); - it != depends.end(); ++it) { - if (!makefile->FindTargetToUse(it->c_str())) { - usePRE_BUILD = false; - break; - } - } - } } #endif - if (rccEnabled) { + // Initialize autogen target dependencies + if (const char* deps = target->GetProperty("AUTOGEN_TARGET_DEPENDS")) { + cmSystemTools::ExpandListArgument(deps, autogenDepends); + } + // Add link library targets to the autogen dependencies + { + const cmTarget::LinkLibraryVectorType& libVec = + target->Target->GetOriginalLinkLibraries(); + for (cmTarget::LinkLibraryVectorType::const_iterator it = libVec.begin(); + it != libVec.end(); ++it) { + const std::string& libName = it->first; + if (makefile->FindTargetToUse(libName) != CM_NULLPTR) { + autogenDepends.push_back(libName); + } + } + } + { cmFilePathChecksum fpathCheckSum(makefile); + // Iterate over all source files std::vector srcFiles; target->GetConfigCommonSourceFiles(srcFiles); for (std::vector::const_iterator fileIt = srcFiles.begin(); fileIt != srcFiles.end(); ++fileIt) { cmSourceFile* sf = *fileIt; - if (sf->GetExtension() == "qrc" && - !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOGEN")) && - !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"))) { - { + if (!PropertyEnabled(sf, "SKIP_AUTOGEN")) { + const std::string ext = sf->GetExtension(); + // Add generated file that will be scanned by moc or uic to + // the dependencies + if (mocEnabled || uicEnabled) { + const cmSystemTools::FileFormat fileType = + cmSystemTools::GetFileFormat(ext.c_str()); + if ((fileType == cmSystemTools::CXX_FILE_FORMAT) || + (fileType == cmSystemTools::HEADER_FILE_FORMAT)) { + if (PropertyEnabled(sf, "GENERATED")) { + if ((mocEnabled && !PropertyEnabled(sf, "SKIP_AUTOMOC")) || + (uicEnabled && !PropertyEnabled(sf, "SKIP_AUTOUIC"))) { + autogenDepends.push_back( + cmsys::SystemTools::GetRealPath(sf->GetFullPath())); +#if defined(_WIN32) && !defined(__CYGWIN__) + // Cannot use PRE_BUILD with generated files + usePRE_BUILD = false; +#endif + } + } + } + } + // Process rcc enabled files + if (rccEnabled && (ext == "qrc") && + !PropertyEnabled(sf, "SKIP_AUTORCC")) { const std::string absFile = cmsys::SystemTools::GetRealPath(sf->GetFullPath()); - // Run cmake again when .qrc file changes - makefile->AddCMakeDependFile(absFile); - - std::string rccOutputFile = autogenBuildDir; - rccOutputFile += fpathCheckSum.getPart(absFile); - rccOutputFile += "/qrc_"; - rccOutputFile += - cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); - rccOutputFile += ".cpp"; - - // Add rcc output file to origin target sources - cmSourceFile* gf = makefile->GetOrCreateSource(rccOutputFile, true); - gf->SetProperty("SKIP_AUTOGEN", "On"); - target->AddSource(rccOutputFile); - // Register rcc output file as generated - autogenOutputFiles.push_back(rccOutputFile); + // Compose rcc output file name + { + std::string rccOut = autogenBuildDir; + rccOut += fpathCheckSum.getPart(absFile); + rccOut += "/qrc_"; + rccOut += + cmsys::SystemTools::GetFilenameWithoutLastExtension(absFile); + rccOut += ".cpp"; + + // Register rcc output file as generated + autogenProvides.push_back(rccOut); + + // Add rcc output file to origin target sources + cmSourceFile* gf = makefile->GetOrCreateSource(rccOut, true); + gf->SetProperty("SKIP_AUTOGEN", "On"); + target->AddSource(rccOut); + } - if (lg->GetGlobalGenerator()->GetName() == "Ninja" -#if defined(_WIN32) && !defined(__CYGWIN__) - || usePRE_BUILD -#endif - ) { - if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"))) { - { - 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 - // target needs to re-build at all. - usePRE_BUILD = false; -#endif + if (PropertyEnabled(sf, "GENERATED")) { + // Add generated qrc file to the dependencies + autogenDepends.push_back(absFile); + } else { + // Run cmake again when .qrc file changes + makefile->AddCMakeDependFile(absFile); + + // Add the qrc input files to the dependencies + std::string error; + if (!cmQtAutoGeneratorCommon::RccListInputs( + qtMajorVersion, rccCommand, absFile, autogenDepends, + &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 + // target needs to re-build at all. + usePRE_BUILD = false; +#endif } } } @@ -712,12 +733,21 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( #if defined(_WIN32) && !defined(__CYGWIN__) if (usePRE_BUILD) { + // If the autogen target depends on an other target don't use PRE_BUILD + for (std::vector::iterator it = autogenDepends.begin(); + it != autogenDepends.end(); ++it) { + if (makefile->FindTargetToUse(*it) != CM_NULLPTR) { + usePRE_BUILD = false; + break; + } + } + } + if (usePRE_BUILD) { // Add the pre-build command directly to bypass the OBJECT_LIBRARY // rejection in cmMakefile::AddCustomCommandToTarget because we know // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case. std::vector no_output; - std::vector no_byproducts; - cmCustomCommand cc(makefile, no_output, no_byproducts, depends, + cmCustomCommand cc(makefile, no_output, autogenProvides, autogenDepends, commandLines, autogenComment.c_str(), workingDirectory.c_str()); cc.SetEscapeOldStyle(false); @@ -728,7 +758,7 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( { cmTarget* autogenTarget = makefile->AddUtilityCommand( autogenTargetName, true, workingDirectory.c_str(), - /*byproducts=*/autogenOutputFiles, depends, commandLines, false, + /*byproducts=*/autogenProvides, autogenDepends, commandLines, false, autogenComment.c_str()); cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg); -- cgit v0.12 From 8f2ad9c4a06029d6d2859119f957a83c6082b14e Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 19:39:50 +0100 Subject: Autogen: Error return when a scan file is not readable --- Source/cmQtAutoGenerators.cxx | 105 ++++++++++++++++++++++++++---------------- Source/cmQtAutoGenerators.h | 2 +- 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 2510066..c9b650a 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -125,13 +125,19 @@ static bool FileNameIsUnique(const std::string& filePath, return true; } -static std::string ReadAll(const std::string& filename) +static bool ReadAll(std::string& content, const std::string& filename) { - cmsys::ifstream file(filename.c_str()); - std::ostringstream stream; - stream << file.rdbuf(); - file.close(); - return stream.str(); + bool success = false; + { + cmsys::ifstream ifs(filename.c_str()); + if (ifs) { + std::ostringstream osst; + osst << ifs.rdbuf(); + content = osst.str(); + success = true; + } + } + return success; } /** @@ -682,8 +688,10 @@ bool cmQtAutoGenerators::RunAutogen() uicHeaderFiles.insert(headerName); } } - this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded, - mocsNotIncluded, mocDepends, uisIncluded); + if (!this->ParseHeaders(mocHeaderFiles, uicHeaderFiles, mocsIncluded, + mocsNotIncluded, mocDepends, uisIncluded)) { + return false; + }; // Generate files if (!this->MocGenerateAll(mocsIncluded, mocsNotIncluded, mocDepends)) { @@ -799,23 +807,29 @@ bool cmQtAutoGenerators::ParseSourceFile( std::map >& mocDepends, std::map >& uisIncluded, bool relaxed) { - bool success = true; - const std::string contentText = ReadAll(absFilename); - if (contentText.empty()) { - std::ostringstream ost; - ost << "AutoGen: Warning: " << absFilename << "\n" - << "The file is empty\n"; - this->LogWarning(ost.str()); - } else { - // Parse source contents for MOC - if (success && !this->MocSkip(absFilename)) { - success = this->MocParseSourceContent(absFilename, contentText, - mocsIncluded, mocDepends, relaxed); - } - // Parse source contents for UIC - if (success && !this->UicSkip(absFilename)) { - this->UicParseContent(absFilename, contentText, uisIncluded); + std::string contentText; + bool success = ReadAll(contentText, absFilename); + if (success) { + if (!contentText.empty()) { + // Parse source contents for MOC + if (success && !this->MocSkip(absFilename)) { + success = this->MocParseSourceContent( + absFilename, contentText, mocsIncluded, mocDepends, relaxed); + } + // Parse source contents for UIC + if (success && !this->UicSkip(absFilename)) { + this->UicParseContent(absFilename, contentText, uisIncluded); + } + } else { + std::ostringstream ost; + ost << "AutoGen: Warning: The file is empty:\n" + << Quoted(absFilename) << "\n"; + this->LogWarning(ost.str()); } + } else { + std::ostringstream ost; + ost << "AutoGen: Error: Could not read file:\n" << Quoted(absFilename); + this->LogError(ost.str()); } return success; } @@ -1078,7 +1092,7 @@ void cmQtAutoGenerators::SearchHeadersForSourceFile( } } -void cmQtAutoGenerators::ParseHeaders( +bool cmQtAutoGenerators::ParseHeaders( const std::set& mocHeaderFiles, const std::set& uicHeaderFiles, const std::map& mocsIncluded, @@ -1086,6 +1100,7 @@ void cmQtAutoGenerators::ParseHeaders( std::map >& mocDepends, std::map >& uisIncluded) { + bool success = true; // Merged header files list to read files only once std::set headerFiles; headerFiles.insert(mocHeaderFiles.begin(), mocHeaderFiles.end()); @@ -1094,20 +1109,28 @@ void cmQtAutoGenerators::ParseHeaders( for (std::set::const_iterator hIt = headerFiles.begin(); hIt != headerFiles.end(); ++hIt) { const std::string& headerName = *hIt; - const std::string contentText = ReadAll(headerName); - - // Parse header content for MOC - if ((mocHeaderFiles.find(headerName) != mocHeaderFiles.end()) && - (mocsIncluded.find(headerName) == mocsIncluded.end())) { - this->MocParseHeaderContent(headerName, contentText, mocsNotIncluded, - mocDepends); - } - - // Parse header content for UIC - if (uicHeaderFiles.find(headerName) != uicHeaderFiles.end()) { - this->UicParseContent(headerName, contentText, uisIncluded); + std::string contentText; + if (ReadAll(contentText, headerName)) { + // Parse header content for MOC + if ((mocHeaderFiles.find(headerName) != mocHeaderFiles.end()) && + (mocsIncluded.find(headerName) == mocsIncluded.end())) { + this->MocParseHeaderContent(headerName, contentText, mocsNotIncluded, + mocDepends); + } + // Parse header content for UIC + if (uicHeaderFiles.find(headerName) != uicHeaderFiles.end()) { + this->UicParseContent(headerName, contentText, uisIncluded); + } + } else { + std::ostringstream ost; + ost << "AutoGen: Error: Could not read header file:\n" + << Quoted(headerName); + this->LogError(ost.str()); + success = false; + break; } } + return success; } bool cmQtAutoGenerators::MocGenerateAll( @@ -1190,8 +1213,12 @@ bool cmQtAutoGenerators::MocGenerateAll( // Check if the content of moc_compilation.cpp changed { - const std::string oldContents = ReadAll(this->MocCppFilenameAbs); - mocCompChanged = (oldContents != automocSource); + std::string oldContents; + if (ReadAll(oldContents, this->MocCppFilenameAbs)) { + mocCompChanged = (oldContents != automocSource); + } else { + mocCompChanged = true; + } } bool success = true; diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 3bff2b2..00fa0c7 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -78,7 +78,7 @@ private: std::set& mocHeaderFiles, std::set& uicHeaderFiles) const; - void ParseHeaders( + bool ParseHeaders( const std::set& mocHeaderFiles, const std::set& uicHeaderFiles, const std::map& mocsIncluded, -- cgit v0.12 From 60274e1d94c8409f810332345339de5dd449056b Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Mon, 6 Mar 2017 19:57:49 +0100 Subject: Autogen: Add RunCommand method with built in logging --- Source/cmQtAutoGenerators.cxx | 117 +++++++++++++++++++++--------------------- Source/cmQtAutoGenerators.h | 2 + 2 files changed, 61 insertions(+), 58 deletions(-) diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index c9b650a..246dd8d 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -1312,18 +1312,12 @@ bool cmQtAutoGenerators::MocGenerateFile( cmd.push_back(mocFileAbs); cmd.push_back(sourceFile); - // Log moc command - if (this->Verbose) { - this->LogCommand(cmd); - } - // Execute moc command - bool res = false; - int retVal = 0; std::string output; - res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal); - - if (!res || (retVal != 0)) { + if (this->RunCommand(cmd, output)) { + // Success + mocGenerated = true; + } else { // Command failed { std::ostringstream ost; @@ -1335,9 +1329,6 @@ bool cmQtAutoGenerators::MocGenerateFile( } cmSystemTools::RemoveFile(mocFileAbs); this->RunMocFailed = true; - } else { - // Success - mocGenerated = true; } } else { // Parent directory creation failed @@ -1492,18 +1483,11 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, cmd.push_back(uicFileAbs); cmd.push_back(uiInputFile); - // Log command - if (this->Verbose) { - this->LogCommand(cmd); - } - - // Execute command - bool res = false; - int retVal = 0; std::string output; - res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal); - - if (!res || (retVal != 0)) { + if (this->RunCommand(cmd, output)) { + // Success + uicGenerated = true; + } else { // Command failed { std::ostringstream ost; @@ -1516,9 +1500,6 @@ bool cmQtAutoGenerators::UicGenerateFile(const std::string& realName, } cmSystemTools::RemoveFile(uicFileAbs); this->RunUicFailed = true; - } else { - // Success - uicGenerated = true; } } else { // Parent directory creation failed @@ -1649,17 +1630,11 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, cmd.push_back(rccBuildFile); cmd.push_back(rccInputFile); - // Log command - if (this->Verbose) { - this->LogCommand(cmd); - } - - // Execute command - bool res = false; - int retVal = 0; std::string output; - res = cmSystemTools::RunSingleCommand(cmd, &output, &output, &retVal); - if (!res || (retVal != 0)) { + if (this->RunCommand(cmd, output)) { + // Success + rccGenerated = true; + } else { // Command failed { std::ostringstream ost; @@ -1671,9 +1646,6 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, } cmSystemTools::RemoveFile(rccBuildFile); this->RunRccFailed = true; - } else { - // Success - rccGenerated = true; } } else { // Parent directory creation failed @@ -1751,7 +1723,18 @@ void cmQtAutoGenerators::LogError(const std::string& message) const void cmQtAutoGenerators::LogCommand( const std::vector& command) const { - this->LogInfo(cmJoin(command, " ")); + std::vector cmdEscaped; + typedef std::vector::const_iterator Iter; + for (Iter cit = command.begin(); cit != command.end(); ++cit) { + const std::string cesc = Quoted(*cit); + if ((cesc.size() > (cit->size() + 2)) || + (cesc.find(' ') != std::string::npos)) { + cmdEscaped.push_back(cesc); + } else { + cmdEscaped.push_back(*cit); + } + } + this->LogInfo(cmJoin(cmdEscaped, " ")); } /** @@ -1801,6 +1784,41 @@ std::string cmQtAutoGenerators::ChecksumedPath(const std::string& sourceFile, } /** + * @brief Generates the parent directory of the given file on demand + * @return True on success + */ +bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const +{ + bool success = true; + const std::string dirName = cmSystemTools::GetFilenamePath(filename); + if (!dirName.empty()) { + success = cmsys::SystemTools::MakeDirectory(dirName); + if (!success) { + this->LogError("AutoGen: Error: Directory creation failed: " + dirName); + } + } + return success; +} + +/** + * @brief Runs a command and returns true on success + * @return True on success + */ +bool cmQtAutoGenerators::RunCommand(const std::vector& command, + std::string& output) const +{ + // Log command + if (this->Verbose) { + this->LogCommand(command); + } + // Execute command + int retVal = 0; + bool res = + cmSystemTools::RunSingleCommand(command, &output, &output, &retVal); + return (res && (retVal == 0)); +} + +/** * @brief Tries to find the header file to the given file base path by * appending different header extensions * @return True on success @@ -1874,20 +1892,3 @@ bool cmQtAutoGenerators::MocFindIncludedFile( } return success; } - -/** - * @brief Generates the parent directory of the given file on demand - * @return True on success - */ -bool cmQtAutoGenerators::MakeParentDirectory(const std::string& filename) const -{ - bool success = true; - const std::string dirName = cmSystemTools::GetFilenamePath(filename); - if (!dirName.empty()) { - success = cmsys::SystemTools::MakeDirectory(dirName); - if (!success) { - this->LogError("AutoGen: Error: Directory creation failed: " + dirName); - } - } - return success; -} diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index 00fa0c7..ee046de 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -142,6 +142,8 @@ private: const char* basePrefix, const char* baseSuffix) const; bool MakeParentDirectory(const std::string& filename) const; + bool RunCommand(const std::vector& command, + std::string& output) const; bool FindHeader(std::string& header, const std::string& testBasePath) const; -- cgit v0.12 From 9cad44dce264b509afc4b50b540b3a8594cf3217 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 17:07:53 +0100 Subject: Autogen: Test: Rename autorcc_depends test to rccDepends --- Tests/QtAutogen/CMakeLists.txt | 14 ++++++------ Tests/QtAutogen/autorcc_depends/CMakeLists.txt | 27 ----------------------- Tests/QtAutogen/autorcc_depends/res1.qrc.in | 5 ----- Tests/QtAutogen/autorcc_depends/res1/input.txt.in | 1 - Tests/QtAutogen/autorcc_depends/test_res1.cpp | 5 ----- Tests/QtAutogen/rccDepends/CMakeLists.txt | 27 +++++++++++++++++++++++ Tests/QtAutogen/rccDepends/res1.qrc.in | 5 +++++ Tests/QtAutogen/rccDepends/res1/input.txt.in | 1 + Tests/QtAutogen/rccDepends/test_res1.cpp | 5 +++++ 9 files changed, 45 insertions(+), 45 deletions(-) delete mode 100644 Tests/QtAutogen/autorcc_depends/CMakeLists.txt delete mode 100644 Tests/QtAutogen/autorcc_depends/res1.qrc.in delete mode 100644 Tests/QtAutogen/autorcc_depends/res1/input.txt.in delete mode 100644 Tests/QtAutogen/autorcc_depends/test_res1.cpp create mode 100644 Tests/QtAutogen/rccDepends/CMakeLists.txt create mode 100644 Tests/QtAutogen/rccDepends/res1.qrc.in create mode 100644 Tests/QtAutogen/rccDepends/res1/input.txt.in create mode 100644 Tests/QtAutogen/rccDepends/test_res1.cpp diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 4960472..4b84486 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -83,19 +83,19 @@ target_compile_features(empty PRIVATE ${QT_COMPILE_FEATURES}) # -- Test # When a file listed in a .qrc file changes the target must be rebuilt try_compile(RCC_DEPENDS - "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends" - "${CMAKE_CURRENT_SOURCE_DIR}/autorcc_depends" - autorcc_depends + "${CMAKE_CURRENT_BINARY_DIR}/rccDepends" + "${CMAKE_CURRENT_SOURCE_DIR}/rccDepends" + rccDepends CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" "-DQT_TEST_VERSION=${QT_TEST_VERSION}" "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}" OUTPUT_VARIABLE output ) if (NOT RCC_DEPENDS) - message(SEND_ERROR "Initial build of autorcc_depends failed. Output: ${output}") + message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}") endif() -file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/info_file.txt" qrc_files) +file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/info_file.txt" qrc_files) list(GET qrc_files 0 qrc_file1) @@ -104,10 +104,10 @@ set(timeformat "%Y%j%H%M%S") file(TIMESTAMP "${qrc_file1}" file1_before "${timeformat}") execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change. -execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends/res1/input.txt") +execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res1/input.txt") execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/autorcc_depends" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends" ) file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}") diff --git a/Tests/QtAutogen/autorcc_depends/CMakeLists.txt b/Tests/QtAutogen/autorcc_depends/CMakeLists.txt deleted file mode 100644 index 7b51e11..0000000 --- a/Tests/QtAutogen/autorcc_depends/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(autorcc_depends) - -set(CMAKE_AUTORCC ON) - -if (QT_TEST_VERSION STREQUAL 4) - find_package(Qt4 REQUIRED) - set(QT_CORE_TARGET Qt4::QtCore) -else() - if (NOT QT_TEST_VERSION STREQUAL 5) - message(SEND_ERROR "Invalid Qt version specified.") - endif() - - find_package(Qt5Core REQUIRED) - set(QT_CORE_TARGET Qt5::Core) -endif() - -configure_file(res1.qrc.in res1.qrc @ONLY) -configure_file(res1/input.txt.in res1/input.txt @ONLY) - -add_executable(test_res1 - test_res1.cpp - ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc -) -target_link_libraries(test_res1 ${QT_CORE_TARGET}) -add_custom_command(TARGET test_res1 POST_BUILD COMMAND - ${CMAKE_COMMAND} -E echo "$" > info_file.txt) diff --git a/Tests/QtAutogen/autorcc_depends/res1.qrc.in b/Tests/QtAutogen/autorcc_depends/res1.qrc.in deleted file mode 100644 index 2a5417b..0000000 --- a/Tests/QtAutogen/autorcc_depends/res1.qrc.in +++ /dev/null @@ -1,5 +0,0 @@ - - - res1/input.txt - - diff --git a/Tests/QtAutogen/autorcc_depends/res1/input.txt.in b/Tests/QtAutogen/autorcc_depends/res1/input.txt.in deleted file mode 100644 index da62762..0000000 --- a/Tests/QtAutogen/autorcc_depends/res1/input.txt.in +++ /dev/null @@ -1 +0,0 @@ -Res1 input. diff --git a/Tests/QtAutogen/autorcc_depends/test_res1.cpp b/Tests/QtAutogen/autorcc_depends/test_res1.cpp deleted file mode 100644 index 766b775..0000000 --- a/Tests/QtAutogen/autorcc_depends/test_res1.cpp +++ /dev/null @@ -1,5 +0,0 @@ - -int main() -{ - return 0; -} diff --git a/Tests/QtAutogen/rccDepends/CMakeLists.txt b/Tests/QtAutogen/rccDepends/CMakeLists.txt new file mode 100644 index 0000000..c983420 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.7) +project(rccDepends) + +set(CMAKE_AUTORCC ON) + +if (QT_TEST_VERSION STREQUAL 4) + find_package(Qt4 REQUIRED) + set(QT_CORE_TARGET Qt4::QtCore) +else() + if (NOT QT_TEST_VERSION STREQUAL 5) + message(SEND_ERROR "Invalid Qt version specified.") + endif() + + find_package(Qt5Core REQUIRED) + set(QT_CORE_TARGET Qt5::Core) +endif() + +configure_file(res1.qrc.in res1.qrc @ONLY) +configure_file(res1/input.txt.in res1/input.txt @ONLY) + +add_executable(test_res1 + test_res1.cpp + ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc +) +target_link_libraries(test_res1 ${QT_CORE_TARGET}) +add_custom_command(TARGET test_res1 POST_BUILD COMMAND + ${CMAKE_COMMAND} -E echo "$" > info_file.txt) diff --git a/Tests/QtAutogen/rccDepends/res1.qrc.in b/Tests/QtAutogen/rccDepends/res1.qrc.in new file mode 100644 index 0000000..2a5417b --- /dev/null +++ b/Tests/QtAutogen/rccDepends/res1.qrc.in @@ -0,0 +1,5 @@ + + + res1/input.txt + + diff --git a/Tests/QtAutogen/rccDepends/res1/input.txt.in b/Tests/QtAutogen/rccDepends/res1/input.txt.in new file mode 100644 index 0000000..da62762 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/res1/input.txt.in @@ -0,0 +1 @@ +Res1 input. diff --git a/Tests/QtAutogen/rccDepends/test_res1.cpp b/Tests/QtAutogen/rccDepends/test_res1.cpp new file mode 100644 index 0000000..766b775 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/test_res1.cpp @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} -- cgit v0.12 From 89780663b3f64eddf7dda2b5565935b73d92c146 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 17:13:41 +0100 Subject: Autogen: Test: Rename automoc_rerun test to mocRerun --- Tests/QtAutogen/CMakeLists.txt | 14 +++++++------- Tests/QtAutogen/automoc_rerun/CMakeLists.txt | 27 --------------------------- Tests/QtAutogen/automoc_rerun/input.txt | 1 - Tests/QtAutogen/automoc_rerun/res1.qrc | 5 ----- Tests/QtAutogen/automoc_rerun/test1.cpp | 5 ----- Tests/QtAutogen/automoc_rerun/test1.h.in1 | 8 -------- Tests/QtAutogen/automoc_rerun/test1.h.in2 | 7 ------- Tests/QtAutogen/mocRerun/CMakeLists.txt | 27 +++++++++++++++++++++++++++ Tests/QtAutogen/mocRerun/input.txt | 1 + Tests/QtAutogen/mocRerun/res1.qrc | 5 +++++ Tests/QtAutogen/mocRerun/test1.cpp | 5 +++++ Tests/QtAutogen/mocRerun/test1a.h.in | 8 ++++++++ Tests/QtAutogen/mocRerun/test1b.h.in | 7 +++++++ 13 files changed, 60 insertions(+), 60 deletions(-) delete mode 100644 Tests/QtAutogen/automoc_rerun/CMakeLists.txt delete mode 100644 Tests/QtAutogen/automoc_rerun/input.txt delete mode 100644 Tests/QtAutogen/automoc_rerun/res1.qrc delete mode 100644 Tests/QtAutogen/automoc_rerun/test1.cpp delete mode 100644 Tests/QtAutogen/automoc_rerun/test1.h.in1 delete mode 100644 Tests/QtAutogen/automoc_rerun/test1.h.in2 create mode 100644 Tests/QtAutogen/mocRerun/CMakeLists.txt create mode 100644 Tests/QtAutogen/mocRerun/input.txt create mode 100644 Tests/QtAutogen/mocRerun/res1.qrc create mode 100644 Tests/QtAutogen/mocRerun/test1.cpp create mode 100644 Tests/QtAutogen/mocRerun/test1a.h.in create mode 100644 Tests/QtAutogen/mocRerun/test1b.h.in diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 4b84486..bf40166 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -119,26 +119,26 @@ endif() # -- Test # Ensure a repeated build succeeds when a header containing a QObject changes try_compile(MOC_RERUN - "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun" - "${CMAKE_CURRENT_SOURCE_DIR}/automoc_rerun" - automoc_rerun + "${CMAKE_CURRENT_BINARY_DIR}/mocRerun" + "${CMAKE_CURRENT_SOURCE_DIR}/mocRerun" + mocRerun CMAKE_FLAGS "-DQT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE}" "-DQT_TEST_VERSION=${QT_TEST_VERSION}" "-DCMAKE_PREFIX_PATH=${Qt_PREFIX_DIR}" OUTPUT_VARIABLE output ) if (NOT MOC_RERUN) - message(SEND_ERROR "Initial build of automoc_rerun failed. Output: ${output}") + message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}") endif() -configure_file(automoc_rerun/test1.h.in2 automoc_rerun/test1.h COPYONLY) +configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY) execute_process(COMMAND "${CMAKE_COMMAND}" --build . - WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/automoc_rerun" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun" RESULT_VARIABLE automoc_rerun_result ) if (automoc_rerun_result) - message(SEND_ERROR "Second build of automoc_rerun failed.") + message(SEND_ERROR "Second build of mocRerun failed.") endif() # -- Test diff --git a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt b/Tests/QtAutogen/automoc_rerun/CMakeLists.txt deleted file mode 100644 index 92a682b..0000000 --- a/Tests/QtAutogen/automoc_rerun/CMakeLists.txt +++ /dev/null @@ -1,27 +0,0 @@ -cmake_minimum_required(VERSION 3.7) -project(automoc_rerun CXX) - -if (QT_TEST_VERSION STREQUAL 4) - find_package(Qt4 REQUIRED) - set(QT_CORE_TARGET Qt4::QtCore) -else() - if (NOT QT_TEST_VERSION STREQUAL 5) - message(SEND_ERROR "Invalid Qt version specified.") - endif() - - find_package(Qt5Core REQUIRED) - set(QT_CORE_TARGET Qt5::Core) -endif() - -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC ON) - -configure_file(test1.h.in1 test1.h COPYONLY) - -add_executable(test1 - ${CMAKE_CURRENT_BINARY_DIR}/test1.h - test1.cpp - res1.qrc - ) -target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(test1 ${QT_CORE_TARGET}) diff --git a/Tests/QtAutogen/automoc_rerun/input.txt b/Tests/QtAutogen/automoc_rerun/input.txt deleted file mode 100644 index da62762..0000000 --- a/Tests/QtAutogen/automoc_rerun/input.txt +++ /dev/null @@ -1 +0,0 @@ -Res1 input. diff --git a/Tests/QtAutogen/automoc_rerun/res1.qrc b/Tests/QtAutogen/automoc_rerun/res1.qrc deleted file mode 100644 index fb804b5..0000000 --- a/Tests/QtAutogen/automoc_rerun/res1.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - input.txt - - diff --git a/Tests/QtAutogen/automoc_rerun/test1.cpp b/Tests/QtAutogen/automoc_rerun/test1.cpp deleted file mode 100644 index 4316a91..0000000 --- a/Tests/QtAutogen/automoc_rerun/test1.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "test1.h" -int main() -{ - return 0; -} diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in1 b/Tests/QtAutogen/automoc_rerun/test1.h.in1 deleted file mode 100644 index fee2c09..0000000 --- a/Tests/QtAutogen/automoc_rerun/test1.h.in1 +++ /dev/null @@ -1,8 +0,0 @@ -#include -class test1 : public QObject -{ - Q_OBJECT - public slots: - void onTst1() {} - void onTst2() {} -}; diff --git a/Tests/QtAutogen/automoc_rerun/test1.h.in2 b/Tests/QtAutogen/automoc_rerun/test1.h.in2 deleted file mode 100644 index 6531d10..0000000 --- a/Tests/QtAutogen/automoc_rerun/test1.h.in2 +++ /dev/null @@ -1,7 +0,0 @@ -#include -class test1 : public QObject -{ - Q_OBJECT - public slots: - void onTst1() {} -}; diff --git a/Tests/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogen/mocRerun/CMakeLists.txt new file mode 100644 index 0000000..efe936e --- /dev/null +++ b/Tests/QtAutogen/mocRerun/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.7) +project(mocRerun CXX) + +if (QT_TEST_VERSION STREQUAL 4) + find_package(Qt4 REQUIRED) + set(QT_CORE_TARGET Qt4::QtCore) +else() + if (NOT QT_TEST_VERSION STREQUAL 5) + message(SEND_ERROR "Invalid Qt version specified.") + endif() + + find_package(Qt5Core REQUIRED) + set(QT_CORE_TARGET Qt5::Core) +endif() + +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +configure_file(test1a.h.in test1.h COPYONLY) + +add_executable(test1 + ${CMAKE_CURRENT_BINARY_DIR}/test1.h + test1.cpp + res1.qrc + ) +target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(test1 ${QT_CORE_TARGET}) diff --git a/Tests/QtAutogen/mocRerun/input.txt b/Tests/QtAutogen/mocRerun/input.txt new file mode 100644 index 0000000..da62762 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/input.txt @@ -0,0 +1 @@ +Res1 input. diff --git a/Tests/QtAutogen/mocRerun/res1.qrc b/Tests/QtAutogen/mocRerun/res1.qrc new file mode 100644 index 0000000..fb804b5 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/res1.qrc @@ -0,0 +1,5 @@ + + + input.txt + + diff --git a/Tests/QtAutogen/mocRerun/test1.cpp b/Tests/QtAutogen/mocRerun/test1.cpp new file mode 100644 index 0000000..4316a91 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/test1.cpp @@ -0,0 +1,5 @@ +#include "test1.h" +int main() +{ + return 0; +} diff --git a/Tests/QtAutogen/mocRerun/test1a.h.in b/Tests/QtAutogen/mocRerun/test1a.h.in new file mode 100644 index 0000000..fee2c09 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/test1a.h.in @@ -0,0 +1,8 @@ +#include +class test1 : public QObject +{ + Q_OBJECT + public slots: + void onTst1() {} + void onTst2() {} +}; diff --git a/Tests/QtAutogen/mocRerun/test1b.h.in b/Tests/QtAutogen/mocRerun/test1b.h.in new file mode 100644 index 0000000..6531d10 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/test1b.h.in @@ -0,0 +1,7 @@ +#include +class test1 : public QObject +{ + Q_OBJECT + public slots: + void onTst1() {} +}; -- cgit v0.12 From d9a7ef80aaff4373baf4c864c97efbbf20337dea Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 17:26:11 +0100 Subject: Autogen: Test: Add timestamp comparison to moc rerun test --- Tests/QtAutogen/CMakeLists.txt | 43 +++++++++++++++++++++---------- Tests/QtAutogen/mocRerun/CMakeLists.txt | 2 ++ Tests/QtAutogen/rccDepends/CMakeLists.txt | 2 +- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index bf40166..c941d8c 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -95,25 +95,27 @@ if (NOT RCC_DEPENDS) message(SEND_ERROR "Initial build of rccDepends failed. Output: ${output}") endif() -file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/info_file.txt" qrc_files) - -list(GET qrc_files 0 qrc_file1) - +# Get name and timestamp of the output binary +file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/target1.txt" target1List) +list(GET target1List 0 binFile) set(timeformat "%Y%j%H%M%S") +file(TIMESTAMP "${binFile}" timeBegin "${timeformat}") -file(TIMESTAMP "${qrc_file1}" file1_before "${timeformat}") - +# Touch qrc input file and rebuild execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change. execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res1/input.txt") - execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends" + RESULT_VARIABLE rccDepends_result ) +if (rccDepends_result) + message(SEND_ERROR "Second build of rccDepends failed.") +endif() -file(TIMESTAMP "${qrc_file1}" file1_step1 "${timeformat}") - -if (NOT file1_step1 GREATER file1_before) - message(SEND_ERROR "file1 (${qrc_file1}) should have changed in the first step!") +# Compare timestamps +file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}") +if (NOT timeStep1 GREATER timeBegin) + message(SEND_ERROR "file1 (${binFile}) should have changed in the first step!") endif() # -- Test @@ -131,16 +133,29 @@ if (NOT MOC_RERUN) message(SEND_ERROR "Initial build of mocRerun failed. Output: ${output}") endif() -configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY) +# Get name and timestamp of the output binary +file(STRINGS "${CMAKE_CURRENT_BINARY_DIR}/mocRerun/target1.txt" target1List) +list(GET target1List 0 binFile) +set(timeformat "%Y%j%H%M%S") +file(TIMESTAMP "${binFile}" timeBegin "${timeformat}") +# Change file content and rebuild +execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) +configure_file(mocRerun/test1b.h.in mocRerun/test1.h COPYONLY) execute_process(COMMAND "${CMAKE_COMMAND}" --build . WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/mocRerun" - RESULT_VARIABLE automoc_rerun_result + RESULT_VARIABLE mocRerun_result ) -if (automoc_rerun_result) +if (mocRerun_result) message(SEND_ERROR "Second build of mocRerun failed.") endif() +# Compare timestamps +file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}") +if (NOT timeStep1 GREATER timeBegin) + message(SEND_ERROR "File (${binFile}) should have changed in the first step!") +endif() + # -- Test # Test for SKIP_AUTOMOC and SKIP_AUTOGEN on an AUTOMOC enabled target qtx_wrap_cpp(skipMocWrapMoc diff --git a/Tests/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogen/mocRerun/CMakeLists.txt index efe936e..ca0eedf 100644 --- a/Tests/QtAutogen/mocRerun/CMakeLists.txt +++ b/Tests/QtAutogen/mocRerun/CMakeLists.txt @@ -25,3 +25,5 @@ add_executable(test1 ) target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) target_link_libraries(test1 ${QT_CORE_TARGET}) +add_custom_command(TARGET test1 POST_BUILD COMMAND + ${CMAKE_COMMAND} -E echo "$" > target1.txt) diff --git a/Tests/QtAutogen/rccDepends/CMakeLists.txt b/Tests/QtAutogen/rccDepends/CMakeLists.txt index c983420..6fa5752 100644 --- a/Tests/QtAutogen/rccDepends/CMakeLists.txt +++ b/Tests/QtAutogen/rccDepends/CMakeLists.txt @@ -24,4 +24,4 @@ add_executable(test_res1 ) target_link_libraries(test_res1 ${QT_CORE_TARGET}) add_custom_command(TARGET test_res1 POST_BUILD COMMAND - ${CMAKE_COMMAND} -E echo "$" > info_file.txt) + ${CMAKE_COMMAND} -E echo "$" > target1.txt) -- cgit v0.12 From 81656b92107b798d2e78929042812248d12853be Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 17:50:34 +0100 Subject: Autogen: Test: Add generated file to moc rerun test --- Tests/QtAutogen/mocRerun/CMakeLists.txt | 18 ++++++++++++------ Tests/QtAutogen/mocRerun/main.cpp.in | 18 ++++++++++++++++++ Tests/QtAutogen/mocRerun/test1.cpp | 5 ----- Tests/QtAutogen/mocRerun/test1a.h.in | 8 ++++---- Tests/QtAutogen/mocRerun/test1b.h.in | 6 +++--- 5 files changed, 37 insertions(+), 18 deletions(-) create mode 100644 Tests/QtAutogen/mocRerun/main.cpp.in delete mode 100644 Tests/QtAutogen/mocRerun/test1.cpp diff --git a/Tests/QtAutogen/mocRerun/CMakeLists.txt b/Tests/QtAutogen/mocRerun/CMakeLists.txt index ca0eedf..6689f50 100644 --- a/Tests/QtAutogen/mocRerun/CMakeLists.txt +++ b/Tests/QtAutogen/mocRerun/CMakeLists.txt @@ -17,13 +17,19 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) configure_file(test1a.h.in test1.h COPYONLY) +# Generated source file +add_custom_command(OUTPUT main.cpp + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/main.cpp + ) -add_executable(test1 +add_executable(mocRerun ${CMAKE_CURRENT_BINARY_DIR}/test1.h - test1.cpp + ${CMAKE_CURRENT_BINARY_DIR}/main.cpp res1.qrc ) -target_include_directories(test1 PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) -target_link_libraries(test1 ${QT_CORE_TARGET}) -add_custom_command(TARGET test1 POST_BUILD COMMAND - ${CMAKE_COMMAND} -E echo "$" > target1.txt) +target_include_directories(mocRerun PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_link_libraries(mocRerun ${QT_CORE_TARGET}) +# Write target name to text file +add_custom_command(TARGET mocRerun POST_BUILD COMMAND + ${CMAKE_COMMAND} -E echo "$" > target1.txt) diff --git a/Tests/QtAutogen/mocRerun/main.cpp.in b/Tests/QtAutogen/mocRerun/main.cpp.in new file mode 100644 index 0000000..b37ff61 --- /dev/null +++ b/Tests/QtAutogen/mocRerun/main.cpp.in @@ -0,0 +1,18 @@ +#include "test1.h" + +class Test2 : public QObject +{ + Q_OBJECT +public slots: + void onTst1() {} +}; + +int main() +{ + Test1 test1; + Test2 test2; + + return 0; +} + +#include "main.moc" diff --git a/Tests/QtAutogen/mocRerun/test1.cpp b/Tests/QtAutogen/mocRerun/test1.cpp deleted file mode 100644 index 4316a91..0000000 --- a/Tests/QtAutogen/mocRerun/test1.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include "test1.h" -int main() -{ - return 0; -} diff --git a/Tests/QtAutogen/mocRerun/test1a.h.in b/Tests/QtAutogen/mocRerun/test1a.h.in index fee2c09..a335046 100644 --- a/Tests/QtAutogen/mocRerun/test1a.h.in +++ b/Tests/QtAutogen/mocRerun/test1a.h.in @@ -1,8 +1,8 @@ #include -class test1 : public QObject +class Test1 : public QObject { Q_OBJECT - public slots: - void onTst1() {} - void onTst2() {} +public slots: + void onTst1() {} + void onTst2() {} }; diff --git a/Tests/QtAutogen/mocRerun/test1b.h.in b/Tests/QtAutogen/mocRerun/test1b.h.in index 6531d10..6128eeb 100644 --- a/Tests/QtAutogen/mocRerun/test1b.h.in +++ b/Tests/QtAutogen/mocRerun/test1b.h.in @@ -1,7 +1,7 @@ #include -class test1 : public QObject +class Test1 : public QObject { Q_OBJECT - public slots: - void onTst1() {} +public slots: + void onTst1() {} }; -- cgit v0.12 From 7f9baf579033e13a25fb9c4db4c79d8f7bb0b47e Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 18:16:54 +0100 Subject: Autogen: Test: Add generated qrc file to rccDepends test --- Tests/QtAutogen/CMakeLists.txt | 21 ++++++++++++++++++--- Tests/QtAutogen/rccDepends/CMakeLists.txt | 21 +++++++++++++++------ Tests/QtAutogen/rccDepends/main.cpp | 5 +++++ Tests/QtAutogen/rccDepends/res/input1.txt.in | 1 + Tests/QtAutogen/rccDepends/res/input2.txt.in | 1 + Tests/QtAutogen/rccDepends/res1/input.txt.in | 1 - Tests/QtAutogen/rccDepends/res2.qrc.in | 5 +++++ Tests/QtAutogen/rccDepends/test_res1.cpp | 5 ----- 8 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 Tests/QtAutogen/rccDepends/main.cpp create mode 100644 Tests/QtAutogen/rccDepends/res/input1.txt.in create mode 100644 Tests/QtAutogen/rccDepends/res/input2.txt.in delete mode 100644 Tests/QtAutogen/rccDepends/res1/input.txt.in create mode 100644 Tests/QtAutogen/rccDepends/res2.qrc.in delete mode 100644 Tests/QtAutogen/rccDepends/test_res1.cpp diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index c941d8c..1952379 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -101,7 +101,7 @@ list(GET target1List 0 binFile) set(timeformat "%Y%j%H%M%S") file(TIMESTAMP "${binFile}" timeBegin "${timeformat}") -# Touch qrc input file and rebuild +# Touch first qrc input file and rebuild execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change. execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res1/input.txt") execute_process(COMMAND "${CMAKE_COMMAND}" --build . @@ -111,11 +111,26 @@ execute_process(COMMAND "${CMAKE_COMMAND}" --build . if (rccDepends_result) message(SEND_ERROR "Second build of rccDepends failed.") endif() - # Compare timestamps file(TIMESTAMP "${binFile}" timeStep1 "${timeformat}") if (NOT timeStep1 GREATER timeBegin) - message(SEND_ERROR "file1 (${binFile}) should have changed in the first step!") + message(SEND_ERROR "File (${binFile}) should have changed in the first step!") +endif() + +# Touch second qrc input file and rebuild +execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep 1) # Ensure that the timestamp will change. +execute_process(COMMAND "${CMAKE_COMMAND}" -E touch "${CMAKE_CURRENT_BINARY_DIR}/rccDepends/res2/input.txt") +execute_process(COMMAND "${CMAKE_COMMAND}" --build . + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/rccDepends" + RESULT_VARIABLE rccDepends_result +) +if (rccDepends_result) + message(SEND_ERROR "Third build of rccDepends failed.") +endif() +# Compare timestamps +file(TIMESTAMP "${binFile}" timeStep2 "${timeformat}") +if (NOT timeStep2 GREATER timeStep1) + message(SEND_ERROR "File (${binFile}) should have changed in the second step!") endif() # -- Test diff --git a/Tests/QtAutogen/rccDepends/CMakeLists.txt b/Tests/QtAutogen/rccDepends/CMakeLists.txt index 6fa5752..de98573 100644 --- a/Tests/QtAutogen/rccDepends/CMakeLists.txt +++ b/Tests/QtAutogen/rccDepends/CMakeLists.txt @@ -15,13 +15,22 @@ else() set(QT_CORE_TARGET Qt5::Core) endif() +configure_file(res/input1.txt.in res1/input.txt @ONLY) +configure_file(res/input2.txt.in res2/input.txt @ONLY) +# Configure time generated qrc file configure_file(res1.qrc.in res1.qrc @ONLY) -configure_file(res1/input.txt.in res1/input.txt @ONLY) +# Dependency generated qrc file +add_custom_command(OUTPUT res2.qrc + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/res2.qrc.in ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc + ) -add_executable(test_res1 - test_res1.cpp + +add_executable(rccDepends + main.cpp ${CMAKE_CURRENT_BINARY_DIR}/res1.qrc + ${CMAKE_CURRENT_BINARY_DIR}/res2.qrc ) -target_link_libraries(test_res1 ${QT_CORE_TARGET}) -add_custom_command(TARGET test_res1 POST_BUILD COMMAND - ${CMAKE_COMMAND} -E echo "$" > target1.txt) +target_link_libraries(rccDepends ${QT_CORE_TARGET}) +add_custom_command(TARGET rccDepends POST_BUILD COMMAND + ${CMAKE_COMMAND} -E echo "$" > target1.txt) diff --git a/Tests/QtAutogen/rccDepends/main.cpp b/Tests/QtAutogen/rccDepends/main.cpp new file mode 100644 index 0000000..766b775 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/main.cpp @@ -0,0 +1,5 @@ + +int main() +{ + return 0; +} diff --git a/Tests/QtAutogen/rccDepends/res/input1.txt.in b/Tests/QtAutogen/rccDepends/res/input1.txt.in new file mode 100644 index 0000000..da62762 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/res/input1.txt.in @@ -0,0 +1 @@ +Res1 input. diff --git a/Tests/QtAutogen/rccDepends/res/input2.txt.in b/Tests/QtAutogen/rccDepends/res/input2.txt.in new file mode 100644 index 0000000..08e14b7 --- /dev/null +++ b/Tests/QtAutogen/rccDepends/res/input2.txt.in @@ -0,0 +1 @@ +Res2 input. diff --git a/Tests/QtAutogen/rccDepends/res1/input.txt.in b/Tests/QtAutogen/rccDepends/res1/input.txt.in deleted file mode 100644 index da62762..0000000 --- a/Tests/QtAutogen/rccDepends/res1/input.txt.in +++ /dev/null @@ -1 +0,0 @@ -Res1 input. diff --git a/Tests/QtAutogen/rccDepends/res2.qrc.in b/Tests/QtAutogen/rccDepends/res2.qrc.in new file mode 100644 index 0000000..18b916a --- /dev/null +++ b/Tests/QtAutogen/rccDepends/res2.qrc.in @@ -0,0 +1,5 @@ + + + res2/input.txt + + diff --git a/Tests/QtAutogen/rccDepends/test_res1.cpp b/Tests/QtAutogen/rccDepends/test_res1.cpp deleted file mode 100644 index 766b775..0000000 --- a/Tests/QtAutogen/rccDepends/test_res1.cpp +++ /dev/null @@ -1,5 +0,0 @@ - -int main() -{ - return 0; -} -- cgit v0.12 From ef3c319b971de36eabdc4180243a07e3581f84b7 Mon Sep 17 00:00:00 2001 From: Sebastian Holtermann Date: Thu, 2 Mar 2017 19:16:24 +0100 Subject: Autogen: Test: Add mocDepends test --- Tests/QtAutogen/CMakeLists.txt | 4 +++ Tests/QtAutogen/mocDepends/CMakeLists.txt | 45 +++++++++++++++++++++++++++++ Tests/QtAutogen/mocDepends/invalid.hpp.in | 1 + Tests/QtAutogen/mocDepends/object.hpp.in | 14 +++++++++ Tests/QtAutogen/mocDepends/simpleLib.cpp.in | 9 ++++++ Tests/QtAutogen/mocDepends/simpleLib.hpp.in | 11 +++++++ Tests/QtAutogen/mocDepends/test1.cpp | 9 ++++++ Tests/QtAutogen/mocDepends/test2.cpp | 10 +++++++ Tests/QtAutogen/mocDepends/test2.hpp | 16 ++++++++++ 9 files changed, 119 insertions(+) create mode 100644 Tests/QtAutogen/mocDepends/CMakeLists.txt create mode 100644 Tests/QtAutogen/mocDepends/invalid.hpp.in create mode 100644 Tests/QtAutogen/mocDepends/object.hpp.in create mode 100644 Tests/QtAutogen/mocDepends/simpleLib.cpp.in create mode 100644 Tests/QtAutogen/mocDepends/simpleLib.hpp.in create mode 100644 Tests/QtAutogen/mocDepends/test1.cpp create mode 100644 Tests/QtAutogen/mocDepends/test2.cpp create mode 100644 Tests/QtAutogen/mocDepends/test2.hpp diff --git a/Tests/QtAutogen/CMakeLists.txt b/Tests/QtAutogen/CMakeLists.txt index 1952379..86af746 100644 --- a/Tests/QtAutogen/CMakeLists.txt +++ b/Tests/QtAutogen/CMakeLists.txt @@ -239,6 +239,10 @@ target_link_libraries(skipRccB ${QT_LIBRARIES}) add_subdirectory(sameName) # -- Test +# Tests AUTOMOC with generated sources +add_subdirectory(mocDepends) + +# -- Test # Tests various include moc patterns add_subdirectory(mocIncludeStrict) diff --git a/Tests/QtAutogen/mocDepends/CMakeLists.txt b/Tests/QtAutogen/mocDepends/CMakeLists.txt new file mode 100644 index 0000000..8bd72eb --- /dev/null +++ b/Tests/QtAutogen/mocDepends/CMakeLists.txt @@ -0,0 +1,45 @@ +cmake_minimum_required(VERSION 3.7) +project(mocDepends) + +if (QT_TEST_VERSION STREQUAL 4) + find_package(Qt4 REQUIRED) + set(QT_CORE_TARGET Qt4::QtCore) +else() + if (NOT QT_TEST_VERSION STREQUAL 5) + message(SEND_ERROR "Invalid Qt version specified.") + endif() + + find_package(Qt5Core REQUIRED) + set(QT_CORE_TARGET Qt5::Core) +endif() + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +# -- Test 1 using generated header +# This tests the dependency of AUTOMOC of mocDepends1 to the generated object.hpp +add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/object.hpp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/object.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/object.hpp + ) + +add_executable(mocDepends1 test1.cpp + ${CMAKE_CURRENT_BINARY_DIR}/object.hpp +) +target_link_libraries(mocDepends1 ${QT_CORE_TARGET}) +set_target_properties(mocDepends1 PROPERTIES AUTOMOC TRUE) + +# -- Test 2 using generated library +# This tests the dependency of AUTOMOC of mocDepends2 to the +# generated simpleLib.hpp which belongs to a linked library of mocDepends2 +add_custom_command(OUTPUT simpleLib.hpp simpleLib.cpp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/invalid.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp + COMMAND ${CMAKE_COMMAND} -E sleep 3 + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.hpp + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/simpleLib.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/simpleLib.cpp + ) +add_library(SimpleLib STATIC simpleLib.hpp simpleLib.cpp) + +add_executable(mocDepends2 test2.cpp ) +target_link_libraries(mocDepends2 SimpleLib ${QT_CORE_TARGET}) +set_target_properties(mocDepends2 PROPERTIES AUTOMOC TRUE) diff --git a/Tests/QtAutogen/mocDepends/invalid.hpp.in b/Tests/QtAutogen/mocDepends/invalid.hpp.in new file mode 100644 index 0000000..854d9a1 --- /dev/null +++ b/Tests/QtAutogen/mocDepends/invalid.hpp.in @@ -0,0 +1 @@ +#ifndef diff --git a/Tests/QtAutogen/mocDepends/object.hpp.in b/Tests/QtAutogen/mocDepends/object.hpp.in new file mode 100644 index 0000000..f364f7c --- /dev/null +++ b/Tests/QtAutogen/mocDepends/object.hpp.in @@ -0,0 +1,14 @@ +#ifndef OBJECT_HPP +#define OBJECT_HPP + +#include + +class Object : public QObject +{ + Q_OBJECT +public: + Q_SLOT + void aSlot(){}; +}; + +#endif diff --git a/Tests/QtAutogen/mocDepends/simpleLib.cpp.in b/Tests/QtAutogen/mocDepends/simpleLib.cpp.in new file mode 100644 index 0000000..fa33bd3 --- /dev/null +++ b/Tests/QtAutogen/mocDepends/simpleLib.cpp.in @@ -0,0 +1,9 @@ +#include "simpleLib.hpp" + +SimpleLib::SimpleLib() +{ +} + +SimpleLib::~SimpleLib() +{ +} diff --git a/Tests/QtAutogen/mocDepends/simpleLib.hpp.in b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in new file mode 100644 index 0000000..758f1f6 --- /dev/null +++ b/Tests/QtAutogen/mocDepends/simpleLib.hpp.in @@ -0,0 +1,11 @@ +#ifndef SIMPLE_LIB_H +#define SIMPLE_LIB_H + +class SimpleLib +{ +public: + SimpleLib(); + ~SimpleLib(); +}; + +#endif diff --git a/Tests/QtAutogen/mocDepends/test1.cpp b/Tests/QtAutogen/mocDepends/test1.cpp new file mode 100644 index 0000000..92c259c --- /dev/null +++ b/Tests/QtAutogen/mocDepends/test1.cpp @@ -0,0 +1,9 @@ + +#include "object.hpp" + +int main() +{ + Object obj; + + return 0; +} diff --git a/Tests/QtAutogen/mocDepends/test2.cpp b/Tests/QtAutogen/mocDepends/test2.cpp new file mode 100644 index 0000000..155b19b --- /dev/null +++ b/Tests/QtAutogen/mocDepends/test2.cpp @@ -0,0 +1,10 @@ + +#include "test2.hpp" + +int main() +{ + SimpleLib obj; + LObject lobject; + + return 0; +} diff --git a/Tests/QtAutogen/mocDepends/test2.hpp b/Tests/QtAutogen/mocDepends/test2.hpp new file mode 100644 index 0000000..0125f07 --- /dev/null +++ b/Tests/QtAutogen/mocDepends/test2.hpp @@ -0,0 +1,16 @@ +#ifndef TEST2_HPP +#define TEST2_HPP + +#include "simpleLib.hpp" +#include + +// This object triggers the AUTOMOC on this file +class LObject : public QObject +{ + Q_OBJECT +public: + Q_SLOT + void aSlot(){}; +}; + +#endif -- cgit v0.12