diff options
author | Sebastian Holtermann <sebholt@xwmw.org> | 2017-08-31 14:32:14 (GMT) |
---|---|---|
committer | Sebastian Holtermann <sebholt@xwmw.org> | 2017-09-07 15:53:19 (GMT) |
commit | 37ef18a468149ba579b96a763ea3042a360652d7 (patch) | |
tree | 5e83e53948d42c288d473690886ba9c24f9bfc34 /Source | |
parent | 761b3d79746ab91219d6478a021ba3a1c56f05c8 (diff) | |
download | CMake-37ef18a468149ba579b96a763ea3042a360652d7.zip CMake-37ef18a468149ba579b96a763ea3042a360652d7.tar.gz CMake-37ef18a468149ba579b96a763ea3042a360652d7.tar.bz2 |
Autogen: Pass RCC build names and function names in info file
- The output file name of the `rcc` command get computed once
in the AUTOGEN initializer and is passed in the info file.
- The function name for the `-name` option of `rcc` gets computed
once in the AUTOGEN initializer and is passed along with the
other `rcc` options in the info file.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/cmQtAutoGenDigest.h | 4 | ||||
-rw-r--r-- | Source/cmQtAutoGeneratorInitializer.cxx | 106 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.cxx | 219 | ||||
-rw-r--r-- | Source/cmQtAutoGenerators.h | 16 |
4 files changed, 162 insertions, 183 deletions
diff --git a/Source/cmQtAutoGenDigest.h b/Source/cmQtAutoGenDigest.h index 2bd9f04..e756a94 100644 --- a/Source/cmQtAutoGenDigest.h +++ b/Source/cmQtAutoGenDigest.h @@ -16,13 +16,17 @@ class cmQtAutoGenDigestQrc public: cmQtAutoGenDigestQrc() : Generated(false) + , Unique(false) { } public: std::string QrcFile; + std::string QrcName; + std::string PathChecksum; std::string RccFile; bool Generated; + bool Unique; std::vector<std::string> Options; std::vector<std::string> Resources; }; diff --git a/Source/cmQtAutoGeneratorInitializer.cxx b/Source/cmQtAutoGeneratorInitializer.cxx index 0333a55..c7747b8 100644 --- a/Source/cmQtAutoGeneratorInitializer.cxx +++ b/Source/cmQtAutoGeneratorInitializer.cxx @@ -580,40 +580,25 @@ static std::string RccGetExecutable(cmGeneratorTarget const* target, static void SetupAutoTargetRcc(const cmQtAutoGenDigest& digest) { - cmGeneratorTarget const* target = digest.Target; - cmMakefile* makefile = target->Target->GetMakefile(); std::vector<std::string> rccFiles; - std::vector<std::string> rccInputs; - std::vector<std::string> rccFileFiles; - std::vector<std::string> rccFileOptions; + std::vector<std::string> rccBuilds; + std::vector<std::vector<std::string>> rccOptions; + std::vector<std::vector<std::string>> rccInputs; for (const cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { - const std::string absFile = qrcDigest.QrcFile; - // Register file - rccFiles.push_back(absFile); - // Register (known) resource files - { - std::string entriesList = "{"; - if (!qrcDigest.Generated) { - entriesList += cmJoin(qrcDigest.Resources, cmQtAutoGen::listSep); - } - entriesList += "}"; - rccInputs.push_back(entriesList); - } - // rcc options for this qrc file - if (!qrcDigest.Options.empty()) { - rccFileFiles.push_back(absFile); - rccFileOptions.push_back( - cmJoin(qrcDigest.Options, cmQtAutoGen::listSep)); - } + rccFiles.push_back(qrcDigest.QrcFile); + rccBuilds.push_back(qrcDigest.RccFile); + rccOptions.push_back(qrcDigest.Options); + rccInputs.push_back(qrcDigest.Resources); } + cmMakefile* makefile = digest.Target->Target->GetMakefile(); AddDefinitionEscaped(makefile, "_qt_rcc_executable", - RccGetExecutable(target, digest.QtVersionMajor)); + RccGetExecutable(digest.Target, digest.QtVersionMajor)); AddDefinitionEscaped(makefile, "_rcc_files", rccFiles); + AddDefinitionEscaped(makefile, "_rcc_builds", rccBuilds); + AddDefinitionEscaped(makefile, "_rcc_options", rccOptions); AddDefinitionEscaped(makefile, "_rcc_inputs", rccInputs); - AddDefinitionEscaped(makefile, "_rcc_options_files", rccFileFiles); - AddDefinitionEscaped(makefile, "_rcc_options_options", rccFileOptions); } void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( @@ -746,6 +731,8 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( { cmQtAutoGenDigestQrc qrcDigest; qrcDigest.QrcFile = cmSystemTools::GetRealPath(fPath); + qrcDigest.QrcName = + cmSystemTools::GetFilenameWithoutLastExtension(qrcDigest.QrcFile); qrcDigest.Generated = sf->GetPropertyAsBool("GENERATED"); // RCC options { @@ -822,36 +809,65 @@ void cmQtAutoGeneratorInitializer::InitializeAutogenTarget( // Process qrc files if (!digest.Qrcs.empty()) { const bool QtV5 = (digest.QtVersionMajor == "5"); - const cmFilePathChecksum fpathCheckSum(makefile); const std::string rcc = RccGetExecutable(target, digest.QtVersionMajor); // Target rcc options std::vector<std::string> optionsTarget; cmSystemTools::ExpandListArgument( GetSafeProperty(target, "AUTORCC_OPTIONS"), optionsTarget); + // Check if file name is unique for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { - // RCC output file name - { - std::string rccFile = autogenBuildDir + "/"; - rccFile += fpathCheckSum.getPart(qrcDigest.QrcFile); - rccFile += "/qrc_"; - rccFile += - cmSystemTools::GetFilenameWithoutLastExtension(qrcDigest.QrcFile); - rccFile += ".cpp"; - - AddGeneratedSource(target, rccFile, cmQtAutoGen::RCC); - autogenProvides.push_back(rccFile); - qrcDigest.RccFile = std::move(rccFile); + qrcDigest.Unique = true; + for (const cmQtAutoGenDigestQrc& qrcDig2 : digest.Qrcs) { + if ((&qrcDigest != &qrcDig2) && + (qrcDigest.QrcName == qrcDig2.QrcName)) { + qrcDigest.Unique = false; + break; + } } - // RCC options + } + // Path checksum + { + const cmFilePathChecksum fpathCheckSum(makefile); + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + qrcDigest.PathChecksum = fpathCheckSum.getPart(qrcDigest.QrcFile); + } + } + // RCC output file name + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + std::string rccFile = autogenBuildDir + "/"; + rccFile += qrcDigest.PathChecksum; + rccFile += "/qrc_"; + rccFile += qrcDigest.QrcName; + rccFile += ".cpp"; + qrcDigest.RccFile = std::move(rccFile); + } + // RCC options + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + // Target options + std::vector<std::string> opts = optionsTarget; + // Merge computed "-name XYZ" option { - std::vector<std::string> opts = optionsTarget; - if (!qrcDigest.Options.empty()) { - cmQtAutoGen::RccMergeOptions(opts, qrcDigest.Options, QtV5); + std::string name = qrcDigest.QrcName; + // Replace '-' with '_'. The former is not valid for symbol names. + std::replace(name.begin(), name.end(), '-', '_'); + if (!qrcDigest.Unique) { + name += "_"; + name += qrcDigest.PathChecksum; } - qrcDigest.Options = std::move(opts); + std::vector<std::string> nameOpts; + nameOpts.emplace_back("-name"); + nameOpts.emplace_back(std::move(name)); + cmQtAutoGen::RccMergeOptions(opts, nameOpts, QtV5); } - // GENERATED or not + // Merge file option + cmQtAutoGen::RccMergeOptions(opts, qrcDigest.Options, QtV5); + qrcDigest.Options = std::move(opts); + } + for (cmQtAutoGenDigestQrc& qrcDigest : digest.Qrcs) { + // Register file at target + AddGeneratedSource(target, qrcDigest.RccFile, cmQtAutoGen::RCC); + autogenProvides.push_back(qrcDigest.RccFile); if (qrcDigest.Generated) { // Add GENERATED qrc file to the dependencies autogenDepends.insert(qrcDigest.QrcFile); diff --git a/Source/cmQtAutoGenerators.cxx b/Source/cmQtAutoGenerators.cxx index 3369f65..8dc6420 100644 --- a/Source/cmQtAutoGenerators.cxx +++ b/Source/cmQtAutoGenerators.cxx @@ -166,22 +166,6 @@ static std::string SubDirPrefix(const std::string& fileName) return res; } -static bool FileNameIsUnique(const std::string& filePath, - const std::map<std::string, std::string>& fileMap) -{ - size_t count(0); - const std::string fileName = cmSystemTools::GetFilenameName(filePath); - for (const auto& item : fileMap) { - if (cmSystemTools::GetFilenameName(item.first) == fileName) { - ++count; - if (count > 1) { - return false; - } - } - } - return true; -} - static bool ReadAll(std::string& content, const std::string& filename) { bool success = false; @@ -473,51 +457,51 @@ bool cmQtAutoGenerators::ReadAutogenInfoFile( // - Rcc if (this->RccEnabled()) { - InfoGet(makefile, "AM_RCC_SOURCES", this->RccSources); - // File options - { - std::vector<std::string> rccFilesVec; - std::vector<std::string> rccOptionsVec; - InfoGet(makefile, "AM_RCC_OPTIONS_FILES", rccFilesVec); - InfoGet(makefile, "AM_RCC_OPTIONS_OPTIONS", rccOptionsVec); - if (rccFilesVec.size() == rccOptionsVec.size()) { - for (std::vector<std::string>::iterator - fileIt = rccFilesVec.begin(), - optionIt = rccOptionsVec.begin(); - fileIt != rccFilesVec.end(); ++fileIt, ++optionIt) { - // Replace item separator - cmSystemTools::ReplaceString(*optionIt, cmQtAutoGen::listSep, ";"); - this->RccOptions[*fileIt] = *optionIt; - } - } else { - this->LogError( - "AutoGen: Error: RCC files/options lists size missmatch in:\n" + - Quoted(filename)); - return false; - } - } // File lists + auto sources = InfoGetList(makefile, "AM_RCC_SOURCES"); + auto builds = InfoGetList(makefile, "AM_RCC_BUILDS"); + auto options = InfoGetLists(makefile, "AM_RCC_OPTIONS"); + auto inputs = InfoGetLists(makefile, "AM_RCC_INPUTS"); + + if (sources.size() != builds.size()) { + std::ostringstream ost; + ost << "AutoRcc: Error: sources/builds list sizes missmatch (" + << sources.size() << "/" << builds.size() << ")" + << " in\n " << Quoted(filename); + this->LogError(ost.str()); + return false; + } + if (sources.size() != options.size()) { + std::ostringstream ost; + ost << "AutoRcc: Error: sources/options list sizes missmatch (" + << sources.size() << "/" << options.size() << ")" + << " in\n " << Quoted(filename); + this->LogError(ost.str()); + return false; + } + if (sources.size() != inputs.size()) { + std::ostringstream ost; + ost << "AutoRcc: Error: sources/inputs list sizes missmatch (" + << sources.size() << "/" << inputs.size() << ")" + << " in\n " << Quoted(filename); + this->LogError(ost.str()); + return false; + } + { - std::vector<std::string> rccInputLists; - InfoGet(makefile, "AM_RCC_INPUTS", rccInputLists); - if (this->RccSources.size() == rccInputLists.size()) { - for (std::vector<std::string>::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, cmQtAutoGen::listSep, ";"); - std::vector<std::string> rccInputFiles; - cmSystemTools::ExpandListArgument(*inputIt, rccInputFiles); - this->RccInputs[*fileIt] = rccInputFiles; - } - } else { - this->LogError( - "AutoGen: Error: RCC sources/inputs lists size missmatch in:\n" + - Quoted(filename)); - return false; + auto srcItEnd = sources.end(); + auto srcIt = sources.begin(); + auto bldIt = builds.begin(); + auto optIt = options.begin(); + auto inpIt = inputs.begin(); + while (srcIt != srcItEnd) { + this->RccJobs.push_back(RccJob{ std::move(*srcIt), std::move(*bldIt), + std::move(*optIt), + std::move(*inpIt) }); + ++srcIt; + ++bldIt; + ++optIt; + ++inpIt; } } } @@ -560,8 +544,14 @@ void cmQtAutoGenerators::SettingsFileRead(cmMakefile* makefile) if (this->RccEnabled()) { std::string str; str += this->RccExecutable; - str += sep; - str += JoinOptionsMap(this->RccOptions); + for (const RccJob& rccJob : this->RccJobs) { + str += sep; + str += rccJob.QrcFile; + str += sep; + str += rccJob.RccFile; + str += sep; + str += JoinOptionsList(rccJob.Options); + } str += sep; this->SettingsStringRcc = crypt.HashString(str); } @@ -1622,33 +1612,9 @@ bool cmQtAutoGenerators::RccGenerateAll() return true; } - // generate single map with input / output names - std::map<std::string, std::string> qrcGenMap; - { - const std::string qrcPrefix = "qrc_"; - const std::string qrcSuffix = this->ConfigSuffix + ".cpp"; - for (const std::string& src : this->RccSources) { - qrcGenMap[src] = this->ChecksumedPath(src, qrcPrefix, qrcSuffix); - } - } - - // look for name collisions - { - std::multimap<std::string, std::string> collisions; - if (this->NameCollisionTest(qrcGenMap, collisions)) { - std::ostringstream ost; - ost << "AutoRcc: Error: The same qrc_NAME.cpp file" - " will be generated from different sources.\n" - "To avoid this error rename the source .qrc files.\n"; - this->LogErrorNameCollision(ost.str(), collisions); - return false; - } - } - - // generate qrc files - for (const auto& item : qrcGenMap) { - bool unique = FileNameIsUnique(item.first, qrcGenMap); - if (!this->RccGenerateFile(item.first, item.second, unique)) { + // Generate qrc files + for (const RccJob& rccJob : this->RccJobs) { + if (!this->RccGenerateFile(rccJob)) { if (this->RccRunFailed) { return false; } @@ -1660,28 +1626,37 @@ bool cmQtAutoGenerators::RccGenerateAll() /** * @return True if a rcc file was created. False may indicate an error. */ -bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, - const std::string& rccOutputFile, - bool unique_n) +bool cmQtAutoGenerators::RccGenerateFile(const RccJob& rccJob) { bool rccGenerated = false; bool generateRcc = this->RccSettingsChanged; - const std::string rccBuildFile = - cmSystemTools::CollapseCombinedPath(this->AutogenBuildDir, rccOutputFile); + + std::string rccFileAbs; + if (this->ConfigSuffix.empty()) { + rccFileAbs = rccJob.RccFile; + } else { + rccFileAbs = SubDirPrefix(rccJob.RccFile); + rccFileAbs += + cmSystemTools::GetFilenameWithoutLastExtension(rccJob.RccFile); + rccFileAbs += this->ConfigSuffix; + rccFileAbs += cmSystemTools::GetFilenameLastExtension(rccJob.RccFile); + } + const std::string rccFileRel = cmSystemTools::RelativePath( + this->AutogenBuildDir.c_str(), rccFileAbs.c_str()); // Check if regeneration is required if (!generateRcc) { // Test if the resources list file is newer than build file - generateRcc = FileAbsentOrOlder(rccBuildFile, rccInputFile); + generateRcc = FileAbsentOrOlder(rccFileAbs, rccJob.QrcFile); if (!generateRcc) { // Acquire input file list std::vector<std::string> readFiles; - const std::vector<std::string>* files = &this->RccInputs[rccInputFile]; + const std::vector<std::string>* files = &rccJob.Inputs; if (files->empty()) { // Read input file list from qrc file std::string error; if (cmQtAutoGen::RccListInputs(this->QtMajorVersion, - this->RccExecutable, rccInputFile, + this->RccExecutable, rccJob.QrcFile, readFiles, &error)) { files = &readFiles; } else { @@ -1693,7 +1668,7 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, // Test if any input file is newer than the build file if (files != nullptr) { for (const std::string& file : *files) { - if (FileAbsentOrOlder(rccBuildFile, file)) { + if (FileAbsentOrOlder(rccFileAbs, file)) { generateRcc = true; break; } @@ -1705,37 +1680,18 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, if (generateRcc) { // Log if (this->Verbose) { - this->LogBold("Generating RCC source " + rccOutputFile); + this->LogBold("Generating RCC source " + rccFileRel); } // Make sure the parent directory exists - if (this->MakeParentDirectory(cmQtAutoGen::RCC, rccBuildFile)) { - // Compose symbol name - std::string symbolName = - cmSystemTools::GetFilenameWithoutLastExtension(rccInputFile); - if (!unique_n) { - symbolName += "_"; - symbolName += FPathChecksum.getPart(rccInputFile); - } - // Replace '-' with '_'. The former is valid for - // file names but not for symbol names. - std::replace(symbolName.begin(), symbolName.end(), '-', '_'); - + if (this->MakeParentDirectory(cmQtAutoGen::RCC, rccFileAbs)) { // Compose rcc command std::vector<std::string> cmd; cmd.push_back(this->RccExecutable); - { - std::map<std::string, std::string>::const_iterator optionIt = - this->RccOptions.find(rccInputFile); - if (optionIt != this->RccOptions.end()) { - cmSystemTools::ExpandListArgument(optionIt->second, cmd); - } - } - cmd.push_back("-name"); - cmd.push_back(symbolName); + cmd.insert(cmd.end(), rccJob.Options.begin(), rccJob.Options.end()); cmd.push_back("-o"); - cmd.push_back(rccBuildFile); - cmd.push_back(rccInputFile); + cmd.push_back(rccFileAbs); + cmd.push_back(rccJob.QrcFile); std::string output; if (this->RunCommand(cmd, output)) { @@ -1746,12 +1702,12 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, { std::ostringstream ost; ost << "AutoRcc: Error: rcc process failed for\n"; - ost << Quoted(rccOutputFile) << "\n"; + ost << Quoted(rccFileRel) << "\n"; ost << "AutoRcc: Command:\n" << QuotedCommand(cmd) << "\n"; ost << "AutoRcc: Command output:\n" << output << "\n"; this->LogError(ost.str()); } - cmSystemTools::RemoveFile(rccBuildFile); + cmSystemTools::RemoveFile(rccFileAbs); this->RccRunFailed = true; } } else { @@ -1762,17 +1718,14 @@ bool cmQtAutoGenerators::RccGenerateFile(const std::string& rccInputFile, // For a multi configuration generator generate a wrapper file if (!this->ConfigSuffix.empty() && !this->RccRunFailed) { // Wrapper file name - const std::string cppSuffix = ".cpp"; - const size_t suffixLength = this->ConfigSuffix.size() + cppSuffix.size(); - const std::string wrapperFileRel = - rccOutputFile.substr(0, rccOutputFile.size() - suffixLength) + cppSuffix; - const std::string wrapperFileAbs = cmSystemTools::CollapseCombinedPath( - this->AutogenBuildDir, wrapperFileRel); + const std::string& wrapperFileAbs = rccJob.RccFile; + const std::string wrapperFileRel = cmSystemTools::RelativePath( + this->AutogenBuildDir.c_str(), wrapperFileAbs.c_str()); // Wrapper file content - std::string content = - "// This is an autogenerated configuration wrapper file. Do not edit.\n" - "#include \""; - content += cmSystemTools::GetFilenameName(rccBuildFile); + std::string content = "// This is an autogenerated configuration " + "wrapper file. Do not edit.\n" + "#include \""; + content += cmSystemTools::GetFilenameName(rccFileRel); content += "\"\n"; // Write content to file if (this->FileDiffers(wrapperFileAbs, content)) { diff --git a/Source/cmQtAutoGenerators.h b/Source/cmQtAutoGenerators.h index ff31884..975b0b6 100644 --- a/Source/cmQtAutoGenerators.h +++ b/Source/cmQtAutoGenerators.h @@ -46,6 +46,15 @@ private: cmsys::RegularExpression RegExp; }; + /// @brief RCC job + struct RccJob + { + std::string QrcFile; + std::string RccFile; + std::vector<std::string> Options; + std::vector<std::string> Inputs; + }; + // -- Configuration bool MocDependFilterPush(const std::string& key, const std::string& regExp); bool ReadAutogenInfoFile(cmMakefile* makefile, @@ -135,8 +144,7 @@ private: // -- Rcc file generation bool RccGenerateAll(); - bool RccGenerateFile(const std::string& qrcInputFile, - const std::string& qrcOutputFile, bool unique_n); + bool RccGenerateFile(const RccJob& rccJob); // -- Logging void LogErrorNameCollision( @@ -227,9 +235,7 @@ private: // -- Rcc bool RccSettingsChanged; bool RccRunFailed; - std::vector<std::string> RccSources; - std::map<std::string, std::string> RccOptions; - std::map<std::string, std::vector<std::string>> RccInputs; + std::vector<RccJob> RccJobs; }; #endif |