On 05/08/2014 03:14 AM, Konstantin Podsvirov wrote: > Qt is distributed with of his Qt Installer Framework (QtIFW).
For reference, here is a link: http://qt-project.org/wiki/Qt-Installer-Framework > I decided to make friends CMake and QtIFW. > > I added CPack IFW generator and module FindIFW.cmake. Thanks for working on this. > You can copy the code and test it: > > git clone git://podsvirov.pro/cmake/cpackifwgenerator.git For reference, I constructed a patch with the net change from your topic. I revised some whitespace too. See attachment. I'd appreciate comments from others on this mailing list that have worked on developing CPack generators. Also, I'm not familiar with IFW so I can only comment on this from the CMake/CPack side. The patch adds a FindIFW module and has CPack use it to find the packaging tools and add macro cpack_configure_ifw_component. In general find modules may not run reliably outside of a find_package() call in project CMake code (e.g. CMakeLists.txt) because no information about the host or target platform is available otherwise. Normally CPack generators have their own logic for finding the packaging tools. The location should not be needed outside of CPack. A separate module like CPackIFW could be used to provide the macro. We should not need a FindIFW module at all. -Brad
>From af34b92edb7712ffe5c4fff582e3f40dce67defc Mon Sep 17 00:00:00 2001 Message-Id: <af34b92edb7712ffe5c4fff582e3f40dce67defc.1399904456.git.brad.k...@kitware.com> From: Konstantin Podsvirov <konstan...@podsvirov.pro> Date: Thu, 8 May 2014 10:22:51 +0400 Subject: [PATCH] CPack: Add IFW generator --- Help/manual/cmake-modules.7.rst | 1 + Help/module/FindIFW.rst | 1 + Modules/CPackComponent.cmake | 3 + Modules/FindIFW.cmake | 165 +++++++++ Source/CMakeLists.txt | 1 + Source/CPack/cmCPackGeneratorFactory.cxx | 6 + Source/CPack/cmCPackIFWGenerator.cxx | 568 +++++++++++++++++++++++++++++++ Source/CPack/cmCPackIFWGenerator.h | 72 ++++ 8 files changed, 817 insertions(+) create mode 100644 Help/module/FindIFW.rst create mode 100644 Modules/FindIFW.cmake create mode 100644 Source/CPack/cmCPackIFWGenerator.cxx create mode 100644 Source/CPack/cmCPackIFWGenerator.h diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index 2bbe622..0d97233 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -114,6 +114,7 @@ All Modules /module/FindHSPELL /module/FindHTMLHelp /module/FindIcotool + /module/FindIFW /module/FindImageMagick /module/FindITK /module/FindJasper diff --git a/Help/module/FindIFW.rst b/Help/module/FindIFW.rst new file mode 100644 index 0000000..5188cd2 --- /dev/null +++ b/Help/module/FindIFW.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/FindIFW.cmake diff --git a/Modules/CPackComponent.cmake b/Modules/CPackComponent.cmake index 1433d9e..5524a3f 100644 --- a/Modules/CPackComponent.cmake +++ b/Modules/CPackComponent.cmake @@ -458,6 +458,9 @@ macro(cpack_add_component_group grpname) cpack_append_string_variable_set_command( CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_DESCRIPTION CPACK_ADDGRP_STR) + cpack_append_string_variable_set_command( + CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_PARENT_GROUP + CPACK_ADDGRP_STR) cpack_append_option_set_command( CPACK_COMPONENT_GROUP_${CPACK_ADDGRP_UNAME}_EXPANDED CPACK_ADDGRP_STR) diff --git a/Modules/FindIFW.cmake b/Modules/FindIFW.cmake new file mode 100644 index 0000000..edcede1 --- /dev/null +++ b/Modules/FindIFW.cmake @@ -0,0 +1,165 @@ +#.rst: +# FindIFW +# ------- +# +# This module looks for the location of the command line utilities supplied with +# the Qt Installer Framework (QtIFW_). +# +# .. _QtIFW: http://qt-project.org/doc/qtinstallerframework-1.5/index.html +# +# The module also defines several commands to control the behavior of the +# CPack IFW generator. +# +# Variables +# ^^^^^^^^^ +# +# The module defines the following variables: +# +# :: +# +# IFW_BINARYCREATOR_EXECUTABLE - path to binarycreator command line client +# IFW_REPOGEN_EXECUTABLE - path to repogen command line client +# IFW_FOUND - true if the binarycreator command line client was found +# +# Commands +# ^^^^^^^^^ +# +# The module defines the following commands: +# +# .. command:: cpack_configure_ifw_component +# +# Sets the arguments specific to the CPack IFW generator. +# +# :: +# +# cpack_configure_ifw_component(compname +# [VERSION version] +# [SCRIPT script]) +# +# This command should be called after cpack_add_component command. +# +# VERSION is version of component. +# +# SCRIPT is relative or absolute path to operations script +# for this component. +# +# Example usage +# ^^^^^^^^^^^^^ +# +# :: +# +# set(CPACK_PACKAGE_NAME "MyPackage") +# set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example") +# set(CPACK_PACKAGE_VERSION "1.0.0") +# +# include(CPack) +# find_package(IFW) +# +# cpack_add_component(myapp +# DISPLAY_NAME "MyApp" +# DESCRIPTION "My Application") +# if(IFW_FOUND) +# cpack_configure_ifw_component(myapp +# VERSION "1.2.3" +# SCRIPT "operations.qs") +# endif() +# + +#============================================================================= +# Copyright 2014 Kitware, Inc. +# Copyright 2014 Konstantin Podsvirov <konstan...@podsvirov.pro> +# +# 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. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# Default path + +if(WIN32) + set(_IFW_PATHS "C:/Qt") +else() + set(_IFW_PATHS "/opt/qt") +endif() + +set(_IFW_SUFFIXES + "QtIFW-1.5.0/bin" + "QtIFW-1.5.1/bin") + +# Look for 'binarycreator' + +find_program(IFW_BINARYCREATOR_EXECUTABLE + NAMES binarycreator + PATHS ${_IFW_PATHS} + PATH_SUFFIXES ${_IFW_SUFFIXES} + DOC "QtIFW binarycreator command line client" + ) +mark_as_advanced(IFW_BINARYCREATOR_EXECUTABLE) + +# Look for 'repogen' + +find_program(IFW_REPOGEN_EXECUTABLE + NAMES repogen + PATHS ${_IFW_PATHS} + PATH_SUFFIXES ${_IFW_SUFFIXES} + DOC "QtIFW repogen command line client" + ) + +# Handle the QUIETLY and REQUIRED arguments and set IFW_FOUND to TRUE if +# all listed variables are TRUE + +include(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake) +find_package_handle_standard_args(IFW + REQUIRED_VARS IFW_BINARYCREATOR_EXECUTABLE) + +# Macro definition based on CPackComponent + +if(NOT CPackComponent_CMake_INCLUDED) + include(CPackComponent) +endif() + +# Macro for configure component +macro(cpack_configure_ifw_component compname) + + set(_IFW_ARG_NAMES + "VERSION" + "SCRIPT" + ) + + string(TOUPPER ${compname} _CPACK_ADDCOMP_UNAME) + cpack_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_ADDCOMP_UNAME} + "${_IFW_ARG_NAMES}" + "" + ${ARGN} + ) + + # Resolve full filename for script file + set(_IFW_SCRIPT_MACRO CPACK_IFW_COMPONENT_${_CPACK_ADDCOMP_UNAME}_SCRIPT) + set(_IFW_SCRIPT_FILE ${${_IFW_SCRIPT_MACRO}}) + if(DEFINED ${_IFW_SCRIPT_MACRO}) + get_filename_component(${_IFW_SCRIPT_MACRO} ${_IFW_SCRIPT_FILE} ABSOLUTE) + set(_IFW_SCRIPT_FILE ${${_IFW_SCRIPT_MACRO}}) + if(NOT EXISTS ${_IFW_SCRIPT_FILE}) + message(WARNING "CPack IFW: script file \"${_IFW_SCRIPT_FILE}\" for component \"${compname}\" is not exists" ) + set(${_IFW_SCRIPT_MACRO}) + endif() + endif() + + set(_CPACK_ADDCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n") + + foreach(_IFW_ARG_NAME ${_IFW_ARG_NAMES}) + cpack_append_string_variable_set_command( + CPACK_IFW_COMPONENT_${_CPACK_ADDCOMP_UNAME}_${_IFW_ARG_NAME} + _CPACK_ADDCOMP_STR) + endforeach() + + if(CPack_CMake_INCLUDED) + file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_ADDCOMP_STR}") + endif() + +endmacro() diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 660c0c5..7b7be6a 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -570,6 +570,7 @@ set(CPACK_SRCS CPack/cmCPackGenerator.cxx CPack/cmCPackLog.cxx CPack/cmCPackNSISGenerator.cxx + CPack/cmCPackIFWGenerator.cxx CPack/cmCPackSTGZGenerator.cxx CPack/cmCPackTGZGenerator.cxx CPack/cmCPackTarBZip2Generator.cxx diff --git a/Source/CPack/cmCPackGeneratorFactory.cxx b/Source/CPack/cmCPackGeneratorFactory.cxx index 9faf2b0..788e785 100644 --- a/Source/CPack/cmCPackGeneratorFactory.cxx +++ b/Source/CPack/cmCPackGeneratorFactory.cxx @@ -19,6 +19,7 @@ #include "cmCPackZIPGenerator.h" #include "cmCPackSTGZGenerator.h" #include "cmCPackNSISGenerator.h" +#include "cmCPackIFWGenerator.h" #ifdef __APPLE__ # include "cmCPackDragNDropGenerator.h" @@ -68,6 +69,11 @@ cmCPackGeneratorFactory::cmCPackGeneratorFactory() this->RegisterGenerator("NSIS64", "Null Soft Installer (64-bit)", cmCPackNSISGenerator::CreateGenerator64); } + if (cmCPackIFWGenerator::CanGenerate()) + { + this->RegisterGenerator("IFW", "Qt Installer Framework", + cmCPackIFWGenerator::CreateGenerator); + } #ifdef __CYGWIN__ if (cmCPackCygwinBinaryGenerator::CanGenerate()) { diff --git a/Source/CPack/cmCPackIFWGenerator.cxx b/Source/CPack/cmCPackIFWGenerator.cxx new file mode 100644 index 0000000..c61f689 --- /dev/null +++ b/Source/CPack/cmCPackIFWGenerator.cxx @@ -0,0 +1,568 @@ +/*============================================================================ + 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 "cmGlobalGenerator.h" +#include "cmLocalGenerator.h" +#include "cmSystemTools.h" +#include "cmMakefile.h" +#include "cmGeneratedFileStream.h" +#include "cmCPackLog.h" +#include "cmCPackComponentGroup.h" + +#include <cmsys/SystemTools.hxx> +#include <cmsys/Glob.hxx> +#include <cmsys/Directory.hxx> +#include <cmsys/RegularExpression.hxx> + +/* NSIS uses different command line syntax on Windows and others */ +#ifdef _WIN32 +# define IFW_OPT "/" +#else +# define IFW_OPT "-" +#endif + +//---------------------------------------------------------------------- +cmCPackIFWGenerator::cmCPackIFWGenerator() +{ +} + +//---------------------------------------------------------------------- +cmCPackIFWGenerator::~cmCPackIFWGenerator() +{ +} + +//---------------------------------------------------------------------- +int cmCPackIFWGenerator::PackageFiles() +{ + // TODO: Fix nsis to force out file name +/* + std::string nsisInFileName = this->FindTemplate("NSIS.template.in"); + if ( nsisInFileName.size() == 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPack error: Could not find NSIS installer template file." + << std::endl); + return false; + } + std::string nsisInInstallOptions + = this->FindTemplate("NSIS.InstallOptions.ini.in"); + if ( nsisInInstallOptions.size() == 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPack error: Could not find NSIS installer options file." + << std::endl); + return false; + } +*/ + if (!ifwCreateConfigFile()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPack error: Could not create IFW \"config.xml\" file." + << std::endl); + return false; + } + + if (Components.empty() && !ifwCreatePackageFile()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "CPack error: Could not create IFW \"root/meta/package.xml\" file." + << std::endl); + return false; + } + + std::string ifwTLD = this->GetOption("CPACK_TOPLEVEL_DIRECTORY"); + std::string ifwTmpFile = ifwTLD; + ifwTmpFile += "/IFWOutput.log"; + + // Create group meta information + std::map<std::string, cmCPackComponentGroup>::iterator groupIt; + for(groupIt = this->ComponentGroups.begin(); + groupIt != this->ComponentGroups.end(); + ++groupIt + ) + { + std::string groupId = IfwGetGroupId(&groupIt->second); + std::string pkgXmlFileName = this->toplevel + "/packages/" + + groupId + + "/meta/package.xml"; + cmGeneratedFileStream pkgXml(pkgXmlFileName.data()); + pkgXml << "<?xml version=\"1.0\"?>" << std::endl; + pkgXml << "<Package>" << std::endl; + pkgXml << " <DisplayName>" << groupIt->second.DisplayName << "</DisplayName>" << std::endl; + pkgXml << " <Description>" << groupIt->second.Description << "</Description>" << std::endl; + pkgXml << " <Name>" << groupId << "</Name>" << std::endl; + pkgXml << " <Version>" << this->GetOption("CPACK_PACKAGE_VERSION") << "</Version>" << std::endl; + pkgXml << " <ReleaseDate>" << createCurrentDate() << "</ReleaseDate>" << std::endl; + pkgXml << "</Package>" << std::endl; + } + + std::string ifwDownloadedComponents; + + // Create the remaining components, which aren't associated with groups. + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt = this->Components.begin(); + compIt != this->Components.end(); + ++compIt) + { + if (!compIt->second.Group || true) + { + std::string pkgMetaDir = this->toplevel + "/" + + GetComponentInstallDirNamePrefix(compIt->second.Name) + + compIt->second.Name + "/meta"; + std::string pkgXmlFileName = pkgMetaDir + "/package.xml"; + cmGeneratedFileStream pkgXml(pkgXmlFileName.data()); + + // Check IFW version for component + std::string macroPrefix = "CPACK_IFW_COMPONENT_" + + cmsys::SystemTools::UpperCase(compIt->second.Name); + + pkgXml << "<?xml version=\"1.0\"?>" << std::endl; + pkgXml << "<Package>" << std::endl; + pkgXml << " <DisplayName>" << compIt->second.DisplayName << "</DisplayName>" << std::endl; + pkgXml << " <Description>" << compIt->second.Description << "</Description>" << std::endl; + pkgXml << " <Name>" << compIt->second.Name << "</Name>" << std::endl; + + // Version + const char* ifwPackageVersion = this->GetOption("CPACK_PACKAGE_VERSION"); + const char* ifwCompVersion = + this->GetOption(macroPrefix + "_VERSION"); + pkgXml << " <Version>" << (ifwCompVersion ? ifwCompVersion : ifwPackageVersion) << "</Version>" << std::endl; + + pkgXml << " <ReleaseDate>" << createCurrentDate() << "</ReleaseDate>" << std::endl; + + // Script + const char* ifwCompScript = + this->GetOption(macroPrefix + "_SCRIPT"); + if (ifwCompScript) + { + // Copy file + std::string ifwCompScriptFile = pkgMetaDir + "/operations.qs"; + cmsys::SystemTools::CopyFileIfDifferent(ifwCompScript, ifwCompScriptFile.data()); + pkgXml << " <Script>" << "operations.qs" << "</Script>" << std::endl; + } + + // Dependencies + if (!compIt->second.Dependencies.empty()) + { + pkgXml << " <Dependencies>"; + std::vector<cmCPackComponent *>::iterator depCompIt; + for(depCompIt = compIt->second.Dependencies.begin(); + depCompIt != compIt->second.Dependencies.end(); + ++depCompIt) + { + pkgXml << IfwGetComponentId(*depCompIt); + if (depCompIt + 1 != compIt->second.Dependencies.end()) + pkgXml << ","; + } + pkgXml << "</Dependencies>" << std::endl; + } + + // TODO: Check how enable virtual component (now it's allways disabled) + if (compIt->second.IsRequired) { + pkgXml << " <ForcedInstallation>true</ForcedInstallation>" << std::endl; + } else if (compIt->second.IsDisabledByDefault) { + pkgXml << " <Default>false</Default>" << std::endl; + } else if (compIt->second.IsHidden) { + pkgXml << " <Virtual>true</Virtual>" << std::endl; + } else { + pkgXml << " <Default>true</Default>" << std::endl; + } + + pkgXml << "</Package>" << std::endl; + } + if (compIt->second.IsDownloaded) + { + if (!ifwDownloadedComponents.empty()) ifwDownloadedComponents += ","; + ifwDownloadedComponents += compIt->second.Name; + } + } + + // Run repogen + if (!ifwDownloadSite.empty()) + { + std::string ifwCmd = ifwRepoGen; + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + ifwCmd += " -p " + this->toplevel + "/packages"; + if (!ifwOnlineOnly && !ifwDownloadedComponents.empty()) { + ifwCmd += " -i " + ifwDownloadedComponents; + } + ifwCmd += " " + this->toplevel + "/repository"; + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd + << std::endl); + std::string output; + int retVal = 1; + bool res = cmSystemTools::RunSingleCommand(ifwCmd.c_str(), &output, + &retVal, 0, 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; + } + } + + // Run binary creator + { + std::string ifwCmd = ifwBinCreator; + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + ifwCmd += " -p " + this->toplevel + "/packages"; + if (ifwOnlineOnly) { + ifwCmd += " --online-only"; + } else if (!ifwDownloadedComponents.empty() && !ifwDownloadSite.empty()) { + ifwCmd += " -e " + ifwDownloadedComponents; + } + // TODO: set correct name for multipackages + if (this->packageFileNames.size() > 0) { + ifwCmd += " " + packageFileNames[0]; + } else { + ifwCmd += " installer"; + } + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Execute: " << ifwCmd + << std::endl); + std::string output; + int retVal = 1; + bool res = cmSystemTools::RunSingleCommand(ifwCmd.c_str(), &output, + &retVal, 0, 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/root/data"; + } + + this->SetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX", tmpPref.c_str()); + + return this->GetOption("CPACK_IFW_PACKAGING_INSTALL_PREFIX"); +} + +//---------------------------------------------------------------------- +const char *cmCPackIFWGenerator::GetOutputExtension() +{ + const char *suffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX"); + return suffix ? suffix : ""; +} + +std::string cmCPackIFWGenerator::IfwGetGroupId(cmCPackComponentGroup *group) +{ + std::string ifwGroupId; + if (group) + { + ifwGroupId = group->Name; + group = group->ParentGroup; + } + while(group) { + ifwGroupId = group->Name + "." + ifwGroupId; + group = group->ParentGroup; + } + return ifwGroupId; +} + +std::string cmCPackIFWGenerator::IfwGetComponentId(cmCPackComponent *component) +{ + std::string ifwCompId; + if(component) { + std::string ifwGroupId = IfwGetGroupId(component->Group); + if(!ifwGroupId.empty()) ifwCompId += ifwGroupId + "."; + ifwCompId += component->Name; + } + return ifwCompId; +} + +//---------------------------------------------------------------------- +int cmCPackIFWGenerator::InitializeInternal() +{ + // Find IFW package + + if(!this->IsSet("IFW_FOUND")) + { + this->ReadListFile("FindIFW.cmake"); + } + + if(!this->IsSet("IFW_FOUND")) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find IFW package: likely it is not installed" + << std::endl); + return 0; + } + + // Look 'binarycreator' executable (needs) + + const char *ifwBinCratorStr = this->GetOption("IFW_BINARYCREATOR_EXECUTABLE"); + + ifwBinCreator = ifwBinCratorStr ? ifwBinCratorStr : ""; + + if (ifwBinCreator.empty()) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find IFW compiler \"binarycreator\": likely it is not installed, " + "or not in your PATH" + << std::endl); + return 0; + } + + // Look 'repogen' executable (optional) + + const char *ifwRepoGenStr = this->GetOption("IFW_REPOGEN_EXECUTABLE"); + + ifwRepoGen = ifwRepoGenStr ? ifwRepoGenStr : ""; + + // Remote repository + + if (const char *site = this->GetOption("CPACK_DOWNLOAD_SITE")) + ifwDownloadSite = site; + + ifwOnlineOnly = this->IsOn("CPACK_DOWNLOAD_ALL") ? true : false; + + if (!ifwDownloadSite.empty() && ifwRepoGen.empty()) { + cmCPackLogger(cmCPackLog::LOG_ERROR, + "Cannot find IFW repository generator \"repogen\": likely it is not installed, " + "or not in your PATH" + << std::endl); + return 0; + } + + return this->Superclass::InitializeInternal(); +} + +//---------------------------------------------------------------------- +std::string cmCPackIFWGenerator::GetComponentInstallDirNamePrefix(const std::string &componentName) +{ + std::string prefix = "packages/"; + + std::map<std::string, cmCPackComponent>::iterator compIt = this->Components.find(componentName); + + cmCPackComponent *comp = compIt != this->Components.end() ? &compIt->second : 0; + + std::string groupPrefix = comp ? this->IfwGetGroupId(comp->Group) : ""; + + if(!groupPrefix.empty()) groupPrefix += "."; + + return prefix + groupPrefix; +} + +//---------------------------------------------------------------------- +std::string cmCPackIFWGenerator::GetComponentInstallDirNameSuffix(const std::string &componentName) +{ + const std::string prefix = GetComponentInstallDirNamePrefix(componentName); + const std::string suffix = "/data"; + + if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { + return prefix + componentName + suffix; + } + + if (componentPackageMethod == ONE_PACKAGE) { + return std::string(prefix + "ALL_COMPONENTS_IN_ONE" + suffix); + } + // We have to find the name of the COMPONENT GROUP + // the current COMPONENT belongs to. +// std::string groupVar = "CPACK_COMPONENT_" + +// cmSystemTools::UpperCase(componentName) + "_GROUP"; +// if (NULL != GetOption(groupVar)) +// { +// return preffix + std::string(GetOption(groupVar)) + "." + componentName + suffix; +// } +// else +// { +// return preffix + componentName + suffix; +// } + return prefix + componentName + suffix; +} + +//---------------------------------------------------------------------- +bool cmCPackIFWGenerator::GetListOfSubdirectories(const char* topdir, + std::vector<std::string>& dirs) +{ + cmsys::Directory dir; + dir.Load(topdir); + size_t fileNum; + for (fileNum = 0; fileNum < dir.GetNumberOfFiles(); ++fileNum) + { + if (strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),".") && + strcmp(dir.GetFile(static_cast<unsigned long>(fileNum)),"..")) + { + cmsys_stl::string fullPath = topdir; + fullPath += "/"; + fullPath += dir.GetFile(static_cast<unsigned long>(fileNum)); + if(cmsys::SystemTools::FileIsDirectory(fullPath.c_str()) && + !cmsys::SystemTools::FileIsSymlink(fullPath.c_str())) + { + if (!this->GetListOfSubdirectories(fullPath.c_str(), dirs)) + { + return false; + } + } + } + } + dirs.push_back(topdir); + return true; +} + +//---------------------------------------------------------------------- +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; +} + +int cmCPackIFWGenerator::ifwCreateConfigFile() +{ + cmGeneratedFileStream cfg((this->toplevel + "/config/config.xml").data()); + + std::string ifwPkgName; + if (const char *name = this->GetOption("CPACK_PACKAGE_NAME")) { + ifwPkgName = name; + } else { + ifwPkgName = "Your package"; + } + + std::string ifwPkgDescription; + if (const char *name = this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { + ifwPkgDescription = name; + } else { + ifwPkgDescription = "Your package description"; + } + + std::string ifwPkgVersion; + if (const char *version = this->GetOption("CPACK_PACKAGE_VERSION")) { + ifwPkgVersion = version; + } else { + ifwPkgVersion = "1.0.0"; + } + + std::string ifwPkgInstDir; + if (const char *dir = this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY")) { + ifwPkgInstDir = dir; + } else { + ifwPkgVersion = "InstallationDirectory"; + } + + cfg << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + cfg << "<Installer>" << std::endl; + cfg << " <Name>" << ifwPkgName << "</Name>" << std::endl; + cfg << " <Version>" << ifwPkgVersion << "</Version>" << std::endl; + cfg << " <Title>" << ifwPkgDescription << "</Title>" << std::endl; + cfg << " <TargetDir>@RootDir@" << ifwPkgInstDir << "</TargetDir>" << std::endl; + + if (!ifwDownloadSite.empty()) + { + cfg << " <RemoteRepositories>" << std::endl; + cfg << " <Repository>" << std::endl; + cfg << " <Url>" << ifwDownloadSite << "</Url>" << std::endl; +// <Enabled>1</Enabled> +// <Username>user</Username> +// <Password>password</Password> +// <DisplayName>Example repository</DisplayName> + cfg << " </Repository>" << std::endl; + cfg << " </RemoteRepositories>" << std::endl; + } + + cfg << "</Installer>" << std::endl; + + return 1; +} + +int cmCPackIFWGenerator::ifwCreatePackageFile() +{ + std::string ifwPkgName; + if (const char *name = this->GetOption("CPACK_PACKAGE_NAME")) { + ifwPkgName = name; + } else { + ifwPkgName = "Your package"; + } + + std::string ifwPkgDescription; + if (const char *name = this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) { + ifwPkgDescription = name; + } else { + ifwPkgDescription = "Your package description"; + } + + cmGeneratedFileStream pkgXml((this->toplevel + "/packages/root/meta/package.xml").data()); + pkgXml << "<?xml version=\"1.0\"?>" << std::endl; + pkgXml << "<Package>" << std::endl; + pkgXml << " <DisplayName>" << ifwPkgName << "</DisplayName>" << std::endl; + pkgXml << " <Description>" << ifwPkgDescription << "</Description>" << std::endl; + pkgXml << " <Name>" << "root" << "</Name>" << std::endl; +// pkgXml << " <Version>" << this->GetOption("CPACK_PACKAGE_VERSION") << "</Version>" << std::endl; + pkgXml << " <Version>" << "1.0.0" << "</Version>" << std::endl; + pkgXml << " <ReleaseDate>" << createCurrentDate() << "</ReleaseDate>" << std::endl; + + // TODO: Check how enable virtual component (now it's allways disabled) +// if (compIt->second.IsRequired) { + pkgXml << " <ForcedInstallation>true</ForcedInstallation>" << std::endl; +// } else if (compIt->second.IsDisabledByDefault) { +// pkgXml << " <Default>false</Default>" << std::endl; +// } else if (compIt->second.IsHidden) { +// pkgXml << " <Virtual>true</Virtual>" << std::endl; +// } else { + pkgXml << " <Default>true</Default>" << std::endl; +// } + + pkgXml << "</Package>" << std::endl; + + return 1; +} + +std::string cmCPackIFWGenerator::createCurrentDate() +{ + time_t rawtime; + struct tm * timeinfo; + char buffer[80]; + + time (&rawtime); + timeinfo = localtime(&rawtime); + + //strftime(buffer,80,"%d-%m-%Y %I:%M:%S",timeinfo); + strftime(buffer,80,"%Y-%m-%d",timeinfo); + + return buffer; +} diff --git a/Source/CPack/cmCPackIFWGenerator.h b/Source/CPack/cmCPackIFWGenerator.h new file mode 100644 index 0000000..3f70ae6 --- /dev/null +++ b/Source/CPack/cmCPackIFWGenerator.h @@ -0,0 +1,72 @@ +/*============================================================================ + CMake - Cross Platform Makefile Generator + Copyright 2000-2009 Kitware, Inc. + + 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. +============================================================================*/ + +#ifndef cmCPackIFWGenerator_h +#define cmCPackIFWGenerator_h + + +#include "cmCPackGenerator.h" +#include <set> + +/** \class cmCPackNSISGenerator + * \brief A generator for NSIS files + * + * http://people.freebsd.org/~kientzle/libarchive/ + */ +class cmCPackIFWGenerator : public cmCPackGenerator +{ +public: + cmCPackTypeMacro(cmCPackIFWGenerator, cmCPackGenerator); + + /** + * Construct generator + */ + cmCPackIFWGenerator(); + virtual ~cmCPackIFWGenerator(); + +protected: + virtual int InitializeInternal(); + virtual int PackageFiles(); + virtual const char* GetPackagingInstallPrefix(); + + virtual const char* GetOutputExtension(); + + std::string IfwGetGroupId(cmCPackComponentGroup *group); + std::string IfwGetComponentId(cmCPackComponent *component); + + virtual std::string GetComponentInstallDirNamePrefix( + const std::string& componentName); + + virtual std::string GetComponentInstallDirNameSuffix( + const std::string& componentName); + + bool GetListOfSubdirectories(const char* dir, + std::vector<std::string>& dirs); + + enum cmCPackGenerator::CPackSetDestdirSupport SupportsSetDestdir() const; + virtual bool SupportsAbsoluteDestination() const; + virtual bool SupportsComponentInstallation() const; + +private: + int ifwCreateConfigFile(); + int ifwCreatePackageFile(); + std::string createCurrentDate(); + + std::string ifwRepoGen; + std::string ifwBinCreator; + + std::string ifwDownloadSite; + + bool ifwOnlineOnly; +}; + +#endif -- 1.9.2
-- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/cgi-bin/mailman/listinfo/cmake-developers