diff options
27 files changed, 615 insertions, 148 deletions
diff --git a/CMakeCPackOptions.cmake.in b/CMakeCPackOptions.cmake.in index 5600b35..6003565 100644 --- a/CMakeCPackOptions.cmake.in +++ b/CMakeCPackOptions.cmake.in @@ -38,6 +38,10 @@ if(CPACK_GENERATOR MATCHES "IFW") @_CPACK_IFW_PACKAGE_ICON@ set(CPACK_IFW_PACKAGE_WINDOW_ICON "@CMake_SOURCE_DIR@/Source/QtDialog/CMakeSetup128.png") + set(CPACK_IFW_PACKAGE_CONTROL_SCRIPT + "@CMake_SOURCE_DIR@/Source/QtIFW/controlscript.qs") + # Uninstaller configuration + set(CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME "cmake-maintenance") # Package configuration group set(CPACK_IFW_PACKAGE_GROUP CMake) # Group configuration diff --git a/CTestCustom.cmake.in b/CTestCustom.cmake.in index cc2fbb8..7f20d10 100644 --- a/CTestCustom.cmake.in +++ b/CTestCustom.cmake.in @@ -37,6 +37,7 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION "LINK : warning LNK4089: all references to.*SHELL32.dll.*discarded by /OPT:REF" "LINK : warning LNK4089: all references to.*USER32.dll.*discarded by /OPT:REF" "LINK : warning LNK4089: all references to.*ole32.dll.*discarded by /OPT:REF" + "Warning.*: .*/Utilities/KWIML/test/test_INT_format.h.* # Redundant preprocessing concatenation" "Warning: library was too large for page size.*" "Warning: public.*_archive_.*in module.*archive_*clashes with prior module.*archive_.*" "Warning: public.*BZ2_bz.*in module.*bzlib.*clashes with prior module.*bzlib.*" diff --git a/Help/command/cmake_minimum_required.rst b/Help/command/cmake_minimum_required.rst index 92e3001..9865eeb 100644 --- a/Help/command/cmake_minimum_required.rst +++ b/Help/command/cmake_minimum_required.rst @@ -35,3 +35,7 @@ with an error instead of just a warning. :command:`project` command. It is important to establish version and policy settings before invoking other commands whose behavior they may affect. See also policy :policy:`CMP0000`. + + Calling ``cmake_minimum_required()`` inside a :command:`function` + limits some effects to the function scope when invoked. Such calls + should not be made with the intention of having global effects. diff --git a/Help/release/dev/cpack-ifw-updates.rst b/Help/release/dev/cpack-ifw-updates.rst new file mode 100644 index 0000000..c01f04b --- /dev/null +++ b/Help/release/dev/cpack-ifw-updates.rst @@ -0,0 +1,5 @@ +cpack-ifw-updates +----------------- + +* The :manual:`cpack(1)` ``IFW`` generator and the :module:`CPackIFW` + module learned to support Qt Framework Installer 2.0 tools. diff --git a/Modules/CPackDeb.cmake b/Modules/CPackDeb.cmake index 0ccb042..226153c 100644 --- a/Modules/CPackDeb.cmake +++ b/Modules/CPackDeb.cmake @@ -28,29 +28,33 @@ # # .. variable:: CPACK_DEBIAN_PACKAGE_NAME # +# The Debian package summary +# # * Mandatory : YES -# * Default : CPACK_PACKAGE_NAME (lower case) +# * Default : :variable:`CPACK_PACKAGE_NAME` (lower case) # -# The debian package summary # # .. variable:: CPACK_DEBIAN_PACKAGE_VERSION # +# The Debian package version +# # * Mandatory : YES -# * Default : CPACK_PACKAGE_VERSION +# * Default : :variable:`CPACK_PACKAGE_VERSION` # -# The debian package version # # .. variable:: CPACK_DEBIAN_PACKAGE_ARCHITECTURE # +# The Debian package architecture +# # * Mandatory : YES -# * Default : Output of dpkg --print-architecture (or i386 if dpkg is not found) +# * Default : Output of :code:`dpkg --print-architecture` (or :code:`i386` +# if :code:`dpkg` is not found) # -# The debian package architecture # # .. variable:: CPACK_DEBIAN_PACKAGE_DEPENDS # CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS # -# May be used to set deb dependencies. +# Sets the Debian dependencies of this package. # # * Mandatory : NO # * Default : @@ -64,7 +68,7 @@ # If :variable:`CPACK_DEBIAN_PACKAGE_SHLIBDEPS` or # more specifically :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS` # is set for this component, the discovered dependencies will be appended -# to :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS` intead of +# to :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS` instead of # :variable:`CPACK_DEBIAN_PACKAGE_DEPENDS`. If # :variable:`CPACK_DEBIAN_<COMPONENT>_PACKAGE_DEPENDS` is an empty string, # only the automatically discovered dependencies will be set for this @@ -76,15 +80,16 @@ # # .. variable:: CPACK_DEBIAN_PACKAGE_MAINTAINER # +# The Debian package maintainer +# # * Mandatory : YES -# * Default : CPACK_PACKAGE_CONTACT +# * Default : :code:`CPACK_PACKAGE_CONTACT` # -# The debian package maintainer # # .. variable:: CPACK_DEBIAN_PACKAGE_DESCRIPTION # CPACK_COMPONENT_<COMPONENT>_DESCRIPTION # -# The debian package description +# The Debian package description # # * Mandatory : YES # * Default : @@ -92,6 +97,7 @@ # - :variable:`CPACK_DEBIAN_PACKAGE_DESCRIPTION` if set or # - :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` # +# # .. variable:: CPACK_DEBIAN_PACKAGE_SECTION # # * Mandatory : YES @@ -99,33 +105,40 @@ # # .. variable:: CPACK_DEBIAN_COMPRESSION_TYPE # +# The compression used for creating the Debian package. +# Possible values are: lzma, xz, bzip2 and gzip. +# # * Mandatory : YES # * Default : 'gzip' # -# Possible values are: lzma, xz, bzip2 and gzip. # # .. variable:: CPACK_DEBIAN_PACKAGE_PRIORITY # +# The Debian package priority +# # * Mandatory : YES # * Default : 'optional' # -# The debian package priority # # .. variable:: CPACK_DEBIAN_PACKAGE_HOMEPAGE # -# * Mandatory : NO -# * Default : - -# # The URL of the web site for this package, preferably (when applicable) the # site from which the original source can be obtained and any additional # upstream documentation or information may be found. -# The content of this field is a simple URL without any surrounding -# characters such as <>. +# +# * Mandatory : NO +# * Default : - +# +# .. note:: +# +# The content of this field is a simple URL without any surrounding +# characters such as <>. +# # # .. variable:: CPACK_DEBIAN_PACKAGE_SHLIBDEPS # CPACK_DEBIAN_<COMPONENT>_PACKAGE_SHLIBDEPS # -# May be set to ON in order to use dpkg-shlibdeps to generate +# May be set to ON in order to use :code:`dpkg-shlibdeps` to generate # better package dependency list. # # * Mandatory : NO @@ -141,92 +154,132 @@ # may fail to find your own shared libs. # See http://www.cmake.org/Wiki/CMake_RPATH_handling. # -# .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG # -# * Mandatory : NO -# * Default : - +# .. variable:: CPACK_DEBIAN_PACKAGE_DEBUG # # May be set when invoking cpack in order to trace debug information # during CPackDeb run. # +# * Mandatory : NO +# * Default : - +# # .. variable:: CPACK_DEBIAN_PACKAGE_PREDEPENDS # +# Sets the `Pre-Depends` field of the Debian package. +# Like :variable:`Depends <CPACK_DEBIAN_PACKAGE_DEPENDS>`, except that it +# also forces :code:`dpkg` to complete installation of the packages named +# before even starting the installation of the package which declares the +# pre-dependency. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# This field is like Depends, except that it also forces dpkg to complete installation of -# the packages named before even starting the installation of the package which declares -# the pre-dependency. +# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # # .. variable:: CPACK_DEBIAN_PACKAGE_ENHANCES # +# Sets the `Enhances` field of the Debian package. +# Similar to :variable:`Suggests <CPACK_DEBIAN_PACKAGE_SUGGESTS>` but works +# in the opposite direction: declares that a package can enhance the +# functionality of another package. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# This field is similar to Suggests but works in the opposite direction. -# It is used to declare that a package can enhance the functionality of another package. +# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps # # .. variable:: CPACK_DEBIAN_PACKAGE_BREAKS # +# Sets the `Breaks` field of the Debian package. +# When a binary package (P) declares that it breaks other packages (B), +# :code:`dpkg` will not allow the package (P) which declares `Breaks` be +# **unpacked** unless the packages that will be broken (B) are deconfigured +# first. +# As long as the package (P) is configured, the previously deconfigured +# packages (B) cannot be reconfigured again. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# When one binary package declares that it breaks another, dpkg will refuse to allow the -# package which declares Breaks be installed unless the broken package is deconfigured first, -# and it will refuse to allow the broken package to be reconfigured. +# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-breaks +# # # .. variable:: CPACK_DEBIAN_PACKAGE_CONFLICTS # +# Sets the `Conflicts` field of the Debian package. +# When one binary package declares a conflict with another using a `Conflicts` +# field, :code:`dpkg` will not allow them to be unpacked on the system at +# the same time. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# When one binary package declares a conflict with another using a Conflicts field, -# dpkg will refuse to allow them to be installed on the system at the same time. +# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-conflicts +# +# .. note:: +# +# This is a stronger restriction than +# :variable:`Breaks <CPACK_DEBIAN_PACKAGE_BREAKS>`, which prevents the +# broken package from being configured while the breaking package is in +# the "Unpacked" state but allows both packages to be unpacked at the same +# time. # # .. variable:: CPACK_DEBIAN_PACKAGE_PROVIDES # +# Sets the `Provides` field of the Debian package. +# A virtual package is one which appears in the `Provides` control field of +# another package. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# A virtual package is one which appears in the Provides control field of another package. +# See https://www.debian.org/doc/debian-policy/ch-relationships.html#s-virtual +# # # .. variable:: CPACK_DEBIAN_PACKAGE_REPLACES # +# Sets the `Replaces` field of the Debian package. +# Packages can declare in their control file that they should overwrite +# files in certain other packages, or completely replace other packages. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# Packages can declare in their control file that they should overwrite -# files in certain other packages, or completely replace other packages. +# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps +# # # .. variable:: CPACK_DEBIAN_PACKAGE_RECOMMENDS # +# Sets the `Recommends` field of the Debian package. +# Allows packages to declare a strong, but not absolute, dependency on other +# packages. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# Allows packages to declare a strong, but not absolute, dependency on other packages. +# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps +# # # .. variable:: CPACK_DEBIAN_PACKAGE_SUGGESTS # +# Sets the `Suggests` field of the Debian package. +# Allows packages to declare a suggested package install grouping. +# # * Mandatory : NO # * Default : - # -# see http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps -# Allows packages to declare a suggested package install grouping. +# See http://www.debian.org/doc/debian-policy/ch-relationships.html#s-binarydeps +# # # .. variable:: CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA # +# This variable allow advanced user to add custom script to the +# control.tar.gz. +# Typical usage is for conffiles, postinst, postrm, prerm. +# # * Mandatory : NO # * Default : - # -# This variable allow advanced user to add custom script to the -# control.tar.gz Typical usage is for conffiles, postinst, postrm, prerm. # Usage:: # # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA diff --git a/Modules/CPackIFW.cmake b/Modules/CPackIFW.cmake index e5b7601..6649933 100644 --- a/Modules/CPackIFW.cmake +++ b/Modules/CPackIFW.cmake @@ -2,7 +2,7 @@ # CPackIFW # -------- # -# .. _QtIFW: http://qt-project.org/doc/qtinstallerframework/index.html +# .. _QtIFW: http://doc.qt.io/qtinstallerframework/index.html # # This module looks for the location of the command line utilities supplied with # the Qt Installer Framework (QtIFW_). @@ -33,18 +33,26 @@ # # You can use the following variables to change behavior of CPack ``IFW`` generator. # +# Debug +# """""" +# +# .. variable:: CPACK_IFW_VERBOSE +# +# Set to ``ON`` to enable addition debug output. +# By default is ``OFF``. +# # Package # """"""" # # .. variable:: CPACK_IFW_PACKAGE_TITLE # # Name of the installer as displayed on the title bar. -# By default used :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY` +# By default used :variable:`CPACK_PACKAGE_DESCRIPTION_SUMMARY`. # # .. variable:: CPACK_IFW_PACKAGE_PUBLISHER # # Publisher of the software (as shown in the Windows Control Panel). -# By default used :variable:`CPACK_PACKAGE_VENDOR` +# By default used :variable:`CPACK_PACKAGE_VENDOR`. # # .. variable:: CPACK_IFW_PRODUCT_URL # @@ -63,6 +71,12 @@ # # Filename for a logo is used as QWizard::LogoPixmap. # +# .. variable:: CPACK_IFW_PACKAGE_START_MENU_DIRECTORY +# +# Name of the default program group for the product in the Windows Start menu. +# +# By default used :variable:`CPACK_IFW_PACKAGE_NAME`. +# # .. variable:: CPACK_IFW_TARGET_DIRECTORY # # Default target directory for installation. @@ -85,6 +99,35 @@ # The root package name, which will be used if configuration group is not # specified # +# .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME +# +# Filename of the generated maintenance tool. +# The platform-specific executable file extension is appended. +# +# By default used QtIFW_ defaults (``maintenancetool``). +# +# .. variable:: CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE +# +# Filename for the configuration of the generated maintenance tool. +# +# By default used QtIFW_ defaults (``maintenancetool.ini``). +# +# .. variable:: CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS +# +# Set to ``ON`` if the installation path can contain non-ASCII characters. +# +# Is ``ON`` for QtIFW_ less 2.0 tools. +# +# .. variable:: CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH +# +# Set to ``OFF`` if the installation path cannot contain space characters. +# +# Is ``ON`` for QtIFW_ less 2.0 tools. +# +# .. variable:: CPACK_IFW_PACKAGE_CONTROL_SCRIPT +# +# Filename for a custom installer control script. +# # .. variable:: CPACK_IFW_REPOSITORIES_ALL # # The list of remote repositories. @@ -113,6 +156,10 @@ # Tools # """""""" # +# .. variable:: CPACK_IFW_FRAMEWORK_VERSION +# +# The version of used QtIFW_ tools. +# # .. variable:: CPACK_IFW_BINARYCREATOR_EXECUTABLE # # The path to "binarycreator" command line client. @@ -276,16 +323,16 @@ # Qt Installer Framework Manual: # # Index page -# http://qt-project.org/doc/qtinstallerframework/index.html +# http://doc.qt.io/qtinstallerframework/index.html # # Component Scripting -# http://qt-project.org/doc/qtinstallerframework/scripting.html +# http://doc.qt.io/qtinstallerframework/scripting.html # # Predefined Variables -# http://qt-project.org/doc/qtinstallerframework/scripting.html#predefined-variables +# http://doc.qt.io/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/ +# Download Qt Installer Framework for you platform from Qt site: +# http://download.qt.io/official_releases/qt-installer-framework # #============================================================================= @@ -324,8 +371,14 @@ else() endif() set(_CPACK_IFW_SUFFIXES +# Common "bin" - "QtIFW-1.7.0/bin" +# Second branch + "QtIFW2.3.0/bin" + "QtIFW2.2.0/bin" + "QtIFW2.1.0/bin" + "QtIFW2.0.0/bin" +# First branch "QtIFW-1.6.0/bin" "QtIFW-1.5.0/bin" "QtIFW-1.4.0/bin" @@ -351,6 +404,26 @@ find_program(CPACK_IFW_REPOGEN_EXECUTABLE ) mark_as_advanced(CPACK_IFW_REPOGEN_EXECUTABLE) +# Look for 'installerbase' + +find_program(CPACK_IFW_INSTALLERBASE_EXECUTABLE + NAMES installerbase + PATHS ${_CPACK_IFW_PATHS} + PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES} + DOC "QtIFW installer executable base" + ) +mark_as_advanced(CPACK_IFW_INSTALLERBASE_EXECUTABLE) + +# Look for 'devtool' (appeared in the second branch) + +find_program(CPACK_IFW_DEVTOOL_EXECUTABLE + NAMES devtool + PATHS ${_CPACK_IFW_PATHS} + PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES} + DOC "QtIFW devtool command line client" + ) +mark_as_advanced(CPACK_IFW_DEVTOOL_EXECUTABLE) + # ## Next code is included only once # @@ -359,6 +432,27 @@ if(NOT CPackIFW_CMake_INCLUDED) set(CPackIFW_CMake_INCLUDED 1) #============================================================================= +# Framework version +#============================================================================= + +if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND CPACK_IFW_DEVTOOL_EXECUTABLE) + execute_process(COMMAND + "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}" --framework-version + OUTPUT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION) + if(CPACK_IFW_FRAMEWORK_VERSION) + string(REPLACE " " "" + CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") + string(REPLACE "\t" "" + CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") + string(REPLACE "\n" "" + CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION}") + if(CPACK_IFW_VERBOSE) + message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} version") + endif() + endif() +endif() + +#============================================================================= # Macro definition #============================================================================= @@ -514,4 +608,7 @@ macro(cpack_ifw_add_repository reponame) endmacro() +# Resolve package control script +_cpack_ifw_resolve_script(CPACK_IFW_PACKAGE_CONTROL_SCRIPT) + endif() # NOT CPackIFW_CMake_INCLUDED diff --git a/Source/CMakeVersion.cmake b/Source/CMakeVersion.cmake index bb3c25c..060aedd 100644 --- a/Source/CMakeVersion.cmake +++ b/Source/CMakeVersion.cmake @@ -1,5 +1,5 @@ # CMake version number components. set(CMake_VERSION_MAJOR 3) set(CMake_VERSION_MINOR 2) -set(CMake_VERSION_PATCH 20150515) +set(CMake_VERSION_PATCH 20150519) #set(CMake_VERSION_RC 1) diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.cxx b/Source/CPack/IFW/cmCPackIFWGenerator.cxx index 0439ff6..80ba068 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.cxx +++ b/Source/CPack/IFW/cmCPackIFWGenerator.cxx @@ -29,6 +29,8 @@ #include <cmMakefile.h> #include <cmGeneratedFileStream.h> #include <cmXMLSafe.h> +#include <cmVersionConfig.h> +#include <cmTimestamp.h> //---------------------------------------------------------------------------- cmCPackIFWGenerator::cmCPackIFWGenerator() @@ -41,6 +43,27 @@ 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); @@ -59,7 +82,12 @@ int cmCPackIFWGenerator::PackageFiles() if (!Installer.Repositories.empty()) { std::string ifwCmd = RepoGen; - ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + + if(IsVersionLess("2.0.0")) + { + ifwCmd += " -c " + this->toplevel + "/config/config.xml"; + } + ifwCmd += " -p " + this->toplevel + "/packages"; if(!PkgsDirsVector.empty()) @@ -216,8 +244,7 @@ const char *cmCPackIFWGenerator::GetPackagingInstallPrefix() //---------------------------------------------------------------------------- const char *cmCPackIFWGenerator::GetOutputExtension() { - const char *suffix = this->GetOption("CMAKE_EXECUTABLE_SUFFIX"); - return suffix ? suffix : cmCPackGenerator::GetOutputExtension(); + return ExecutableSuffix.c_str(); } //---------------------------------------------------------------------------- @@ -267,6 +294,17 @@ int cmCPackIFWGenerator::InitializeInternal() RepoGen = RepoGenStr; } + // Framework version + if(const char* FrameworkVersionSrt = + this->GetOption("CPACK_IFW_FRAMEWORK_VERSION")) + { + FrameworkVersion = FrameworkVersionSrt; + } + else + { + FrameworkVersion = "1.9.9"; + } + // Variables that Change Behavior // Resolve duplicate names @@ -307,6 +345,24 @@ int cmCPackIFWGenerator::InitializeInternal() 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(); } @@ -552,3 +608,20 @@ cmCPackIFWPackage* cmCPackIFWGenerator::GetComponentPackage( = ComponentPackages.find(component); return pit != ComponentPackages.end() ? pit->second : 0; } + +//---------------------------------------------------------------------------- +void cmCPackIFWGenerator::WriteGeneratedByToStrim(cmGeneratedFileStream &xout) +{ + xout << "<!-- Generated by CPack " << CMake_VERSION << " IFW generator " + << "for QtIFW "; + if(IsVersionLess("2.0")) + { + xout << "less 2.0"; + } + else + { + xout << FrameworkVersion; + } + xout << " tools at " << cmTimestamp().CurrentTime("", true) << " -->" + << std::endl; +} diff --git a/Source/CPack/IFW/cmCPackIFWGenerator.h b/Source/CPack/IFW/cmCPackIFWGenerator.h index 1d4d67b..3246861 100644 --- a/Source/CPack/IFW/cmCPackIFWGenerator.h +++ b/Source/CPack/IFW/cmCPackIFWGenerator.h @@ -13,6 +13,7 @@ #ifndef cmCPackIFWGenerator_h #define cmCPackIFWGenerator_h +#include <cmGeneratedFileStream.h> #include <CPack/cmCPackGenerator.h> #include "cmCPackIFWPackage.h" @@ -44,6 +45,21 @@ public: */ virtual ~cmCPackIFWGenerator(); + /** + * Compare \a version with QtIFW framework version + */ + bool IsVersionLess(const char *version); + + /** + * Compare \a version with QtIFW framework version + */ + bool IsVersionGreater(const char *version); + + /** + * Compare \a version with QtIFW framework version + */ + bool IsVersionEqual(const char *version); + protected: // cmCPackGenerator reimplementation /** @@ -105,6 +121,8 @@ protected: // Methods cmCPackIFWPackage* GetGroupPackage(cmCPackComponentGroup *group) const; cmCPackIFWPackage* GetComponentPackage(cmCPackComponent *component) const; + void WriteGeneratedByToStrim(cmGeneratedFileStream& xout); + protected: // Data friend class cmCPackIFWPackage; @@ -126,6 +144,8 @@ protected: // Data private: std::string RepoGen; std::string BinCreator; + std::string FrameworkVersion; + std::string ExecutableSuffix; bool OnlineOnly; bool ResolveDuplicateNames; diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.cxx b/Source/CPack/IFW/cmCPackIFWInstaller.cxx index 4a99e50..8c77a2c 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.cxx +++ b/Source/CPack/IFW/cmCPackIFWInstaller.cxx @@ -51,6 +51,25 @@ bool cmCPackIFWInstaller::IsOn(const std::string &op) const } //---------------------------------------------------------------------------- +bool cmCPackIFWInstaller::IsVersionLess(const char *version) +{ + return Generator ? Generator->IsVersionLess(version) : false; +} + +//---------------------------------------------------------------------------- +bool cmCPackIFWInstaller::IsVersionGreater(const char *version) +{ + return Generator ? Generator->IsVersionGreater(version) : false; +} + +//---------------------------------------------------------------------------- +bool cmCPackIFWInstaller::IsVersionEqual(const char *version) +{ + return Generator ? Generator->IsVersionEqual(version) : false; +} + + +//---------------------------------------------------------------------------- void cmCPackIFWInstaller::ConfigureFromOptions() { // Name; @@ -151,6 +170,17 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } } + // Start menu + if (const char* optIFW_START_MENU_DIR = + this->GetOption("CPACK_IFW_PACKAGE_START_MENU_DIRECTORY")) + { + StartMenuDir = optIFW_START_MENU_DIR; + } + else + { + StartMenuDir = Name; + } + // Default target directory for installation if (const char* optIFW_TARGET_DIRECTORY = GetOption("CPACK_IFW_TARGET_DIRECTORY")) @@ -177,7 +207,7 @@ void cmCPackIFWInstaller::ConfigureFromOptions() // Repositories Repositories.clear(); RepositoryStruct Repo; - if (const char *site = this->GetOption("CPACK_DOWNLOAD_SITE")) + if(const char *site = this->GetOption("CPACK_DOWNLOAD_SITE")) { Repo.Url = site; Repositories.push_back(Repo); @@ -245,6 +275,53 @@ void cmCPackIFWInstaller::ConfigureFromOptions() } } } + + // Maintenance tool + if(const char* optIFW_MAINTENANCE_TOOL = + this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_NAME")) + { + MaintenanceToolName = optIFW_MAINTENANCE_TOOL; + } + + // Maintenance tool ini file + if(const char* optIFW_MAINTENANCE_TOOL_INI = + this->GetOption("CPACK_IFW_PACKAGE_MAINTENANCE_TOOL_INI_FILE")) + { + MaintenanceToolIniFile = optIFW_MAINTENANCE_TOOL_INI; + } + + // Allow non-ASCII characters + if(this->GetOption("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS")) + { + if(IsOn("CPACK_IFW_PACKAGE_ALLOW_NON_ASCII_CHARACTERS")) + { + AllowNonAsciiCharacters = "true"; + } + else + { + AllowNonAsciiCharacters = "false"; + } + } + + // Space in path + if(this->GetOption("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH")) + { + if(IsOn("CPACK_IFW_PACKAGE_ALLOW_SPACE_IN_PATH")) + { + AllowSpaceInPath = "true"; + } + else + { + AllowSpaceInPath = "false"; + } + } + + // Control script + if(const char* optIFW_CONTROL_SCRIPT = + this->GetOption("CPACK_IFW_PACKAGE_CONTROL_SCRIPT")) + { + ControlScript = optIFW_CONTROL_SCRIPT; + } } //---------------------------------------------------------------------------- @@ -259,7 +336,10 @@ void cmCPackIFWInstaller::GenerateInstallerFile() // Output stream cmGeneratedFileStream xout((Directory + "/config/config.xml").data()); - xout << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl; + xout << "<?xml version=\"1.0\"?>" << std::endl; + + WriteGeneratedByToStrim(xout); + xout << "<Installer>" << std::endl; xout << " <Name>" << cmXMLSafe(Name).str() << "</Name>" << std::endl; @@ -313,11 +393,20 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout << " <Logo>" << name << "</Logo>" << std::endl; } + // Start menu + if(!IsVersionLess("2.0")) + { + xout << " <StartMenuDir>" << StartMenuDir + << "</StartMenuDir>" << std::endl; + } + + // Target dir if(!TargetDir.empty()) { xout << " <TargetDir>" << TargetDir << "</TargetDir>" << std::endl; } + // Admin target dir if(!AdminTargetDir.empty()) { xout << " <AdminTargetDir>" << AdminTargetDir @@ -364,11 +453,52 @@ void cmCPackIFWInstaller::GenerateInstallerFile() xout << " </RemoteRepositories>" << std::endl; } - // CPack IFW default policy - xout << " <!-- CPack IFW default policy -->" << std::endl; - xout << " <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>" - << std::endl; - xout << " <AllowSpaceInPath>true</AllowSpaceInPath>" << std::endl; + // Maintenance tool + if(!IsVersionLess("2.0") && !MaintenanceToolName.empty()) + { + xout << " <MaintenanceToolName>" << MaintenanceToolName + << "</MaintenanceToolName>" << std::endl; + } + + // Maintenance tool ini file + if(!IsVersionLess("2.0") && !MaintenanceToolIniFile.empty()) + { + xout << " <MaintenanceToolIniFile>" << MaintenanceToolIniFile + << "</MaintenanceToolIniFile>" << std::endl; + } + + // Different allows + if(IsVersionLess("2.0")) + { + // CPack IFW default policy + xout << " <!-- CPack IFW default policy for QtIFW less 2.0 -->" + << std::endl; + xout << " <AllowNonAsciiCharacters>true</AllowNonAsciiCharacters>" + << std::endl; + xout << " <AllowSpaceInPath>true</AllowSpaceInPath>" << std::endl; + } + else + { + if(!AllowNonAsciiCharacters.empty()) + { + xout << " <AllowNonAsciiCharacters>" << AllowNonAsciiCharacters + << "</AllowNonAsciiCharacters>" << std::endl; + } + if(!AllowSpaceInPath.empty()) + { + xout << " <AllowAllowSpaceInPath>" << AllowSpaceInPath + << "</AllowSpaceInPath>" << std::endl; + } + } + + // Control script (copy to config dir) + if(!IsVersionLess("2.0") && !ControlScript.empty()) + { + std::string name = cmSystemTools::GetFilenameName(ControlScript); + std::string path = Directory + "/config/" + name; + cmsys::SystemTools::CopyFileIfDifferent(ControlScript.data(), path.data()); + xout << " <ControlScript>" << name << "</ControlScript>" << std::endl; + } xout << "</Installer>" << std::endl; } @@ -402,5 +532,10 @@ void cmCPackIFWInstaller::GeneratePackageFiles() { cmCPackIFWPackage* package = pit->second; package->GeneratePackageFile(); - } + } +} + +void cmCPackIFWInstaller::WriteGeneratedByToStrim(cmGeneratedFileStream &xout) +{ + if(Generator) Generator->WriteGeneratedByToStrim(xout); } diff --git a/Source/CPack/IFW/cmCPackIFWInstaller.h b/Source/CPack/IFW/cmCPackIFWInstaller.h index 5824d33..4cba5b2 100644 --- a/Source/CPack/IFW/cmCPackIFWInstaller.h +++ b/Source/CPack/IFW/cmCPackIFWInstaller.h @@ -13,6 +13,7 @@ #ifndef cmCPackIFWInstaller_h #define cmCPackIFWInstaller_h +#include <cmGeneratedFileStream.h> #include <cmStandardIncludes.h> class cmCPackIFWPackage; @@ -69,17 +70,39 @@ public: // Configuration /// Filename for a logo std::string Logo; + /// Name of the default program group in the Windows Start menu + std::string StartMenuDir; + /// Default target directory for installation std::string TargetDir; /// Default target directory for installation with administrator rights std::string AdminTargetDir; + /// Filename of the generated maintenance tool + std::string MaintenanceToolName; + + /// Filename for the configuration of the generated maintenance tool + std::string MaintenanceToolIniFile; + + /// Set to true if the installation path can contain non-ASCII characters + std::string AllowNonAsciiCharacters; + + /// Set to false if the installation path cannot contain space characters + std::string AllowSpaceInPath; + + /// Filename for a custom installer control script + std::string ControlScript; + public: // Internal implementation const char* GetOption(const std::string& op) const; bool IsOn(const std::string& op) const; + bool IsVersionLess(const char *version); + bool IsVersionGreater(const char *version); + bool IsVersionEqual(const char *version); + void ConfigureFromOptions(); void GenerateInstallerFile(); @@ -90,6 +113,9 @@ public: // Internal implementation PackagesMap Packages; std::vector<RepositoryStruct> Repositories; std::string Directory; + +protected: + void WriteGeneratedByToStrim(cmGeneratedFileStream& xout); }; #endif // cmCPackIFWInstaller_h diff --git a/Source/CPack/IFW/cmCPackIFWPackage.cxx b/Source/CPack/IFW/cmCPackIFWPackage.cxx index 38cef87..5474ad1b 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.cxx +++ b/Source/CPack/IFW/cmCPackIFWPackage.cxx @@ -132,6 +132,24 @@ bool cmCPackIFWPackage::IsOn(const std::string &op) const } //---------------------------------------------------------------------------- +bool cmCPackIFWPackage::IsVersionLess(const char *version) +{ + return Generator ? Generator->IsVersionLess(version) : false; +} + +//---------------------------------------------------------------------------- +bool cmCPackIFWPackage::IsVersionGreater(const char *version) +{ + return Generator ? Generator->IsVersionGreater(version) : false; +} + +//---------------------------------------------------------------------------- +bool cmCPackIFWPackage::IsVersionEqual(const char *version) +{ + return Generator ? Generator->IsVersionEqual(version) : false; +} + +//---------------------------------------------------------------------------- std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent *component) { if (!component) return ""; @@ -432,6 +450,9 @@ void cmCPackIFWPackage::GeneratePackageFile() cmGeneratedFileStream xout((Directory + "/meta/package.xml").data()); xout << "<?xml version=\"1.0\"?>" << std::endl; + + WriteGeneratedByToStrim(xout); + xout << "<Package>" << std::endl; xout << " <DisplayName>" << DisplayName @@ -538,3 +559,8 @@ void cmCPackIFWPackage::GeneratePackageFile() xout << "</Package>" << std::endl; } + +void cmCPackIFWPackage::WriteGeneratedByToStrim(cmGeneratedFileStream &xout) +{ + if(Generator) Generator->WriteGeneratedByToStrim(xout); +} diff --git a/Source/CPack/IFW/cmCPackIFWPackage.h b/Source/CPack/IFW/cmCPackIFWPackage.h index 9fc9bd0..d2f7927 100644 --- a/Source/CPack/IFW/cmCPackIFWPackage.h +++ b/Source/CPack/IFW/cmCPackIFWPackage.h @@ -14,6 +14,7 @@ #define cmCPackIFWPackage_h #include <cmStandardIncludes.h> +#include <cmGeneratedFileStream.h> class cmCPackComponent; class cmCPackComponentGroup; @@ -107,6 +108,10 @@ public: // Internal implementation const char* GetOption(const std::string& op) const; bool IsOn(const std::string& op) const; + bool IsVersionLess(const char *version); + bool IsVersionGreater(const char *version); + bool IsVersionEqual(const char *version); + std::string GetComponentName(cmCPackComponent *component); void DefaultConfiguration(); @@ -128,6 +133,9 @@ public: // Internal implementation std::set<DependenceStruct*> AlienDependencies; // Patch to package directory std::string Directory; + +protected: + void WriteGeneratedByToStrim(cmGeneratedFileStream& xout); }; #endif // cmCPackIFWPackage_h diff --git a/Source/QtIFW/controlscript.qs b/Source/QtIFW/controlscript.qs new file mode 100644 index 0000000..d1a9b10 --- /dev/null +++ b/Source/QtIFW/controlscript.qs @@ -0,0 +1,6 @@ +// controlscript.qs - CMake installation control script + +function Controller() +{ + // do nothing now +} diff --git a/Source/QtIFW/installscript.qs.in b/Source/QtIFW/installscript.qs.in index 5491611..570dba1 100644 --- a/Source/QtIFW/installscript.qs.in +++ b/Source/QtIFW/installscript.qs.in @@ -18,7 +18,7 @@ Component.prototype.createOperations = function() installer.value("StartMenuDir") + "/CMake Web Site.lnk"); component.addOperation("CreateShortcut", - installer.value("TargetDir") + "/uninstall.exe", - installer.value("StartMenuDir") + "/Uninstall.lnk"); + installer.value("TargetDir") + "/cmake-maintenance.exe", + installer.value("StartMenuDir") + "/CMake Maintenance Tool.lnk"); } } diff --git a/Source/cmDefinitions.cxx b/Source/cmDefinitions.cxx index f54bc4d..e2c6876 100644 --- a/Source/cmDefinitions.cxx +++ b/Source/cmDefinitions.cxx @@ -18,32 +18,29 @@ cmDefinitions::Def cmDefinitions::NoDef; //---------------------------------------------------------------------------- cmDefinitions::Def const& cmDefinitions::GetInternal( - const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend) + const std::string& key, StackIter begin, StackIter end) { - assert(rbegin != rend); - MapType::const_iterator i = rbegin->Map.find(key); - if (i != rbegin->Map.end()) + assert(begin != end); + MapType::const_iterator i = begin->Map.find(key); + if (i != begin->Map.end()) { return i->second; } - std::list<cmDefinitions>::reverse_iterator rit = rbegin; - ++rit; - if (rit == rend) + StackIter it = begin; + ++it; + if (it == end) { return cmDefinitions::NoDef; } - Def const& def = cmDefinitions::GetInternal(key, rit, rend); - return rbegin->Map.insert(MapType::value_type(key, def)).first->second; + Def const& def = cmDefinitions::GetInternal(key, it, end); + return begin->Map.insert(MapType::value_type(key, def)).first->second; } //---------------------------------------------------------------------------- const char* cmDefinitions::Get(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend) + StackIter begin, StackIter end) { - Def const& def = cmDefinitions::GetInternal(key, rbegin, rend); + Def const& def = cmDefinitions::GetInternal(key, begin, end); return def.Exists? def.c_str() : 0; } @@ -77,36 +74,24 @@ std::vector<std::string> cmDefinitions::LocalKeys() const } //---------------------------------------------------------------------------- -cmDefinitions cmDefinitions::MakeClosure( - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend) +cmDefinitions cmDefinitions::MakeClosure(StackConstIter begin, + StackConstIter end) { - std::set<std::string> undefined; cmDefinitions closure; - closure.MakeClosure(undefined, rbegin, rend); - return closure; -} - -//---------------------------------------------------------------------------- -void -cmDefinitions::MakeClosure(std::set<std::string>& undefined, - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend) -{ - for (std::list<cmDefinitions>::const_reverse_iterator it = rbegin; - it != rend; ++it) + std::set<std::string> undefined; + for (StackConstIter it = begin; it != end; ++it) { // Consider local definitions. for(MapType::const_iterator mi = it->Map.begin(); mi != it->Map.end(); ++mi) { // Use this key if it is not already set or unset. - if(this->Map.find(mi->first) == this->Map.end() && + if(closure.Map.find(mi->first) == closure.Map.end() && undefined.find(mi->first) == undefined.end()) { if(mi->second.Exists) { - this->Map.insert(*mi); + closure.Map.insert(*mi); } else { @@ -115,22 +100,29 @@ cmDefinitions::MakeClosure(std::set<std::string>& undefined, } } } + return closure; } //---------------------------------------------------------------------------- std::vector<std::string> -cmDefinitions::ClosureKeys(std::set<std::string>& bound) const +cmDefinitions::ClosureKeys(StackConstIter begin, StackConstIter end) { + std::set<std::string> bound; std::vector<std::string> defined; - defined.reserve(this->Map.size()); - for(MapType::const_iterator mi = this->Map.begin(); - mi != this->Map.end(); ++mi) + + for (StackConstIter it = begin; it != end; ++it) { - // Use this key if it is not already set or unset. - if(bound.insert(mi->first).second && mi->second.Exists) + defined.reserve(defined.size() + it->Map.size()); + for(MapType::const_iterator mi = it->Map.begin(); + mi != it->Map.end(); ++mi) { - defined.push_back(mi->first); + // Use this key if it is not already set or unset. + if(bound.insert(mi->first).second && mi->second.Exists) + { + defined.push_back(mi->first); + } } } + return defined; } diff --git a/Source/cmDefinitions.h b/Source/cmDefinitions.h index b244793..80643a9 100644 --- a/Source/cmDefinitions.h +++ b/Source/cmDefinitions.h @@ -28,12 +28,13 @@ */ class cmDefinitions { + typedef std::list<cmDefinitions>::reverse_iterator StackIter; + typedef std::list<cmDefinitions>::const_reverse_iterator StackConstIter; public: /** Get the value associated with a key; null if none. Store the result locally if it came from a parent. */ static const char* Get(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend); + StackIter begin, StackIter end); /** Set (or unset if null) a value associated with a key. */ void Set(const std::string& key, const char* value); @@ -43,12 +44,10 @@ public: /** Get the set of all local keys. */ std::vector<std::string> LocalKeys() const; - std::vector<std::string> - ClosureKeys(std::set<std::string>& bound) const; + static std::vector<std::string> ClosureKeys(StackConstIter begin, + StackConstIter end); - static cmDefinitions MakeClosure( - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend); + static cmDefinitions MakeClosure(StackConstIter begin, StackConstIter end); private: // String with existence boolean. @@ -74,11 +73,7 @@ private: MapType Map; static Def const& GetInternal(const std::string& key, - std::list<cmDefinitions>::reverse_iterator rbegin, - std::list<cmDefinitions>::reverse_iterator rend); - void MakeClosure(std::set<std::string>& undefined, - std::list<cmDefinitions>::const_reverse_iterator rbegin, - std::list<cmDefinitions>::const_reverse_iterator rend); + StackIter begin, StackIter end); }; #endif diff --git a/Source/cmExecutionStatus.h b/Source/cmExecutionStatus.h index d4da5a4..201465d 100644 --- a/Source/cmExecutionStatus.h +++ b/Source/cmExecutionStatus.h @@ -12,47 +12,44 @@ #ifndef cmExecutionStatus_h #define cmExecutionStatus_h -#include "cmObject.h" +#include "cmStandardIncludes.h" /** \class cmExecutionStatus * \brief Superclass for all command status classes * * when a command is involked it may set values on a command status instance */ -class cmExecutionStatus : public cmObject +class cmExecutionStatus { public: - cmTypeMacro(cmExecutionStatus, cmObject); + cmExecutionStatus() { this->Clear(); } - cmExecutionStatus() { this->Clear();} - - virtual void SetReturnInvoked(bool val) + void SetReturnInvoked(bool val) { this->ReturnInvoked = val; } - virtual bool GetReturnInvoked() + bool GetReturnInvoked() { return this->ReturnInvoked; } - virtual void SetBreakInvoked(bool val) + void SetBreakInvoked(bool val) { this->BreakInvoked = val; } - virtual bool GetBreakInvoked() + bool GetBreakInvoked() { return this->BreakInvoked; } - virtual void SetContinueInvoked(bool val) + void SetContinueInvoked(bool val) { this->ContinueInvoked = val; } - virtual bool GetContinueInvoked() + bool GetContinueInvoked() { return this->ContinueInvoked; } - virtual void Clear() + void Clear() { this->ReturnInvoked = false; this->BreakInvoked = false; this->ContinueInvoked = false; this->NestedError = false; } - virtual void SetNestedError(bool val) { this->NestedError = val; } - virtual bool GetNestedError() { return this->NestedError; } - + void SetNestedError(bool val) { this->NestedError = val; } + bool GetNestedError() { return this->NestedError; } -protected: +private: bool ReturnInvoked; bool BreakInvoked; bool ContinueInvoked; diff --git a/Source/cmFunctionCommand.cxx b/Source/cmFunctionCommand.cxx index fdd1018..001adb1 100644 --- a/Source/cmFunctionCommand.cxx +++ b/Source/cmFunctionCommand.cxx @@ -94,8 +94,8 @@ bool cmFunctionHelperCommand::InvokeInitialPass } // we push a scope on the makefile - cmMakefile::LexicalPushPop lexScope(this->Makefile); cmMakefile::ScopePushPop varScope(this->Makefile); + cmMakefile::LexicalPushPop lexScope(this->Makefile); static_cast<void>(varScope); // Push a weak policy scope which restores the policies recorded at diff --git a/Source/cmMakefile.cxx b/Source/cmMakefile.cxx index 2d855ee..99d22d6 100644 --- a/Source/cmMakefile.cxx +++ b/Source/cmMakefile.cxx @@ -94,16 +94,8 @@ public: std::vector<std::string> ClosureKeys() const { - std::vector<std::string> closureKeys; - std::set<std::string> bound; - for (std::list<cmDefinitions>::const_reverse_iterator it = - this->VarStack.rbegin(); it != this->VarStack.rend(); ++it) - { - std::vector<std::string> const& localKeys = it->ClosureKeys(bound); - closureKeys.insert(closureKeys.end(), - localKeys.begin(), localKeys.end()); - } - return closureKeys; + return cmDefinitions::ClosureKeys(this->VarStack.rbegin(), + this->VarStack.rend()); } void PopDefinitions() @@ -3276,6 +3268,7 @@ void cmMakefile::PopFunctionBlockerBarrier(bool reportError) this->FunctionBlockerBarriers.back(); while(this->FunctionBlockers.size() > barrier) { + cmMakefile::LoopBlockPop loopBlockPop(this); cmsys::auto_ptr<cmFunctionBlocker> fb(this->FunctionBlockers.back()); this->FunctionBlockers.pop_back(); if(reportError) diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt new file mode 100644 index 0000000..f4ff709 --- /dev/null +++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach-stderr.txt @@ -0,0 +1,8 @@ +^CMake Error at FunctionUnmatchedForeach.cmake:[0-9]+ \(f\): + A logical block opening on the line + + .*/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake:[0-9]+ \(foreach\) + + is not closed. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake new file mode 100644 index 0000000..ee9c184 --- /dev/null +++ b/Tests/RunCMake/Syntax/FunctionUnmatchedForeach.cmake @@ -0,0 +1,5 @@ +function(f) + foreach(i 1) + #endforeach() # missing +endfunction() +f() diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt new file mode 100644 index 0000000..820cd2e --- /dev/null +++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach-stderr.txt @@ -0,0 +1,8 @@ +^CMake Error at MacroUnmatchedForeach.cmake:[0-9]+ \(m\): + A logical block opening on the line + + .*/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake:[0-9]+ \(foreach\) + + is not closed. +Call Stack \(most recent call first\): + CMakeLists.txt:[0-9]+ \(include\)$ diff --git a/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake b/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake new file mode 100644 index 0000000..be443dd --- /dev/null +++ b/Tests/RunCMake/Syntax/MacroUnmatchedForeach.cmake @@ -0,0 +1,5 @@ +macro(m) + foreach(i 1) + #endforeach() # missing +endmacro() +m() diff --git a/Tests/RunCMake/Syntax/RunCMakeTest.cmake b/Tests/RunCMake/Syntax/RunCMakeTest.cmake index cecd338..c431280 100644 --- a/Tests/RunCMake/Syntax/RunCMakeTest.cmake +++ b/Tests/RunCMake/Syntax/RunCMakeTest.cmake @@ -108,3 +108,7 @@ run_cmake(CMP0053-NameWithNewlineQuoted) run_cmake(CMP0053-NameWithCarriageReturnQuoted) run_cmake(CMP0053-NameWithEscapedSpacesQuoted) run_cmake(CMP0053-NameWithEscapedTabsQuoted) + +# Function and macro tests. +run_cmake(FunctionUnmatchedForeach) +run_cmake(MacroUnmatchedForeach) |