| /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying |
| file Copyright.txt or https://cmake.org/licensing for details. */ |
| #include "cmCPackIFWPackage.h" |
| |
| #include "CPack/cmCPackComponentGroup.h" |
| #include "CPack/cmCPackGenerator.h" |
| #include "CPack/cmCPackLog.h" |
| #include "cmCPackIFWGenerator.h" |
| #include "cmCPackIFWInstaller.h" |
| #include "cmGeneratedFileStream.h" |
| #include "cmSystemTools.h" |
| #include "cmTimestamp.h" |
| #include "cmXMLWriter.h" |
| |
| #include <cmConfigure.h> |
| #include <map> |
| #include <sstream> |
| #include <stddef.h> |
| |
| //----------------------------------------------------------------- Logger --- |
| #ifdef cmCPackLogger |
| #undef cmCPackLogger |
| #endif |
| #define cmCPackLogger(logType, msg) \ |
| do { \ |
| std::ostringstream cmCPackLog_msg; \ |
| cmCPackLog_msg << msg; \ |
| if (Generator) { \ |
| Generator->Logger->Log(logType, __FILE__, __LINE__, \ |
| cmCPackLog_msg.str().c_str()); \ |
| } \ |
| } while (false) |
| |
| //---------------------------------------------------------- CompareStruct --- |
| cmCPackIFWPackage::CompareStruct::CompareStruct() |
| : Type(CompareNone) |
| { |
| } |
| |
| //------------------------------------------------------- DependenceStruct --- |
| cmCPackIFWPackage::DependenceStruct::DependenceStruct() |
| { |
| } |
| |
| cmCPackIFWPackage::DependenceStruct::DependenceStruct( |
| const std::string& dependence) |
| { |
| // Search compare section |
| size_t pos = std::string::npos; |
| if ((pos = dependence.find("<=")) != std::string::npos) { |
| Compare.Type = CompareLessOrEqual; |
| Compare.Value = dependence.substr(pos + 2); |
| } else if ((pos = dependence.find(">=")) != std::string::npos) { |
| Compare.Type = CompareGreaterOrEqual; |
| Compare.Value = dependence.substr(pos + 2); |
| } else if ((pos = dependence.find('<')) != std::string::npos) { |
| Compare.Type = CompareLess; |
| Compare.Value = dependence.substr(pos + 1); |
| } else if ((pos = dependence.find('=')) != std::string::npos) { |
| Compare.Type = CompareEqual; |
| Compare.Value = dependence.substr(pos + 1); |
| } else if ((pos = dependence.find('>')) != std::string::npos) { |
| Compare.Type = CompareGreater; |
| Compare.Value = dependence.substr(pos + 1); |
| } |
| Name = pos == std::string::npos ? dependence : dependence.substr(0, pos); |
| } |
| |
| std::string cmCPackIFWPackage::DependenceStruct::NameWithCompare() const |
| { |
| if (Compare.Type == CompareNone) { |
| return Name; |
| } |
| |
| std::string result = Name; |
| |
| if (Compare.Type == CompareLessOrEqual) { |
| result += "<="; |
| } else if (Compare.Type == CompareGreaterOrEqual) { |
| result += ">="; |
| } else if (Compare.Type == CompareLess) { |
| result += "<"; |
| } else if (Compare.Type == CompareEqual) { |
| result += "="; |
| } else if (Compare.Type == CompareGreater) { |
| result += ">"; |
| } |
| |
| result += Compare.Value; |
| |
| return result; |
| } |
| |
| //------------------------------------------------------ cmCPackIFWPackage --- |
| cmCPackIFWPackage::cmCPackIFWPackage() |
| : Generator(CM_NULLPTR) |
| , Installer(CM_NULLPTR) |
| { |
| } |
| |
| const char* cmCPackIFWPackage::GetOption(const std::string& op) const |
| { |
| const char* option = Generator ? Generator->GetOption(op) : CM_NULLPTR; |
| return option && *option ? option : CM_NULLPTR; |
| } |
| |
| bool cmCPackIFWPackage::IsOn(const std::string& op) const |
| { |
| return Generator ? Generator->IsOn(op) : false; |
| } |
| |
| bool cmCPackIFWPackage::IsSetToOff(const std::string& op) const |
| { |
| return Generator ? Generator->IsSetToOff(op) : false; |
| } |
| |
| bool cmCPackIFWPackage::IsSetToEmpty(const std::string& op) const |
| { |
| return Generator ? Generator->IsSetToEmpty(op) : false; |
| } |
| |
| bool cmCPackIFWPackage::IsVersionLess(const char* version) |
| { |
| return Generator ? Generator->IsVersionLess(version) : false; |
| } |
| |
| bool cmCPackIFWPackage::IsVersionGreater(const char* version) |
| { |
| return Generator ? Generator->IsVersionGreater(version) : false; |
| } |
| |
| bool cmCPackIFWPackage::IsVersionEqual(const char* version) |
| { |
| return Generator ? Generator->IsVersionEqual(version) : false; |
| } |
| |
| std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component) |
| { |
| if (!component) { |
| return ""; |
| } |
| const char* option = |
| GetOption("CPACK_IFW_COMPONENT_" + |
| cmsys::SystemTools::UpperCase(component->Name) + "_NAME"); |
| return option ? option : component->Name; |
| } |
| |
| void cmCPackIFWPackage::DefaultConfiguration() |
| { |
| DisplayName = ""; |
| Description = ""; |
| Version = ""; |
| ReleaseDate = ""; |
| Script = ""; |
| Licenses.clear(); |
| UserInterfaces.clear(); |
| SortingPriority = ""; |
| Default = ""; |
| Essential = ""; |
| Virtual = ""; |
| ForcedInstallation = ""; |
| } |
| |
| // Defaul configuration (all in one package) |
| int cmCPackIFWPackage::ConfigureFromOptions() |
| { |
| // Restore defaul configuration |
| DefaultConfiguration(); |
| |
| // Name |
| Name = Generator->GetRootPackageName(); |
| |
| // Display name |
| if (const char* option = this->GetOption("CPACK_PACKAGE_NAME")) { |
| DisplayName = option; |
| } else { |
| DisplayName = "Your package"; |
| } |
| |
| // Description |
| if (const char* option = |
| this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { |
| Description = option; |
| } else { |
| Description = "Your package description"; |
| } |
| |
| // Version |
| if (const char* option = GetOption("CPACK_PACKAGE_VERSION")) { |
| Version = option; |
| } else { |
| Version = "1.0.0"; |
| } |
| |
| ForcedInstallation = "true"; |
| |
| return 1; |
| } |
| |
| int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component) |
| { |
| if (!component) { |
| return 0; |
| } |
| |
| // Restore defaul configuration |
| DefaultConfiguration(); |
| |
| std::string prefix = "CPACK_IFW_COMPONENT_" + |
| cmsys::SystemTools::UpperCase(component->Name) + "_"; |
| |
| // Display name |
| DisplayName = component->DisplayName; |
| |
| // Description |
| Description = component->Description; |
| |
| // Version |
| if (const char* optVERSION = GetOption(prefix + "VERSION")) { |
| Version = optVERSION; |
| } else if (const char* optPACKAGE_VERSION = |
| GetOption("CPACK_PACKAGE_VERSION")) { |
| Version = optPACKAGE_VERSION; |
| } else { |
| Version = "1.0.0"; |
| } |
| |
| // Script |
| if (const char* option = GetOption(prefix + "SCRIPT")) { |
| Script = option; |
| } |
| |
| // User interfaces |
| if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { |
| UserInterfaces.clear(); |
| cmSystemTools::ExpandListArgument(option, UserInterfaces); |
| } |
| |
| // CMake dependencies |
| if (!component->Dependencies.empty()) { |
| std::vector<cmCPackComponent*>::iterator dit; |
| for (dit = component->Dependencies.begin(); |
| dit != component->Dependencies.end(); ++dit) { |
| Dependencies.insert(Generator->ComponentPackages[*dit]); |
| } |
| } |
| |
| // QtIFW dependencies |
| if (const char* option = this->GetOption(prefix + "DEPENDS")) { |
| std::vector<std::string> deps; |
| cmSystemTools::ExpandListArgument(option, deps); |
| for (std::vector<std::string>::iterator dit = deps.begin(); |
| dit != deps.end(); ++dit) { |
| DependenceStruct dep(*dit); |
| if (!Generator->Packages.count(dep.Name)) { |
| bool hasDep = Generator->DependentPackages.count(dep.Name) > 0; |
| DependenceStruct& depRef = Generator->DependentPackages[dep.Name]; |
| if (!hasDep) { |
| depRef = dep; |
| } |
| AlienDependencies.insert(&depRef); |
| } |
| } |
| } |
| |
| // Licenses |
| if (const char* option = this->GetOption(prefix + "LICENSES")) { |
| Licenses.clear(); |
| cmSystemTools::ExpandListArgument(option, Licenses); |
| if (Licenses.size() % 2 != 0) { |
| cmCPackLogger( |
| cmCPackLog::LOG_WARNING, prefix |
| << "LICENSES" |
| << " should contain pairs of <display_name> and <file_path>." |
| << std::endl); |
| Licenses.clear(); |
| } |
| } |
| |
| // Priority |
| if (const char* option = this->GetOption(prefix + "PRIORITY")) { |
| SortingPriority = option; |
| } |
| |
| // Default |
| Default = component->IsDisabledByDefault ? "false" : "true"; |
| |
| // Essential |
| if (this->IsOn(prefix + "ESSENTIAL")) { |
| Essential = "true"; |
| } |
| |
| // Virtual |
| Virtual = component->IsHidden ? "true" : ""; |
| |
| // ForcedInstallation |
| ForcedInstallation = component->IsRequired ? "true" : "false"; |
| |
| return ConfigureFromPrefix(prefix); |
| } |
| |
| int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group) |
| { |
| if (!group) { |
| return 0; |
| } |
| |
| // Restore defaul configuration |
| DefaultConfiguration(); |
| |
| std::string prefix = "CPACK_IFW_COMPONENT_GROUP_" + |
| cmsys::SystemTools::UpperCase(group->Name) + "_"; |
| |
| DisplayName = group->DisplayName; |
| Description = group->Description; |
| |
| // Version |
| if (const char* optVERSION = GetOption(prefix + "VERSION")) { |
| Version = optVERSION; |
| } else if (const char* optPACKAGE_VERSION = |
| GetOption("CPACK_PACKAGE_VERSION")) { |
| Version = optPACKAGE_VERSION; |
| } else { |
| Version = "1.0.0"; |
| } |
| |
| // Script |
| if (const char* option = GetOption(prefix + "SCRIPT")) { |
| Script = option; |
| } |
| |
| // User interfaces |
| if (const char* option = this->GetOption(prefix + "USER_INTERFACES")) { |
| UserInterfaces.clear(); |
| cmSystemTools::ExpandListArgument(option, UserInterfaces); |
| } |
| |
| // Licenses |
| if (const char* option = this->GetOption(prefix + "LICENSES")) { |
| Licenses.clear(); |
| cmSystemTools::ExpandListArgument(option, Licenses); |
| if (Licenses.size() % 2 != 0) { |
| cmCPackLogger( |
| cmCPackLog::LOG_WARNING, prefix |
| << "LICENSES" |
| << " should contain pairs of <display_name> and <file_path>." |
| << std::endl); |
| Licenses.clear(); |
| } |
| } |
| |
| // Priority |
| if (const char* option = this->GetOption(prefix + "PRIORITY")) { |
| SortingPriority = option; |
| } |
| |
| return ConfigureFromPrefix(prefix); |
| } |
| |
| int cmCPackIFWPackage::ConfigureFromGroup(const std::string& groupName) |
| { |
| // Group configuration |
| |
| cmCPackComponentGroup group; |
| std::string prefix = |
| "CPACK_COMPONENT_GROUP_" + cmsys::SystemTools::UpperCase(groupName) + "_"; |
| |
| if (const char* option = GetOption(prefix + "DISPLAY_NAME")) { |
| group.DisplayName = option; |
| } else { |
| group.DisplayName = group.Name; |
| } |
| |
| if (const char* option = GetOption(prefix + "DESCRIPTION")) { |
| group.Description = option; |
| } |
| group.IsBold = IsOn(prefix + "BOLD_TITLE"); |
| group.IsExpandedByDefault = IsOn(prefix + "EXPANDED"); |
| |
| // Package configuration |
| |
| group.Name = groupName; |
| |
| if (Generator) { |
| Name = Generator->GetGroupPackageName(&group); |
| } else { |
| Name = group.Name; |
| } |
| |
| return ConfigureFromGroup(&group); |
| } |
| |
| // Common options for components and groups |
| int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix) |
| { |
| // Temporary variable for full option name |
| std::string option; |
| |
| // Display name |
| option = prefix + "DISPLAY_NAME"; |
| if (IsSetToEmpty(option)) { |
| DisplayName.clear(); |
| } else if (const char* value = GetOption(option)) { |
| DisplayName = value; |
| } |
| |
| // Description |
| option = prefix + "DESCRIPTION"; |
| if (IsSetToEmpty(option)) { |
| Description.clear(); |
| } else if (const char* value = GetOption(option)) { |
| Description = value; |
| } |
| |
| // Release date |
| option = prefix + "RELEASE_DATE"; |
| if (IsSetToEmpty(option)) { |
| ReleaseDate.clear(); |
| } else if (const char* value = GetOption(option)) { |
| ReleaseDate = value; |
| } |
| |
| // Visibility |
| option = prefix + "VIRTUAL"; |
| if (IsSetToEmpty(option)) { |
| Virtual.clear(); |
| } else if (IsOn(option)) { |
| Virtual = "true"; |
| } |
| |
| // Default selection |
| option = prefix + "DEFAULT"; |
| if (IsSetToEmpty(option)) { |
| Default.clear(); |
| } else if (const char* value = GetOption(option)) { |
| std::string lowerValue = cmsys::SystemTools::LowerCase(value); |
| if (lowerValue.compare("true") == 0) { |
| Default = "true"; |
| } else if (lowerValue.compare("false") == 0) { |
| Default = "false"; |
| } else if (lowerValue.compare("script") == 0) { |
| Default = "script"; |
| } else { |
| Default = value; |
| } |
| } |
| |
| // Forsed installation |
| option = prefix + "FORCED_INSTALLATION"; |
| if (IsSetToEmpty(option)) { |
| ForcedInstallation.clear(); |
| } else if (IsOn(option)) { |
| ForcedInstallation = "true"; |
| } else if (IsSetToOff(option)) { |
| ForcedInstallation = "false"; |
| } |
| |
| return 1; |
| } |
| |
| void cmCPackIFWPackage::GeneratePackageFile() |
| { |
| // Lazy directory initialization |
| if (Directory.empty()) { |
| if (Installer) { |
| Directory = Installer->Directory + "/packages/" + Name; |
| } else if (Generator) { |
| Directory = Generator->toplevel + "/packages/" + Name; |
| } |
| } |
| |
| // Output stream |
| cmGeneratedFileStream fout((Directory + "/meta/package.xml").data()); |
| cmXMLWriter xout(fout); |
| |
| xout.StartDocument(); |
| |
| WriteGeneratedByToStrim(xout); |
| |
| xout.StartElement("Package"); |
| |
| xout.Element("DisplayName", DisplayName); |
| xout.Element("Description", Description); |
| xout.Element("Name", Name); |
| xout.Element("Version", Version); |
| |
| if (!ReleaseDate.empty()) { |
| xout.Element("ReleaseDate", ReleaseDate); |
| } else { |
| xout.Element("ReleaseDate", cmTimestamp().CurrentTime("%Y-%m-%d", true)); |
| } |
| |
| // Script (copy to meta dir) |
| if (!Script.empty()) { |
| std::string name = cmSystemTools::GetFilenameName(Script); |
| std::string path = Directory + "/meta/" + name; |
| cmsys::SystemTools::CopyFileIfDifferent(Script.data(), path.data()); |
| xout.Element("Script", name); |
| } |
| |
| // User Interfaces (copy to meta dir) |
| std::vector<std::string> userInterfaces = UserInterfaces; |
| for (size_t i = 0; i < userInterfaces.size(); i++) { |
| std::string name = cmSystemTools::GetFilenameName(userInterfaces[i]); |
| std::string path = Directory + "/meta/" + name; |
| cmsys::SystemTools::CopyFileIfDifferent(userInterfaces[i].data(), |
| path.data()); |
| userInterfaces[i] = name; |
| } |
| if (!userInterfaces.empty()) { |
| xout.StartElement("UserInterfaces"); |
| for (size_t i = 0; i < userInterfaces.size(); i++) { |
| xout.Element("UserInterface", userInterfaces[i]); |
| } |
| xout.EndElement(); |
| } |
| |
| // Dependencies |
| std::set<DependenceStruct> compDepSet; |
| for (std::set<DependenceStruct*>::iterator ait = AlienDependencies.begin(); |
| ait != AlienDependencies.end(); ++ait) { |
| compDepSet.insert(*(*ait)); |
| } |
| for (std::set<cmCPackIFWPackage*>::iterator it = Dependencies.begin(); |
| it != Dependencies.end(); ++it) { |
| compDepSet.insert(DependenceStruct((*it)->Name)); |
| } |
| // Write dependencies |
| if (!compDepSet.empty()) { |
| std::ostringstream dependencies; |
| std::set<DependenceStruct>::iterator it = compDepSet.begin(); |
| dependencies << it->NameWithCompare(); |
| ++it; |
| while (it != compDepSet.end()) { |
| dependencies << "," << it->NameWithCompare(); |
| ++it; |
| } |
| xout.Element("Dependencies", dependencies.str()); |
| } |
| |
| // Licenses (copy to meta dir) |
| std::vector<std::string> licenses = Licenses; |
| for (size_t i = 1; i < licenses.size(); i += 2) { |
| std::string name = cmSystemTools::GetFilenameName(licenses[i]); |
| std::string path = Directory + "/meta/" + name; |
| cmsys::SystemTools::CopyFileIfDifferent(licenses[i].data(), path.data()); |
| licenses[i] = name; |
| } |
| if (!licenses.empty()) { |
| xout.StartElement("Licenses"); |
| for (size_t i = 0; i < licenses.size(); i += 2) { |
| xout.StartElement("License"); |
| xout.Attribute("name", licenses[i]); |
| xout.Attribute("file", licenses[i + 1]); |
| xout.EndElement(); |
| } |
| xout.EndElement(); |
| } |
| |
| if (!ForcedInstallation.empty()) { |
| xout.Element("ForcedInstallation", ForcedInstallation); |
| } |
| |
| if (!Virtual.empty()) { |
| xout.Element("Virtual", Virtual); |
| } else if (!Default.empty()) { |
| xout.Element("Default", Default); |
| } |
| |
| // Essential |
| if (!Essential.empty()) { |
| xout.Element("Essential", Essential); |
| } |
| |
| // Priority |
| if (!SortingPriority.empty()) { |
| xout.Element("SortingPriority", SortingPriority); |
| } |
| |
| xout.EndElement(); |
| xout.EndDocument(); |
| } |
| |
| void cmCPackIFWPackage::WriteGeneratedByToStrim(cmXMLWriter& xout) |
| { |
| if (Generator) { |
| Generator->WriteGeneratedByToStrim(xout); |
| } |
| } |