diff options
Diffstat (limited to 'Source/CPack/IFW/cmCPackIFWGenerator.cxx')
-rw-r--r-- | Source/CPack/IFW/cmCPackIFWGenerator.cxx | 582 |
1 files changed, 582 insertions, 0 deletions
diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx new file mode 100644 index 0000000..4a5eb90 --- /dev/null +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -0,0 +1,582 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc., Insight Software Consortium + + Distributed under the OSI-approved BSD License (the "License"); + see accompanying file Copyright.txt for details. + + This software is distributed WITHOUT ANY WARRANTY; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the License for more information. +============================================================================*/ + +#include "cmCPackIFWGenerator.h" + +#include <CPack/cmCPackComponentGroup.h> +#include <CPack/cmCPackLog.h> + +#include <cmsys/Directory.hxx> +#include <cmsys/Glob.hxx> +#include <cmsys/RegularExpression.hxx> +#include <cmsys/SystemTools.hxx> + +#include <cmGeneratedFileStream.h> +#include <cmGlobalGenerator.h> +#include <cmMakefile.h> +#include <cmSystemTools.h> +#include <cmTimestamp.h> +#include <cmVersionConfig.h> +#include <cmXMLWriter.h> + +cmCPackIFWGenerator::cmCPackIFWGenerator() +{ +} + +cmCPackIFWGenerator::~cmCPackIFWGenerator() +{ +} + +bool cmCPackIFWGenerator::IsVersionLess(const char* version) +{ + return cmSystemTools::VersionCompare(cmSystemTools::OP_LESS, + FrameworkVersion.data(), version); +} + +bool cmCPackIFWGenerator::IsVersionGreater(const char* version) +{ + return cmSystemTools::VersionCompare(cmSystemTools::OP_GREATER, + FrameworkVersion.data(), version); +} + +bool cmCPackIFWGenerator::IsVersionEqual(const char* version) +{ + return cmSystemTools::VersionCompare(cmSystemTools::OP_EQUAL, + FrameworkVersion.data(), version); +} + +int cmCPackIFWGenerator::PackageFiles() +{ + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl); + + // Installer configuragion + Installer.GenerateInstallerFile(); + + // Packages configuration + Installer.GeneratePackageFiles(); + + std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + std::string ifwTmpFile = ifwTLD; + ifwTmpFile += "/IFWOutput.log"; + + // Run repogen + if (!Installer.RemoteRepositories.empty()) { + std::string ifwCmd = RepoGen; + + if (IsVersionLess("2.0.0")) { + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + } + + ifwCmd += " -p " + this->toplevel + "/packages"; + + if (!PkgsDirsVector.empty()) { + for (std::vector<std::string>::iterator it = PkgsDirsVector.begin(); + it != PkgsDirsVector.end(); ++it) { + ifwCmd += " -p " + *it; + } + } + + if (!OnlineOnly && !DownloadedPackages.empty()) { + ifwCmd += " -i "; + std::set<cmCPackIFWPackage*>::iterator it = DownloadedPackages.begin(); + ifwCmd += (*it)->Name; + ++it; + while (it != DownloadedPackages.end()) { + ifwCmd += "," + (*it)->Name; + ++it; + } + } + ifwCmd += " " + this->toplevel + "/repository"; + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd << std::endl); + std::string output; + int retVal = 1; + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate repository" + << std::endl); + bool res = cmSystemTools::RunSingleCommand(ifwCmd.c_str(), &output, + &output, &retVal, CM_NULLPTR, + this->GeneratorVerbose, 0); + if (!res || retVal) { + cmGeneratedFileStream ofs(ifwTmpFile.c_str()); + ofs << "# Run command: " << ifwCmd << std::endl + << "# Output:" << std::endl + << output << std::endl; + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: " + << ifwCmd << std::endl + << "Please check " << ifwTmpFile << " for errors" + << std::endl); + return 0; + } + + if (!Repository.RepositoryUpdate.empty() && + !Repository.PatchUpdatesXml()) { + cmCPackLogger(cmCPackLog::LOG_WARNING, "Problem patch IFW \"Updates\" " + << "file: " << this->toplevel + "/repository/Updates.xml" + << std::endl); + } + + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- repository: " + << this->toplevel << "/repository generated" << std::endl); + } + + // Run binary creator + { + std::string ifwCmd = BinCreator; + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + ifwCmd += " -p " + this->toplevel + "/packages"; + + if (!PkgsDirsVector.empty()) { + for (std::vector<std::string>::iterator it = PkgsDirsVector.begin(); + it != PkgsDirsVector.end(); ++it) { + ifwCmd += " -p " + *it; + } + } + + if (OnlineOnly) { + ifwCmd += " --online-only"; + } else if (!DownloadedPackages.empty() && + !Installer.RemoteRepositories.empty()) { + ifwCmd += " -e "; + std::set<cmCPackIFWPackage*>::iterator it = DownloadedPackages.begin(); + ifwCmd += (*it)->Name; + ++it; + while (it != DownloadedPackages.end()) { + ifwCmd += "," + (*it)->Name; + ++it; + } + } else if (!DependentPackages.empty()) { + ifwCmd += " -i "; + // Binary + std::set<cmCPackIFWPackage*>::iterator bit = BinaryPackages.begin(); + while (bit != BinaryPackages.end()) { + ifwCmd += (*bit)->Name + ","; + ++bit; + } + // Depend + DependenceMap::iterator it = DependentPackages.begin(); + ifwCmd += it->second.Name; + ++it; + while (it != DependentPackages.end()) { + ifwCmd += "," + it->second.Name; + ++it; + } + } + // TODO: set correct name for multipackages + if (!this->packageFileNames.empty()) { + ifwCmd += " " + packageFileNames[0]; + } else { + ifwCmd += " installer"; + } + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd << std::endl); + std::string output; + int retVal = 1; + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl); + bool res = cmSystemTools::RunSingleCommand(ifwCmd.c_str(), &output, + &output, &retVal, CM_NULLPTR, + this->GeneratorVerbose, 0); + if (!res || retVal) { + cmGeneratedFileStream ofs(ifwTmpFile.c_str()); + ofs << "# Run command: " << ifwCmd << std::endl + << "# Output:" << std::endl + << output << std::endl; + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem running IFW command: " + << ifwCmd << std::endl + << "Please check " << ifwTmpFile << " for errors" + << std::endl); + return 0; + } + } + + return 1; +} + +const char* cmCPackIFWGenerator::GetPackagingInstallPrefix() +{ + const char* defPrefix = cmCPackGenerator::GetPackagingInstallPrefix(); + + std::string tmpPref = defPrefix ? defPrefix : ""; + + if (this->Components.empty()) { + tmpPref += "packages/" + GetRootPackageName() + "/data"; + } + + this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str()); + + return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX"); +} + +const char* cmCPackIFWGenerator::GetOutputExtension() +{ + return ExecutableSuffix.c_str(); +} + +int cmCPackIFWGenerator::InitializeInternal() +{ + // Search Qt Installer Framework tools + + const std::string BinCreatorOpt = "CPACK_IFW_BINARYCREATOR_EXECUTABLE"; + const std::string RepoGenOpt = "CPACK_IFW_REPOGEN_EXECUTABLE"; + const std::string FrameworkVersionOpt = "CPACK_IFW_FRAMEWORK_VERSION"; + + if (!this->IsSet(BinCreatorOpt) || !this->IsSet(RepoGenOpt) || + !this->IsSet(FrameworkVersionOpt)) { + this->ReadListFile("CPackIFW.cmake"); + } + + // Look 'binarycreator' executable (needs) + + const char* BinCreatorStr = this->GetOption(BinCreatorOpt); + if (!BinCreatorStr || cmSystemTools::IsNOTFOUND(BinCreatorStr)) { + BinCreator = ""; + } else { + BinCreator = BinCreatorStr; + } + + if (BinCreator.empty()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find QtIFW compiler \"binarycreator\": " + "likely it is not installed, or not in your PATH" + << std::endl); + return 0; + } + + // Look 'repogen' executable (optional) + + const char* RepoGenStr = this->GetOption(RepoGenOpt); + if (!RepoGenStr || cmSystemTools::IsNOTFOUND(RepoGenStr)) { + RepoGen = ""; + } else { + RepoGen = RepoGenStr; + } + + // Framework version + if (const char* FrameworkVersionSrt = this->GetOption(FrameworkVersionOpt)) { + FrameworkVersion = FrameworkVersionSrt; + } else { + FrameworkVersion = "1.9.9"; + } + + // Variables that Change Behavior + + // Resolve duplicate names + ResolveDuplicateNames = this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES"); + + // Additional packages dirs + PkgsDirsVector.clear(); + if (const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) { + cmSystemTools::ExpandListArgument(dirs, PkgsDirsVector); + } + + // Installer + Installer.Generator = this; + Installer.ConfigureFromOptions(); + + // Repository + Repository.Generator = this; + Repository.Name = "Unspecified"; + if (const char* site = this->GetOption("CPACK_DOWNLOAD_SITE")) { + Repository.Url = site; + Installer.RemoteRepositories.push_back(&Repository); + } + + // Repositories + if (const char* RepoAllStr = this->GetOption("CPACK_IFW_REPOSITORIES_ALL")) { + std::vector<std::string> RepoAllVector; + cmSystemTools::ExpandListArgument(RepoAllStr, RepoAllVector); + for (std::vector<std::string>::iterator rit = RepoAllVector.begin(); + rit != RepoAllVector.end(); ++rit) { + GetRepository(*rit); + } + } + + if (const char* ifwDownloadAll = this->GetOption("CPACK_IFW_DOWNLOAD_ALL")) { + OnlineOnly = cmSystemTools::IsOn(ifwDownloadAll); + } else if (const char* cpackDownloadAll = + this->GetOption("CPACK_DOWNLOAD_ALL")) { + OnlineOnly = cmSystemTools::IsOn(cpackDownloadAll); + } else { + OnlineOnly = false; + } + + if (!Installer.RemoteRepositories.empty() && RepoGen.empty()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find QtIFW repository generator \"repogen\": " + "likely it is not installed, or not in your PATH" + << std::endl); + return 0; + } + + // Executable suffix + if (const char* optExeSuffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX")) { + ExecutableSuffix = optExeSuffix; + if (ExecutableSuffix.empty()) { + std::string sysName(this->GetOption("CMAKE_SYSTEM_NAME")); + if (sysName == "Linux") { + ExecutableSuffix = ".run"; + } + } + } else { + ExecutableSuffix = cmCPackGenerator::GetOutputExtension(); + } + + return this->Superclass::InitializeInternal(); +} + +std::string cmCPackIFWGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) +{ + const std::string prefix = "packages/"; + const std::string suffix = "/data"; + + if (componentPackageMethod == ONE_PACKAGE) { + return std::string(prefix + GetRootPackageName() + suffix); + } + + return prefix + GetComponentPackageName(&Components[componentName]) + suffix; +} + +cmCPackComponent* cmCPackIFWGenerator::GetComponent( + const std::string& projectName, const std::string& componentName) +{ + ComponentsMap::iterator cit = Components.find(componentName); + if (cit != Components.end()) { + return &(cit->second); + } + + cmCPackComponent* component = + cmCPackGenerator::GetComponent(projectName, componentName); + if (!component) { + return component; + } + + std::string name = GetComponentPackageName(component); + PackagesMap::iterator pit = Packages.find(name); + if (pit != Packages.end()) { + return component; + } + + cmCPackIFWPackage* package = &Packages[name]; + package->Name = name; + package->Generator = this; + if (package->ConfigureFromComponent(component)) { + package->Installer = &Installer; + Installer.Packages.insert( + std::pair<std::string, cmCPackIFWPackage*>(name, package)); + ComponentPackages.insert( + std::pair<cmCPackComponent*, cmCPackIFWPackage*>(component, package)); + if (component->IsDownloaded) { + DownloadedPackages.insert(package); + } else { + BinaryPackages.insert(package); + } + } else { + Packages.erase(name); + cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot configure package \"" + << name << "\" for component \"" << component->Name << "\"" + << std::endl); + } + + return component; +} + +cmCPackComponentGroup* cmCPackIFWGenerator::GetComponentGroup( + const std::string& projectName, const std::string& groupName) +{ + cmCPackComponentGroup* group = + cmCPackGenerator::GetComponentGroup(projectName, groupName); + if (!group) { + return group; + } + + std::string name = GetGroupPackageName(group); + PackagesMap::iterator pit = Packages.find(name); + if (pit != Packages.end()) { + return group; + } + + cmCPackIFWPackage* package = &Packages[name]; + package->Name = name; + package->Generator = this; + if (package->ConfigureFromGroup(group)) { + package->Installer = &Installer; + Installer.Packages.insert( + std::pair<std::string, cmCPackIFWPackage*>(name, package)); + GroupPackages.insert( + std::pair<cmCPackComponentGroup*, cmCPackIFWPackage*>(group, package)); + BinaryPackages.insert(package); + } else { + Packages.erase(name); + cmCPackLogger(cmCPackLog::LOG_ERROR, "Cannot configure package \"" + << name << "\" for component group \"" << group->Name + << "\"" << std::endl); + } + return group; +} + +enum cmCPackGenerator::CPackSetDestdirSupport +cmCPackIFWGenerator::SupportsSetDestdir() const +{ + return cmCPackGenerator::SETDESTDIR_SHOULD_NOT_BE_USED; +} + +bool cmCPackIFWGenerator::SupportsAbsoluteDestination() const +{ + return false; +} + +bool cmCPackIFWGenerator::SupportsComponentInstallation() const +{ + return true; +} + +bool cmCPackIFWGenerator::IsOnePackage() const +{ + return componentPackageMethod == ONE_PACKAGE; +} + +std::string cmCPackIFWGenerator::GetRootPackageName() +{ + // Default value + std::string name = "root"; + if (const char* optIFW_PACKAGE_GROUP = + this->GetOption("CPACK_IFW_PACKAGE_GROUP")) { + // Configure from root group + cmCPackIFWPackage package; + package.Generator = this; + package.ConfigureFromGroup(optIFW_PACKAGE_GROUP); + name = package.Name; + } else if (const char* optIFW_PACKAGE_NAME = + this->GetOption("CPACK_IFW_PACKAGE_NAME")) { + // Configure from root package name + name = optIFW_PACKAGE_NAME; + } else if (const char* optPACKAGE_NAME = + this->GetOption("CPACK_PACKAGE_NAME")) { + // Configure from package name + name = optPACKAGE_NAME; + } + return name; +} + +std::string cmCPackIFWGenerator::GetGroupPackageName( + cmCPackComponentGroup* group) const +{ + std::string name; + if (!group) { + return name; + } + if (cmCPackIFWPackage* package = GetGroupPackage(group)) { + return package->Name; + } + const char* option = + GetOption("CPACK_IFW_COMPONENT_GROUP_" + + cmsys::SystemTools::UpperCase(group->Name) + "_NAME"); + name = option ? option : group->Name; + if (group->ParentGroup) { + cmCPackIFWPackage* package = GetGroupPackage(group->ParentGroup); + bool dot = !ResolveDuplicateNames; + if (dot && name.substr(0, package->Name.size()) == package->Name) { + dot = false; + } + if (dot) { + name = package->Name + "." + name; + } + } + return name; +} + +std::string cmCPackIFWGenerator::GetComponentPackageName( + cmCPackComponent* component) const +{ + std::string name; + if (!component) { + return name; + } + if (cmCPackIFWPackage* package = GetComponentPackage(component)) { + return package->Name; + } + std::string prefix = "CPACK_IFW_COMPONENT_" + + cmsys::SystemTools::UpperCase(component->Name) + "_"; + const char* option = GetOption(prefix + "NAME"); + name = option ? option : component->Name; + if (component->Group) { + cmCPackIFWPackage* package = GetGroupPackage(component->Group); + if ((componentPackageMethod == ONE_PACKAGE_PER_GROUP) || + IsOn(prefix + "COMMON")) { + return package->Name; + } + bool dot = !ResolveDuplicateNames; + if (dot && name.substr(0, package->Name.size()) == package->Name) { + dot = false; + } + if (dot) { + name = package->Name + "." + name; + } + } + return name; +} + +cmCPackIFWPackage* cmCPackIFWGenerator::GetGroupPackage( + cmCPackComponentGroup* group) const +{ + std::map<cmCPackComponentGroup*, cmCPackIFWPackage*>::const_iterator pit = + GroupPackages.find(group); + return pit != GroupPackages.end() ? pit->second : CM_NULLPTR; +} + +cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage( + cmCPackComponent* component) const +{ + std::map<cmCPackComponent*, cmCPackIFWPackage*>::const_iterator pit = + ComponentPackages.find(component); + return pit != ComponentPackages.end() ? pit->second : CM_NULLPTR; +} + +cmCPackIFWRepository* cmCPackIFWGenerator::GetRepository( + const std::string& repositoryName) +{ + RepositoriesMap::iterator rit = Repositories.find(repositoryName); + if (rit != Repositories.end()) { + return &(rit->second); + } + + cmCPackIFWRepository* repository = &Repositories[repositoryName]; + repository->Name = repositoryName; + repository->Generator = this; + if (repository->ConfigureFromOptions()) { + if (repository->Update == cmCPackIFWRepository::None) { + Installer.RemoteRepositories.push_back(repository); + } else { + Repository.RepositoryUpdate.push_back(repository); + } + } else { + Repositories.erase(repositoryName); + repository = CM_NULLPTR; + cmCPackLogger(cmCPackLog::LOG_WARNING, "Invalid repository \"" + << repositoryName << "\"" + << " configuration. Repository will be skipped." + << std::endl); + } + return repository; +} + +void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmXMLWriter& xout) +{ + std::ostringstream comment; + comment << "Generated by CPack " << CMake_VERSION << " IFW generator " + << "for QtIFW "; + if (IsVersionLess("2.0")) { + comment << "less 2.0"; + } else { + comment << FrameworkVersion; + } + comment << " tools at " << cmTimestamp().CurrentTime("", true); + xout.Comment(comment.str().c_str()); +} |