diff options
author | Konstantin Podsvirov <konstantin@podsvirov.pro> | 2014-07-23 07:01:59 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2014-07-28 14:24:03 (GMT) |
commit | 44850a267d1c2ee64947ebb93de3998549b59d03 (patch) | |
tree | 7e52d6426e9e5ceb152b2b951521098d0b89a6a8 | |
parent | 3e3ab2adb4a70352a41b469788a2885b20a86fef (diff) | |
download | CMake-44850a267d1c2ee64947ebb93de3998549b59d03.zip CMake-44850a267d1c2ee64947ebb93de3998549b59d03.tar.gz CMake-44850a267d1c2ee64947ebb93de3998549b59d03.tar.bz2 |
CPack: Add an "IFW" generator for Qt Framework Installer
Add support for packaging with the Qt Framework Installer tools:
http://qt-project.org/doc/qtinstallerframework/index.html
Reviewed-by: Nils Gladitz <nilsgladitz@gmail.com>
-rw-r--r-- | CMakeCPack.cmake | 32 | ||||
-rw-r--r-- | CMakeCPackOptions.cmake.in | 14 | ||||
-rw-r--r-- | Help/manual/cmake-modules.7.rst | 1 | ||||
-rw-r--r-- | Help/module/CPackIFW.rst | 1 | ||||
-rw-r--r-- | Modules/CPack.cmake | 2 | ||||
-rw-r--r-- | Modules/CPackComponent.cmake | 3 | ||||
-rw-r--r-- | Modules/CPackIFW.cmake | 384 | ||||
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/CPack/cmCPackGeneratorFactory.cxx | 6 | ||||
-rw-r--r-- | Source/CPack/cmCPackIFWGenerator.cxx | 856 | ||||
-rw-r--r-- | Source/CPack/cmCPackIFWGenerator.h | 82 | ||||
-rw-r--r-- | Source/QtIFW/cmake.org.html | 7 | ||||
-rw-r--r-- | Source/QtIFW/installscript.qs.in | 24 |
13 files changed, 1413 insertions, 0 deletions
diff --git a/CMakeCPack.cmake b/CMakeCPack.cmake index fb55bfc..5b096ad 100644 --- a/CMakeCPack.cmake +++ b/CMakeCPack.cmake @@ -59,11 +59,43 @@ if(EXISTS "${CMAKE_ROOT}/Modules/CPack.cmake") if(${CPACK_SYSTEM_NAME} MATCHES Windows) if(CMAKE_CL_64) set(CPACK_SYSTEM_NAME win64-x64) + set(CPACK_IFW_TARGET_DIRECTORY "@RootDir@/Program Files/${CMAKE_PROJECT_NAME}") else() set(CPACK_SYSTEM_NAME win32-x86) endif() endif() + # default component for IFW + if(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME) + set(_CPACK_IFW_COMPONENT_NAME ${CMAKE_INSTALL_DEFAULT_COMPONENT_NAME}) + else() + set(_CPACK_IFW_COMPONENT_NAME Unspecified) + endif() + string(TOUPPER ${_CPACK_IFW_COMPONENT_NAME} _CPACK_IFW_COMPONENT_UNAME) + + if(${CMAKE_SYSTEM_NAME} MATCHES Windows) + if(BUILD_QtDialog) + set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/bin/cmake-gui.exe\", \"@StartMenuDir@/CMake (cmake-gui).lnk\");\n") + endif() + if(SPHINX_HTML) + set(_CPACK_IFW_SHORTCUT_OPTIONAL "${_CPACK_IFW_SHORTCUT_OPTIONAL}component.addOperation(\"CreateShortcut\", \"@TargetDir@/doc/cmake-${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}/html/index.html\", \"@StartMenuDir@/CMake Documentation.lnk\");\n") + endif() + configure_file("${CMake_SOURCE_DIR}/Source/QtIFW/installscript.qs.in" + "${CMake_BINARY_DIR}/installscript.qs" @ONLY + ) + install(FILES "${CMake_SOURCE_DIR}/Source/QtIFW/cmake.org.html" + DESTINATION "." + ) + set(_CPACK_IFW_COMPONENT_SCRIPT "set(CPACK_IFW_COMPONENT_${_CPACK_IFW_COMPONENT_UNAME}_SCRIPT \"${CMake_BINARY_DIR}/installscript.qs\")") + endif() + + if(${CMAKE_SYSTEM_NAME} MATCHES Linux) + set(CPACK_IFW_TARGET_DIRECTORY "@HomeDir@/${CMAKE_PROJECT_NAME}") + set(CPACK_IFW_ADMIN_TARGET_DIRECTORY "@ApplicationsDir@/${CMAKE_PROJECT_NAME}") + endif() + + set(_CPACK_IFW_PACKAGE_VERSION ${CMake_VERSION_MAJOR}.${CMake_VERSION_MINOR}.${CMake_VERSION_PATCH}) + if(NOT DEFINED CPACK_PACKAGE_FILE_NAME) # if the CPACK_PACKAGE_FILE_NAME is not defined by the cache # default to source package - system, on cygwin system is not diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index aba404f..135c07d 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -31,6 +31,20 @@ endif() # they might not if qt was not enabled for the build include("@QT_DIALOG_CPACK_OPTIONS_FILE@" OPTIONAL) +if(CPACK_GENERATOR MATCHES "IFW") + # Version with QtIFW limitations + set(CPACK_PACKAGE_VERSION "@_CPACK_IFW_PACKAGE_VERSION@") + # Enable install default component + set(CPACK_COMPONENTS_ALL "@_CPACK_IFW_COMPONENT_NAME@") + # Configuration + set(CPACK_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_DISPLAY_NAME "@CPACK_PACKAGE_NAME@") + set(CPACK_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_DESCRIPTION "@CPACK_PACKAGE_DESCRIPTION_SUMMARY@") + # IFW Configuration + set(CPACK_IFW_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_NAME "@CPACK_PACKAGE_NAME@") + set(CPACK_IFW_COMPONENT_@_CPACK_IFW_COMPONENT_UNAME@_LICENSES "@CPACK_PACKAGE_NAME@ Copyright" "@CPACK_RESOURCE_FILE_LICENSE@") + @_CPACK_IFW_COMPONENT_SCRIPT@ +endif() + if(CPACK_GENERATOR MATCHES "CygwinSource") # when packaging source make sure the .build directory is not included set(CPACK_SOURCE_IGNORE_FILES diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst index ecc9cc4..91fffe9 100644 --- a/Help/manual/cmake-modules.7.rst +++ b/Help/manual/cmake-modules.7.rst @@ -55,6 +55,7 @@ All Modules /module/CPackCygwin /module/CPackDeb /module/CPackDMG + /module/CPackIFW /module/CPackNSIS /module/CPackPackageMaker /module/CPackRPM diff --git a/Help/module/CPackIFW.rst b/Help/module/CPackIFW.rst new file mode 100644 index 0000000..ea05796 --- /dev/null +++ b/Help/module/CPackIFW.rst @@ -0,0 +1 @@ +.. cmake-module:: ../../Modules/CPackIFW.cmake diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 89547af..b58f944 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -435,6 +435,7 @@ if(NOT CPACK_GENERATOR) option(CPACK_BINARY_WIX "Enable to build WiX packages" OFF) option(CPACK_BINARY_ZIP "Enable to build ZIP packages" OFF) endif() + option(CPACK_BINARY_IFW "Enable to build IFW packages" OFF) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_BUNDLE Bundle) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_DRAGNDROP DragNDrop) @@ -450,6 +451,7 @@ if(NOT CPACK_GENERATOR) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_TZ TZ) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_WIX WIX) cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_ZIP ZIP) + cpack_optional_append(CPACK_GENERATOR CPACK_BINARY_IFW IFW) endif() 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/CPackIFW.cmake b/Modules/CPackIFW.cmake new file mode 100644 index 0000000..f99488a --- /dev/null +++ b/Modules/CPackIFW.cmake @@ -0,0 +1,384 @@ +#.rst: +# CPackIFW +# -------- +# +# .. _QtIFW: http://qt-project.org/doc/qtinstallerframework/index.html +# +# This module looks for the location of the command line utilities supplied with +# the Qt Installer Framework (QtIFW_). +# +# The module also defines several commands to control the behavior of the +# CPack ``IFW`` generator. +# +# +# Overview +# ^^^^^^^^ +# +# CPack ``IFW`` generator helps you create online and offline +# binary cross-platform installers with a graphical user interface. +# +# CPack IFW generator prepare project installation and generate configuration +# and meta information for QtIFW_ tools. +# +# The QtIFW_ provides a set of tools and utilities to create +# installers for the supported desktop Qt platforms: Linux, Microsoft Windows, +# and Mac OS X. +# +# To use CPack ``IFW`` generator you must also install QtIFW_. +# +# Variables +# ^^^^^^^^^ +# +# Variables that Change Behavior +# """""""""""""""""""""""""""""" +# +# .. variable:: CPACK_IFW_TARGET_DIRECTORY +# +# Default target directory for installation. +# By default used "@ApplicationsDir@/:variable:`CPACK_PACKAGE_INSTALL_DIRECTORY`" +# +# You can use predefined variables. +# +# .. variable:: CPACK_IFW_ADMIN_TARGET_DIRECTORY +# +# Default target directory for installation with administrator rights. +# +# You can use predefined variables. +# +# .. variable:: CPACK_IFW_RESOLVE_DUPLICATE_NAMES +# +# Resolve duplicate names when installing components with groups. +# +# .. variable:: CPACK_IFW_PACKAGES_DIRECTORIES +# +# Additional prepared packages dirs that will be used to resolve +# dependent components. +# +# Advanced Variables +# """""""""""""""""" +# +# .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE +# +# The path to "binarycreator" command line client. +# +# This variable is cached and can be configured user if need. +# +# .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND +# +# True if the "binarycreator" command line client was found. +# +# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE +# +# The path to "repogen" command line client. +# +# This variable is cached and can be configured user if need. +# +# .. variable:: CPACK_IFW_REPOGEN_EXECUTABLE_FOUND +# +# True if the "repogen" command line client was found. +# +# Commands +# ^^^^^^^^^ +# +# The module defines the following commands: +# +# -------------------------------------------------------------------------- +# +# .. command:: cpack_ifw_configure_component +# +# Sets the arguments specific to the CPack IFW generator. +# +# :: +# +# cpack_ifw_configure_component(<compname> +# [VERSION <version>] +# [SCRIPT <script>] +# [NAME <name>] +# [PRIORITY <priority>] +# [LICENSES <display_name> <file_path> ...]) +# +# This command should be called after cpack_add_component command. +# +# ``VERSION`` is version of component. By default used :variable:`CPACK_PACKAGE_VERSION`. +# +# ``SCRIPT`` is relative or absolute path to operations script +# for this component. +# +# ``NAME`` is used to create domain-like identification for this component. +# By default used origin component name. +# +# ``PRIORITY`` is priority of the component in the tree. +# +# ``LICENSES`` pair of <display_name> and <file_path> of license text for this +# component. You can specify more then one license. +# +# -------------------------------------------------------------------------- +# +# .. command:: cpack_ifw_configure_component_group +# +# Sets the arguments specific to the CPack IFW generator. +# +# :: +# +# cpack_ifw_configure_component_group(<grpname> +# [VERSION <version>] +# [NAME <name>] +# [PRIORITY <priority>] +# [LICENSES <display_name> <file_path> ...]) +# +# This command should be called after cpack_add_component_group command. +# +# ``VERSION`` is version of component group. By default used :variable:`CPACK_PACKAGE_VERSION`. +# +# ``NAME`` is used to create domain-like identification for this component group. +# By default used origin component group name. +# +# ``PRIORITY`` is priority of the component group in the tree. +# +# ``LICENSES`` pair of <display_name> and <file_path> of license text for this +# component group. You can specify more then one license. +# +# Example usage +# ^^^^^^^^^^^^^ +# +# .. code-block:: cmake +# +# set(CPACK_PACKAGE_NAME "MyPackage") +# set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "MyPackage Installation Example") +# set(CPACK_PACKAGE_VERSION "1.0.0") +# +# include(CPack) +# include(CPackIFW) +# +# cpack_add_component(myapp +# DISPLAY_NAME "MyApp" +# DESCRIPTION "My Application") +# cpack_ifw_configure_component(myapp +# VERSION "1.2.3" +# SCRIPT "operations.qs") +# +# +# Online installer +# ^^^^^^^^^^^^^^^^ +# +# By defaul CPack IFW generator make offline installer. This means that all +# components will be packaged into a binary file. +# +# To make a component downloaded, you must set the ``DOWNLOADED`` option in +# :command:`cpack_add_component`. +# +# Then you would use the command :command:`cpack_configure_downloads`. +# If you set ``ALL`` option all components will be downloaded. +# +# CPack IFW generator create "repository" dir in current binary dir. You +# would copy content of this dir to specified ``site``. +# +# See Also +# ^^^^^^^^ +# +# Qt Installer Framework Manual: +# +# Index page +# http://qt-project.org/doc/qtinstallerframework/index.html +# +# Component Scripting +# http://qt-project.org/doc/qtinstallerframework/scripting.html +# +# Predefined Variables +# http://qt-project.org/doc/qtinstallerframework/scripting.html#predefined-variables +# +# Download Qt Installer Framework for you platform from Qt Project site: +# http://download.qt-project.org/official_releases/qt-installer-framework/ +# + +#============================================================================= +# Copyright 2014 Kitware, Inc. +# Copyright 2014 Konstantin Podsvirov <konstantin@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.) + +#============================================================================= +# Search Qt Installer Framework tools +#============================================================================= + +# Default path + +if(WIN32) + set(_CPACK_IFW_PATHS + "$ENV{HOMEDRIVE}/Qt" + "C:/Qt" + ) +else() + set(_CPACK_IFW_PATHS + "$ENV{HOME}/Qt" + "/opt/Qt" + ) +endif() + +set(_CPACK_IFW_SUFFIXES + "QtIFW-1.7.0/bin" + "QtIFW-1.6.0/bin" + "QtIFW-1.5.0/bin" + "QtIFW-1.4.0/bin" + "QtIFW-1.3.0/bin" +) + +# Look for 'binarycreator' + +if(NOT CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND) + +find_program(CPACK_IFW_BINARYCREATOR_EXECUTABLE + NAMES binarycreator + PATHS ${_CPACK_IFW_PATHS} + PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES} + DOC "QtIFW binarycreator command line client" + ) +mark_as_advanced(CPACK_IFW_BINARYCREATOR_EXECUTABLE) + +if(EXISTS ${CPACK_IFW_BINARYCREATOR_EXECUTABLE}) + set(CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND 1) +endif() + +endif() # NOT CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND + +# Look for 'repogen' + +if(NOT CPACK_IFW_REPOGEN_EXECUTABLE_FOUND) + +find_program(CPACK_IFW_REPOGEN_EXECUTABLE + NAMES repogen + PATHS ${_CPACK_IFW_PATHS} + PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES} + DOC "QtIFW repogen command line client" + ) +mark_as_advanced(CPACK_IFW_REPOGEN_EXECUTABLE) + +if(EXISTS ${CPACK_IFW_REPOGEN_EXECUTABLE}) + set(CPACK_IFW_REPOGEN_EXECUTABLE_FOUND 1) +endif() + +endif() # NOT CPACK_IFW_REPOGEN_EXECUTABLE_FOUND + +# +## Next code is included only once +# + +if(NOT CPackIFW_CMake_INCLUDED) +set(CPackIFW_CMake_INCLUDED 1) + +#============================================================================= +# Macro definition +#============================================================================= + +# Macro definition based on CPackComponent + +if(NOT CPackComponent_CMake_INCLUDED) + include(CPackComponent) +endif() + +if(NOT __CMAKE_PARSE_ARGUMENTS_INCLUDED) + include(CMakeParseArguments) +endif() + +# Resolve full path to lisense file +macro(_cpack_ifw_resolve_lisenses _variable) + if(${_variable}) + set(_ifw_license_file FALSE) + set(_ifw_licenses_fix) + foreach(_ifw_licenses_arg ${${_variable}}) + if(_ifw_license_file) + get_filename_component(_ifw_licenses_arg "${_ifw_licenses_arg}" ABSOLUTE) + set(_ifw_license_file FALSE) + else() + set(_ifw_license_file TRUE) + endif() + list(APPEND _ifw_licenses_fix "${_ifw_licenses_arg}") + endforeach(_ifw_licenses_arg) + set(${_variable} "${_ifw_licenses_fix}") + endif() +endmacro() + +# Macro for configure component +macro(cpack_ifw_configure_component compname) + + string(TOUPPER ${compname} _CPACK_IFWCOMP_UNAME) + + set(_IFW_OPT) + set(_IFW_ARGS VERSION SCRIPT NAME PRIORITY) + set(_IFW_MULTI_ARGS DEPENDS LICENSES) + cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN}) + + # Resolve full filename for script file + set(_IFW_SCRIPT_MACRO CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_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() + + _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES) + + set(_CPACK_IFWCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n") + + foreach(_IFW_ARG_NAME ${_IFW_ARGS}) + cpack_append_string_variable_set_command( + CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME} + _CPACK_IFWCOMP_STR) + endforeach() + + foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS}) + cpack_append_variable_set_command( + CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME} + _CPACK_IFWCOMP_STR) + endforeach() + + if(CPack_CMake_INCLUDED) + file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWCOMP_STR}") + endif() + +endmacro() + +# Macro for configure group +macro(cpack_ifw_configure_component_group grpname) + + string(TOUPPER ${grpname} _CPACK_IFWGRP_UNAME) + + set(_IFW_OPT) + set(_IFW_ARGS VERSION NAME PRIORITY) + set(_IFW_MULTI_ARGS LICENSES) + cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN}) + + _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES) + + set(_CPACK_IFWGRP_STR "\n# Configuration for IFW component group \"${grpname}\"\n") + + foreach(_IFW_ARG_NAME ${_IFW_ARGS}) + cpack_append_string_variable_set_command( + CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME} + _CPACK_IFWGRP_STR) + endforeach() + + foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS}) + cpack_append_variable_set_command( + CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME} + _CPACK_IFWGRP_STR) + endforeach() + + if(CPack_CMake_INCLUDED) + file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWGRP_STR}") + endif() +endmacro() + +endif() # NOT CPackIFW_CMake_INCLUDED diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 3838cb0..c394946 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -577,6 +577,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..a4f33b4 --- /dev/null +++ b/Source/CPack/cmCPackIFWGenerator.cxx @@ -0,0 +1,856 @@ +/*============================================================================ + 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> +#include <cmXMLSafe.h> + +//---------------------------------------------------------------------- +cmCPackIFWGenerator::cmCPackIFWGenerator() +{ +} + +//---------------------------------------------------------------------- +cmCPackIFWGenerator::~cmCPackIFWGenerator() +{ +} + +//---------------------------------------------------------------------- +int cmCPackIFWGenerator::PackageFiles() +{ + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Configuration" << std::endl); + + 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"; + + std::set<std::string> ifwDependsComponents; + std::string ifwBinaryComponents; + std::string ifwDownloadedComponents; + + // Create groups meta information + std::map<std::string, cmCPackComponentGroup>::iterator groupIt; + for(groupIt = this->ComponentGroups.begin(); + groupIt != this->ComponentGroups.end(); + ++groupIt + ) + { + std::string macroPrefix = "CPACK_IFW_COMPONENT_GROUP_" + + cmsys::SystemTools::UpperCase(groupIt->second.Name); + + std::string groupId = IfwGetGroupId(&groupIt->second); + + if(!ifwBinaryComponents.empty()) ifwBinaryComponents += ","; + ifwBinaryComponents += groupId; + + std::string pkgMetaDir = this->toplevel + "/packages/" + + groupId + + "/meta"; + + std::string pkgXmlFileName = pkgMetaDir + + "/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; + + // Version + const char* ifwPackageVersion = this->GetOption("CPACK_PACKAGE_VERSION"); + const char* ifwGroupVersion = this->GetOption(macroPrefix + "_VERSION"); + pkgXml << " <Version>" + << (ifwGroupVersion ? ifwGroupVersion : ifwPackageVersion) + << "</Version>" << std::endl; + pkgXml << " <ReleaseDate>" << IfwCreateCurrentDate() + << "</ReleaseDate>" << std::endl; + + // Licenses + std::vector<std::string> licenses; + if(IfwParseLicenses(licenses, macroPrefix + "_LICENSES", pkgMetaDir)) + { + pkgXml << " <Licenses>" << std::endl; + for(size_t i = 0; i < licenses.size(); i += 2) + { + pkgXml << " <License " + << "name=\"" << licenses[i] << "\" " + << "file=\"" << licenses[i + 1] << "\" " + << "/>" <<std::endl; + } + pkgXml << " </Licenses>" << std::endl; + } + + // Priority + if(const char* ifwGroupPriority = + this->GetOption(macroPrefix + "_PRIORITY")) + { + pkgXml << " <SortingPriority>" << ifwGroupPriority + << "</SortingPriority>" << std::endl; + } + pkgXml << "</Package>" << std::endl; + } + + // Create components meta information + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt = this->Components.begin(); + compIt != this->Components.end(); + ++compIt) + { + // Component id + std::string ifwCompId = IfwGetComponentId(&compIt->second); + + std::string pkgMetaDir = this->toplevel + "/" + + GetComponentInstallDirNamePrefix(compIt->second.Name) + + ifwCompId + "/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>" << ifwCompId << "</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>" << IfwCreateCurrentDate() + << "</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; + } + + // Check dependencies + std::set<std::string> compDepSet; + // CMake dependencies + if (!compIt->second.Dependencies.empty()) + { + std::vector<cmCPackComponent *>::iterator depCompIt; + for(depCompIt = compIt->second.Dependencies.begin(); + depCompIt != compIt->second.Dependencies.end(); + ++depCompIt) + { + compDepSet.insert(IfwGetComponentId(*depCompIt)); + } + } + // QtIFW dependencies + if(const char *ifwCompDepsStr = this->GetOption(macroPrefix + "_DEPENDS")) + { + std::vector<std::string> ifwCompDepsVector; + cmSystemTools::ExpandListArgument(ifwCompDepsStr, + ifwCompDepsVector); + for(std::vector<std::string>::iterator + depCompIt = ifwCompDepsVector.begin(); + depCompIt != ifwCompDepsVector.end(); ++depCompIt) + { + compDepSet.insert(*depCompIt); + ifwDependsComponents.insert(*depCompIt); + } + } + + // Write dependencies + if (!compDepSet.empty()) + { + pkgXml << " <Dependencies>"; + std::set<std::string>::iterator it = compDepSet.begin(); + pkgXml << *it; + ++it; + while(it != compDepSet.end()) + { + pkgXml << "," << *it; + ++it; + } + pkgXml << "</Dependencies>" << std::endl; + } + + // Licenses + std::vector<std::string> licenses; + if(IfwParseLicenses(licenses, macroPrefix + "_LICENSES", pkgMetaDir)) + { + pkgXml << " <Licenses>" << std::endl; + for(size_t i = 0; i < licenses.size(); i += 2) + { + pkgXml << " <License " + << "name=\"" << licenses[i] << "\" " + << "file=\"" << licenses[i + 1] << "\" " + << "/>" <<std::endl; + } + pkgXml << " </Licenses>" << 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; + } + + // Priority + if(const char* ifwCompPriority = + this->GetOption(macroPrefix + "_PRIORITY")) + { + pkgXml << " <SortingPriority>" << ifwCompPriority + << "</SortingPriority>" << std::endl; + } + + pkgXml << "</Package>" << std::endl; + + // Downloaded + if (compIt->second.IsDownloaded) + { + if (!ifwDownloadedComponents.empty()) ifwDownloadedComponents += ","; + ifwDownloadedComponents += ifwCompId; + } + else + { + if (!ifwBinaryComponents.empty()) ifwBinaryComponents += ","; + ifwBinaryComponents += ifwCompId; + } + } + + // Run repogen + if (!ifwDownloadSite.empty()) + { + std::string ifwCmd = ifwRepoGen; + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + ifwCmd += " -p " + this->toplevel + "/packages"; + + if(!ifwPkgsDirsVector.empty()) + { + for(std::vector<std::string>::iterator it = ifwPkgsDirsVector.begin(); + it != ifwPkgsDirsVector.end(); ++it) + { + ifwCmd += " -p " + *it; + } + } + + 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; + cmCPackLogger(cmCPackLog::LOG_OUTPUT, + "- Generate repository" << std::endl); + 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(!ifwPkgsDirsVector.empty()) + { + for(std::vector<std::string>::iterator it = ifwPkgsDirsVector.begin(); + it != ifwPkgsDirsVector.end(); ++it) + { + ifwCmd += " -p " + *it; + } + } + + if (ifwOnlineOnly) + { + ifwCmd += " --online-only"; + } + else if (!ifwDownloadedComponents.empty() && !ifwDownloadSite.empty()) + { + ifwCmd += " -e " + ifwDownloadedComponents; + } + else if (!ifwDependsComponents.empty()) + { + ifwCmd += " -i "; + std::set<std::string>::iterator it = ifwDependsComponents.begin(); + ifwCmd += *it; + ++it; + while(it != ifwDependsComponents.end()) + { + ifwCmd += "," + (*it); + ++it; + } + + ifwCmd += "," + ifwBinaryComponents; + } + // 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; + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "- Generate package" << std::endl); + 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; + std::string ifwGroupName; + std::list<cmCPackComponentGroup*> groups; + while(group) + { + groups.push_front(group); + group = group->ParentGroup; + } + std::list<cmCPackComponentGroup*>::iterator it = groups.begin(); + if(it != groups.end()) + { + ifwGroupId = IfwGetGroupName(*it); + ++it; + } + while(it != groups.end()) + { + ifwGroupName = IfwGetGroupName(*it); + + if(ifwResolveDuplicateNames) + { + if(ifwGroupName.substr(0, ifwGroupId.size()) == ifwGroupId) + { + ifwGroupId = ifwGroupName; + ++it; + continue; + } + } + + ifwGroupId += "." + ifwGroupName; + + ++it; + } + + return ifwGroupId; +} + +//---------------------------------------------------------------------- +std::string cmCPackIFWGenerator::IfwGetComponentId(cmCPackComponent *component) +{ + std::string ifwCompId; + if(component) { + ifwCompId = IfwGetGroupId(component->Group); + if(!ifwCompId.empty()) ifwCompId += "."; + std::string ifwCompName = IfwGetComponentName(component); + if(ifwResolveDuplicateNames && + (ifwCompName.substr(0, ifwCompId.size()) == ifwCompId)) + { + ifwCompId = ifwCompName; + } + else + { + ifwCompId += ifwCompName; + } + } + return ifwCompId; +} + +//---------------------------------------------------------------------- +std::string cmCPackIFWGenerator::IfwGetGroupName(cmCPackComponentGroup *group) +{ + std::string ifwGroupName = group->Name; + if(const char* name = + this->GetOption("CPACK_IFW_COMPONENT_GROUP_" + + cmsys::SystemTools::UpperCase(group->Name) + "_NAME")) + { + ifwGroupName = name; + } + return ifwGroupName; +} + +//---------------------------------------------------------------------- +std::string +cmCPackIFWGenerator::IfwGetComponentName(cmCPackComponent *component) +{ + return IfwGetComponentName(component->Name); +} + +//---------------------------------------------------------------------- +std::string +cmCPackIFWGenerator::IfwGetComponentName(const std::string &componentName) +{ + std::string ifwCompName = componentName; + if(const char* name = + this->GetOption("CPACK_IFW_COMPONENT_" + + cmsys::SystemTools::UpperCase(componentName) + "_NAME")) + { + ifwCompName = name; + } + return ifwCompName; +} + +//---------------------------------------------------------------------- +int cmCPackIFWGenerator::InitializeInternal() +{ + // Search Qt Installer Framework tools + + if(!this->IsOn("CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND") || + !this->IsOn("CPACK_IFW_REPOGEN_EXECUTABLE_FOUND")) + { + this->ReadListFile("CPackIFW.cmake"); + } + + // Look 'binarycreator' executable (needs) + + if(this->IsOn("CPACK_IFW_BINARYCREATOR_EXECUTABLE_FOUND")) + { + const char *ifwBinCreatorStr = + this->GetOption("CPACK_IFW_BINARYCREATOR_EXECUTABLE"); + ifwBinCreator = ifwBinCreatorStr ? ifwBinCreatorStr : ""; + } + else + { + ifwBinCreator = ""; + } + + if (ifwBinCreator.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) + + if(this->IsOn("CPACK_IFW_REPOGEN_EXECUTABLE_FOUND")) + { + const char *ifwRepoGenStr = + this->GetOption("CPACK_IFW_REPOGEN_EXECUTABLE"); + ifwRepoGen = ifwRepoGenStr ? ifwRepoGenStr : ""; + } + else + { + ifwRepoGen = ""; + } + + // // Variables that Change Behavior + + // Resolve duplicate names + ifwResolveDuplicateNames = this->IsOn("CPACK_IFW_RESOLVE_DUPLICATE_NAMES"); + + // Additional packages dirs + ifwPkgsDirsVector.clear(); + if(const char* dirs = this->GetOption("CPACK_IFW_PACKAGES_DIRECTORIES")) + { + cmSystemTools::ExpandListArgument(dirs, + ifwPkgsDirsVector); + } + + // 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 QtIFW 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*/) +{ + return "packages/"; +} + +//---------------------------------------------------------------------- +std::string +cmCPackIFWGenerator::GetComponentInstallDirNameSuffix( + const std::string& componentName) +{ + std::map<std::string, cmCPackComponent>::iterator + compIt = this->Components.find(componentName); + + cmCPackComponent *comp = + compIt != this->Components.end() ? &compIt->second : 0; + + const std::string prefix = GetComponentInstallDirNamePrefix(componentName); + const std::string suffix = "/data"; + + if (componentPackageMethod == ONE_PACKAGE_PER_COMPONENT) { + return prefix + IfwGetComponentId(comp) + suffix; + } + + if (componentPackageMethod == ONE_PACKAGE) { + return std::string(prefix + "ALL_COMPONENTS_IN_ONE" + suffix); + } + + return prefix + IfwGetComponentId(comp) + 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"; + } + + const char *ifwPkgInstDir = + this->GetOption("CPACK_PACKAGE_INSTALL_DIRECTORY"); + const char *ifwTargetDir = + this->GetOption("CPACK_IFW_TARGET_DIRECTORY"); + const char *ifwAdminTargetDir = + this->GetOption("CPACK_IFW_ADMIN_TARGET_DIRECTORY"); + + cfg << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + cfg << "<Installer>" << std::endl; + cfg << " <Name>" << cmXMLSafe(ifwPkgName).str() << "</Name>" << std::endl; + cfg << " <Version>" << ifwPkgVersion << "</Version>" << std::endl; + cfg << " <Title>" << cmXMLSafe(ifwPkgDescription).str() << "</Title>" + << std::endl; + + // Default target directory for installation + if (ifwTargetDir) + { + cfg << " <TargetDir>" << ifwTargetDir << "</TargetDir>" << std::endl; + } + else if (ifwPkgInstDir) + { + cfg << " <TargetDir>@ApplicationsDir@/" << ifwPkgInstDir + << "</TargetDir>" << std::endl; + } + else + { + cfg << " <TargetDir>@RootDir@/usr/local</TargetDir>" << std::endl; + } + + // Default target directory for installation with administrator rights + if (ifwAdminTargetDir) + { + cfg << " <AdminTargetDir>" << ifwAdminTargetDir + << "</AdminTargetDir>" << std::endl; + } + + if (!ifwDownloadSite.empty()) + { + cfg << " <RemoteRepositories>" << std::endl; + cfg << " <Repository>" << std::endl; + cfg << " <Url>" << ifwDownloadSite << "</Url>" << std::endl; + // These properties can now be set from "cpack_configure_downloads" + // <Enabled>1</Enabled> + // <Username>user</Username> + // <Password>password</Password> + // <DisplayName>Example repository</DisplayName> + cfg << " </Repository>" << std::endl; + cfg << " </RemoteRepositories>" << std::endl; + } + + // CPack IFW default policy + cfg << " <!-- CPack IFW default policy -->" << std::endl; + cfg << " <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>" + << std::endl; + cfg << " <AllowSpaceInPath>true</AllowSpaceInPath>" << std::endl; + + cfg << "</Installer>" << std::endl; + + return 1; +} + +//---------------------------------------------------------------------- +// Create default package file +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 << " <ReleaseDate>" << IfwCreateCurrentDate() << "</ReleaseDate>" + << std::endl; + + pkgXml << " <ForcedInstallation>true</ForcedInstallation>" << std::endl; + pkgXml << " <Default>true</Default>" << std::endl; + + pkgXml << "</Package>" << std::endl; + + return 1; +} + +//---------------------------------------------------------------------- +std::string cmCPackIFWGenerator::IfwCreateCurrentDate() +{ + time_t rawtime; + struct tm * timeinfo; + char buffer[80]; + + time (&rawtime); + timeinfo = localtime(&rawtime); + + strftime(buffer, 80, "%Y-%m-%d", timeinfo); + + return buffer; +} + +//---------------------------------------------------------------------- +bool cmCPackIFWGenerator::IfwParseLicenses(std::vector<std::string> &licenses, + const std::string &variable, + const std::string &metaDir) +{ + if (const char *option = this->GetOption(variable)) + { + if(!licenses.empty()) licenses.clear(); + cmSystemTools::ExpandListArgument( option, licenses ); + } + else + { + return false; + } + + if ( licenses.size() % 2 != 0 ) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, variable + << " should contain pairs of <display_name> and <file_path>." + << std::endl); + return false; + } + + for(size_t i = 1; i < licenses.size(); i += 2) + { + std::string name = cmSystemTools::GetFilenameName(licenses[i]); + std::string path = metaDir + "/" + name; + cmsys::SystemTools::CopyFileIfDifferent(licenses[i].data(), path.data()); + licenses[i] = name; + } + + return licenses.size() > 1; +} diff --git a/Source/CPack/cmCPackIFWGenerator.h b/Source/CPack/cmCPackIFWGenerator.h new file mode 100644 index 0000000..d70e52d --- /dev/null +++ b/Source/CPack/cmCPackIFWGenerator.h @@ -0,0 +1,82 @@ +/*============================================================================ + 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 cmCPackIFWGenerator + * \brief A generator for Qt Installer Framework tools + * + * http://qt-project.org/doc/qtinstallerframework/index.html + */ +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); + + std::string IfwGetGroupName(cmCPackComponentGroup *group); + + std::string IfwGetComponentName(cmCPackComponent *component); + std::string IfwGetComponentName(const std::string &componentName); + + 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 IfwCreateCurrentDate(); + bool IfwParseLicenses(std::vector<std::string> &licenses, + const std::string &variable, + const std::string &metaDir); + + std::string ifwRepoGen; + std::string ifwBinCreator; + + std::string ifwDownloadSite; + + bool ifwOnlineOnly; + bool ifwResolveDuplicateNames; + std::vector<std::string> ifwPkgsDirsVector; +}; + +#endif diff --git a/Source/QtIFW/cmake.org.html b/Source/QtIFW/cmake.org.html new file mode 100644 index 0000000..cf5649d --- /dev/null +++ b/Source/QtIFW/cmake.org.html @@ -0,0 +1,7 @@ +<html> +<head> +<meta http-equiv="Refresh" content="0; url=http://cmake.org/" /> +</head> +<body> +</body> +</html> diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in new file mode 100644 index 0000000..5491611 --- /dev/null +++ b/Source/QtIFW/installscript.qs.in @@ -0,0 +1,24 @@ +function Component() +{ + // default constructor +} + +Component.prototype.createOperations = function() +{ + // call default implementation to actually install applications! + component.createOperations(); + + // Create shortcut + if (installer.value("os") === "win") { + +@_CPACK_IFW_SHORTCUT_OPTIONAL@ + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/cmake.org.html", + installer.value("StartMenuDir") + "/CMake Web Site.lnk"); + + component.addOperation("CreateShortcut", + installer.value("TargetDir") + "/uninstall.exe", + installer.value("StartMenuDir") + "/Uninstall.lnk"); + } +} |