diff options
49 files changed, 1124 insertions, 611 deletions
diff --git a/Modules/BundleUtilities.cmake b/Modules/BundleUtilities.cmake index 7690094..b48c61e 100644 --- a/Modules/BundleUtilities.cmake +++ b/Modules/BundleUtilities.cmake @@ -1,9 +1,11 @@ -# BundleUtilities.cmake +# - Functions to help assemble a standalone bundle application. +# A collection of CMake utility functions useful for dealing with .app +# bundles on the Mac and bundle-like directories on any OS. # -# A collection of CMake utility functions useful for dealing with .app bundles -# on the Mac and bundle-like directories on any OS. -# -# The following functions are provided by this script: +# The following functions are provided by this module: +# fixup_bundle +# copy_and_fixup_bundle +# verify_app # get_bundle_main_executable # get_dotapp_dir # get_bundle_and_executable @@ -15,14 +17,116 @@ # copy_resolved_item_into_bundle # copy_resolved_framework_into_bundle # fixup_bundle_item -# fixup_bundle -# copy_and_fixup_bundle # verify_bundle_prerequisites # verify_bundle_symlinks -# verify_app -# # Requires CMake 2.6 or greater because it uses function, break and # PARENT_SCOPE. Also depends on GetPrerequisites.cmake. +# +# FIXUP_BUNDLE(<app> <libs> <dirs>) +# Fix up a bundle in-place and make it standalone, such that it can be +# drag-n-drop copied to another machine and run on that machine as long as all +# of the system libraries are compatible. +# +# Gather all the keys for all the executables and libraries in a bundle, and +# then, for each key, copy each prerequisite into the bundle. Then fix each one +# up according to its own list of prerequisites. +# +# Then clear all the keys and call verify_app on the final bundle to ensure +# that it is truly standalone. +# +# COPY_AND_FIXUP_BUNDLE(<src> <dst> <libs> <dirs>) +# Makes a copy of the bundle <src> at location <dst> and then fixes up the +# new copied bundle in-place at <dst>... +# +# VERIFY_APP(<app>) +# Verifies that an application <app> appears valid based on running analysis +# tools on it. Calls "message(FATAL_ERROR" if the application is not verified. +# +# GET_BUNDLE_MAIN_EXECUTABLE(<bundle> <result_var>) +# The result will be the full path name of the bundle's main executable file +# or an "error:" prefixed string if it could not be determined. +# +# GET_DOTAPP_DIR(<exe> <dotapp_dir_var>) +# Returns the nearest parent dir whose name ends with ".app" given the full +# path to an executable. If there is no such parent dir, then return a dir at +# the same level as the executable, named with the executable's base name and +# ending with ".app" +# +# The returned directory may or may not exist. +# +# GET_BUNDLE_AND_EXECUTABLE(<app> <bundle_var> <executable_var> <valid_var>) +# Takes either a ".app" directory name or the name of an executable +# nested inside a ".app" directory and returns the path to the ".app" +# directory in <bundle_var> and the path to its main executable in +# <executable_var> +# +# GET_BUNDLE_ALL_EXECUTABLES(<bundle> <exes_var>) +# Scans the given bundle recursively for all executable files and accumulates +# them into a variable. +# +# GET_ITEM_KEY(<item> <key_var>) +# Given a file (item) name, generate a key that should be unique considering +# the set of libraries that need copying or fixing up to make a bundle +# standalone. This is essentially the file name including extension with "." +# replaced by "_" +# +# This key is used as a prefix for CMake variables so that we can associate a +# set of variables with a given item based on its key. +# +# CLEAR_BUNDLE_KEYS(<keys_var>) +# Loop over the list of keys, clearing all the variables associated with each +# key. After the loop, clear the list of keys itself. +# +# Caller of get_bundle_keys should call clear_bundle_keys when done with list +# of keys. +# +# SET_BUNDLE_KEY_VALUES(<keys_var> <context> <item> <exepath> <dirs> +# <copyflag>) +# Add a key to the list (if necessary) for the given item. If added, +# also set all the variables associated with that key. +# +# GET_BUNDLE_KEYS(<app> <libs> <dirs> <keys_var>) +# Loop over all the executable and library files within the bundle (and given +# as extra <libs>) and accumulate a list of keys representing them. Set +# values associated with each key such that we can loop over all of them and +# copy prerequisite libs into the bundle and then do appropriate +# install_name_tool fixups. +# +# COPY_RESOLVED_ITEM_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) +# Copy a resolved item into the bundle if necessary. Copy is not necessary if +# the resolved_item is "the same as" the resolved_embedded_item. +# +# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE(<resolved_item> <resolved_embedded_item>) +# Copy a resolved framework into the bundle if necessary. Copy is not necessary +# if the resolved_item is "the same as" the resolved_embedded_item. +# +# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want full +# frameworks embedded in your bundles, set BU_COPY_FULL_FRAMEWORK_CONTENTS to +# ON before calling fixup_bundle. By default, +# COPY_RESOLVED_FRAMEWORK_INTO_BUNDLE copies the framework dylib itself plus +# the framework Resources directory. +# +# FIXUP_BUNDLE_ITEM(<resolved_embedded_item> <exepath> <dirs>) +# Get the direct/non-system prerequisites of the resolved embedded item. For +# each prerequisite, change the way it is referenced to the value of the +# _EMBEDDED_ITEM keyed variable for that prerequisite. (Most likely changing to +# an "@executable_path" style reference.) +# +# Also, change the id of the item being fixed up to its own _EMBEDDED_ITEM +# value. +# +# Accumulate changes in a local variable and make *one* call to +# install_name_tool at the end of the function with all the changes at once. +# +# VERIFY_BUNDLE_PREREQUISITES(<bundle> <result_var> <info_var>) +# Verifies that the sum of all prerequisites of all files inside the bundle +# are contained within the bundle or are "system" libraries, presumed to exist +# everywhere. +# +# VERIFY_BUNDLE_SYMLINKS(<bundle> <result_var> <info_var>) +# Verifies that any symlinks found in the bundle point to other files that are +# already also in the bundle... Anything that points to an external file causes +# this function to fail the verification. #============================================================================= # Copyright 2008-2009 Kitware, Inc. @@ -44,11 +148,6 @@ get_filename_component(BundleUtilities_cmake_dir "${CMAKE_CURRENT_LIST_FILE}" PA include("${BundleUtilities_cmake_dir}/GetPrerequisites.cmake") -# get_bundle_main_executable -# -# The result will be the full path name of the bundle's main executable file -# or an "error:" prefixed string if it could not be determined. -# function(get_bundle_main_executable bundle result_var) set(result "error: '${bundle}/Contents/Info.plist' file does not exist") @@ -110,15 +209,6 @@ function(get_bundle_main_executable bundle result_var) endfunction(get_bundle_main_executable) -# get_dotapp_dir -# -# Returns the nearest parent dir whose name ends with ".app" given the full path -# to an executable. If there is no such parent dir, then return a dir at the same -# level as the executable, named with the executable's base name and ending with -# ".app" -# -# The returned directory may or may not exist. -# function(get_dotapp_dir exe dotapp_dir_var) set(s "${exe}") @@ -156,13 +246,6 @@ function(get_dotapp_dir exe dotapp_dir_var) endfunction(get_dotapp_dir) -# get_bundle_and_executable -# -# Takes either a ".app" directory name or the name of an executable -# nested inside a ".app" directory and returns the path to the ".app" -# directory in ${bundle_var} and the path to its main executable in -# ${executable_var} -# function(get_bundle_and_executable app bundle_var executable_var valid_var) set(valid 0) @@ -216,11 +299,6 @@ function(get_bundle_and_executable app bundle_var executable_var valid_var) endfunction(get_bundle_and_executable) -# get_bundle_all_executables -# -# Scans the given bundle recursively for all executable files and accumulates -# them into a variable. -# function(get_bundle_all_executables bundle exes_var) set(exes "") @@ -236,15 +314,6 @@ function(get_bundle_all_executables bundle exes_var) endfunction(get_bundle_all_executables) -# get_item_key -# -# Given a file (item) name, generate a key that should be unique considering the set of -# libraries that need copying or fixing up to make a bundle standalone. This is -# essentially the file name including extension with "." replaced by "_" -# -# This key is used as a prefix for CMake variables so that we can associate a set -# of variables with a given item based on its key. -# function(get_item_key item key_var) get_filename_component(item_name "${item}" NAME) if(WIN32) @@ -255,14 +324,6 @@ function(get_item_key item key_var) endfunction(get_item_key) -# clear_bundle_keys -# -# Loop over the list of keys, clearing all the variables associated with each -# key. After the loop, clear the list of keys itself. -# -# Caller of get_bundle_keys should call clear_bundle_keys when done with list -# of keys. -# function(clear_bundle_keys keys_var) foreach(key ${${keys_var}}) set(${key}_ITEM PARENT_SCOPE) @@ -276,11 +337,6 @@ function(clear_bundle_keys keys_var) endfunction(clear_bundle_keys) -# set_bundle_key_values -# -# Add a key to the list (if necessary) for the given item. If added, -# also set all the variables associated with that key. -# function(set_bundle_key_values keys_var context item exepath dirs copyflag) get_filename_component(item_name "${item}" NAME) @@ -336,14 +392,6 @@ function(set_bundle_key_values keys_var context item exepath dirs copyflag) endfunction(set_bundle_key_values) -# get_bundle_keys -# -# Loop over all the executable and library files within the bundle (and given as -# extra "${libs}") and accumulate a list of keys representing them. Set values -# associated with each key such that we can loop over all of them and copy -# prerequisite libs into the bundle and then do appropriate install_name_tool -# fixups. -# function(get_bundle_keys app libs dirs keys_var) set(${keys_var} PARENT_SCOPE) @@ -406,11 +454,6 @@ function(get_bundle_keys app libs dirs keys_var) endfunction(get_bundle_keys) -# copy_resolved_item_into_bundle -# -# Copy a resolved item into the bundle if necessary. Copy is not necessary if -# the resolved_item is "the same as" the resolved_embedded_item. -# function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item) if(WIN32) # ignore case on Windows @@ -434,17 +477,6 @@ function(copy_resolved_item_into_bundle resolved_item resolved_embedded_item) endfunction(copy_resolved_item_into_bundle) -# copy_resolved_framework_into_bundle -# -# Copy a resolved framework into the bundle if necessary. Copy is not necessary -# if the resolved_item is "the same as" the resolved_embedded_item. -# -# By default, BU_COPY_FULL_FRAMEWORK_CONTENTS is not set. If you want full -# frameworks embedded in your bundles, set BU_COPY_FULL_FRAMEWORK_CONTENTS to -# ON before calling fixup_bundle. By default, -# copy_resolved_framework_into_bundle copies the framework dylib itself plus -# any framework Resources. -# function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_item) if(WIN32) # ignore case on Windows @@ -487,18 +519,6 @@ function(copy_resolved_framework_into_bundle resolved_item resolved_embedded_ite endfunction(copy_resolved_framework_into_bundle) -# fixup_bundle_item -# -# Get the direct/non-system prerequisites of the resolved embedded item. For each -# prerequisite, change the way it is referenced to the value of the _EMBEDDED_ITEM -# keyed variable for that prerequisite. (Most likely changing to an "@executable_path" -# style reference.) -# -# Also, change the id of the item being fixed up to its own _EMBEDDED_ITEM value. -# -# Accumulate changes in a local variable and make *one* call to install_name_tool -# at the end of the function with all the changes at once. -# function(fixup_bundle_item resolved_embedded_item exepath dirs) # This item's key is "ikey": # @@ -530,19 +550,6 @@ function(fixup_bundle_item resolved_embedded_item exepath dirs) endfunction(fixup_bundle_item) -# fixup_bundle -# -# Fix up a bundle in-place and make it standalone, such that it can be drag-n-drop -# copied to another machine and run on that machine as long as all of the system -# libraries are compatible. -# -# Gather all the keys for all the executables and libraries in a bundle, and then, -# for each key, copy each prerequisite into the bundle. Then fix each one up according -# to its own list of prerequisites. -# -# Then clear all the keys and call verify_app on the final bundle to ensure that -# it is truly standalone. -# function(fixup_bundle app libs dirs) message(STATUS "fixup_bundle") message(STATUS " app='${app}'") @@ -617,23 +624,12 @@ function(fixup_bundle app libs dirs) endfunction(fixup_bundle) -# copy_and_fixup_bundle -# -# Makes a copy of the bundle "src" at location "dst" and then fixes up the -# new copied bundle in-place at "dst"... -# function(copy_and_fixup_bundle src dst libs dirs) execute_process(COMMAND ${CMAKE_COMMAND} -E copy_directory "${src}" "${dst}") fixup_bundle("${dst}" "${libs}" "${dirs}") endfunction(copy_and_fixup_bundle) -# verify_bundle_prerequisites -# -# Verifies that the sum of all prerequisites of all files inside the bundle -# are contained within the bundle or are "system" libraries, presumed to exist -# everywhere. -# function(verify_bundle_prerequisites bundle result_var info_var) set(result 1) set(info "") @@ -695,12 +691,6 @@ function(verify_bundle_prerequisites bundle result_var info_var) endfunction(verify_bundle_prerequisites) -# verify_bundle_symlinks -# -# Verifies that any symlinks found in the bundle point to other files that are -# already also in the bundle... Anything that points to an external file causes -# this function to fail the verification. -# function(verify_bundle_symlinks bundle result_var info_var) set(result 1) set(info "") @@ -714,11 +704,6 @@ function(verify_bundle_symlinks bundle result_var info_var) endfunction(verify_bundle_symlinks) -# verify_app -# -# Verifies that an application appears valid based on running analysis tools on it. -# Calls message/FATAL_ERROR if the application is not verified. -# function(verify_app app) set(verified 0) set(info "") diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index 439ab4f..3ade3aa 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -83,13 +83,12 @@ # May be used to set RPM packages that are obsoleted by this one. # CPACK_RPM_PACKAGE_RELOCATABLE # Mandatory : NO -# Default : - +# Default : CPACK_PACKAGE_RELOCATABLE # If this variable is set to TRUE or ON CPackRPM will try # to build a relocatable RPM package. A relocatable RPM may # be installed using rpm --prefix or --relocate in order to # install it at an alternate place see rpm(8). -# Note that currently this may fail if the package contains -# files installed with absolute path or CPACK_SET_DESTDIR is set to ON. +# Note that currently this may fail if CPACK_SET_DESTDIR is set to ON. # If CPACK_SET_DESTDIR is set then you will get a warning message # but if there is file installed with absolute path you'll get # unexpected behavior. @@ -331,15 +330,18 @@ ELSE(CPACK_RPM_COMPRESSION_TYPE) SET(CPACK_RPM_COMPRESSION_TYPE_TMP "") ENDIF(CPACK_RPM_COMPRESSION_TYPE) +if(CPACK_PACKAGE_RELOCATABLE) + set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) +endif(CPACK_PACKAGE_RELOCATABLE) if(CPACK_RPM_PACKAGE_RELOCATABLE) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Trying to build a relocatable package") + message("CPackRPM:Debug: Trying to build a relocatable package") endif(CPACK_RPM_PACKAGE_DEBUG) - if(CPACK_SET_DESTDIR) - message(SEND_ERROR "CPackRPM:Warning: CPACK_SET_DESTDIR is set while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.") - else(CPACK_SET_DESTDIR) + if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) + message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.") + else(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) - endif(CPACK_SET_DESTDIR) + endif(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) endif(CPACK_RPM_PACKAGE_RELOCATABLE) # check if additional fields for RPM spec header are given @@ -463,6 +465,34 @@ EXECUTE_PROCESS(COMMAND find -type f -o -type l WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}" OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES) +if (CPACK_ABSOLUTE_DESTINATION_FILES) + IF(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES}") + ENDIF(CPACK_RPM_PACKAGE_DEBUG) + # Remove trailing space + string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) + # Transform endline separated - string into CMake List + string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") + # Remove unecessary quotes + string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") + # Remove ABSOLUTE install file from INSTALL FILE LIST + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES}) + # Rebuild INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endforeach(F) + # Build ABSOLUTE_INSTALL_FILES + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES) + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${CPACK_RPM_ABSOLUTE_INSTALL_FILES}%config \"${F}\"\n") + endforeach(F) + IF(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_ABSOLUTE_INSTALL_FILES=${CPACK_RPM_ABSOLUTE_INSTALL_FILES}") + message("CPackRPM:Debug: CPACK_RPM_INSTALL_FILES=${CPACK_RPM_INSTALL_FILES}") + ENDIF(CPACK_RPM_PACKAGE_DEBUG) +endif(CPACK_ABSOLUTE_DESTINATION_FILES) + # The name of the final spec file to be used by rpmbuild SET(CPACK_RPM_BINARY_SPECFILE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_NAME}.spec") @@ -547,6 +577,7 @@ fi %files %defattr(-,root,root,-) ${CPACK_RPM_INSTALL_FILES} +${CPACK_RPM_ABSOLUTE_INSTALL_FILES} %changelog \@CPACK_RPM_SPEC_CHANGELOG\@ diff --git a/Modules/FeatureSummary.cmake b/Modules/FeatureSummary.cmake index c4a97d5..594e2e7 100644 --- a/Modules/FeatureSummary.cmake +++ b/Modules/FeatureSummary.cmake @@ -1,23 +1,100 @@ # - Macros for generating a summary of enabled/disabled features # -# PRINT_ENABLED_FEATURES() -# Print a summary of all enabled features. By default all successfull -# FIND_PACKAGE() calls will appear here, except the ones which used the -# QUIET keyword. Additional features can be added by appending an entry -# to the global ENABLED_FEATURES property. If SET_FEATURE_INFO() is -# used for that feature, the output will be much more informative. +# This module provides the macros feature_summary(), set_package_info() and +# add_feature_info(). +# For compatiblity it also still provides set_feature_info(), +# print_enabled_features() and print_disabled_features. # -# PRINT_DISABLED_FEATURES() -# Same as PRINT_ENABLED_FEATURES(), but for disabled features. It can -# be extended the same way by adding to the global property -# DISABLED_FEATURES. +# These macros can be used to generate a summary of enabled and disabled +# packages and/or feature for a build tree: # -# SET_FEATURE_INFO(NAME DESCRIPTION [URL [COMMENT] ] ) -# Use this macro to set up information about the named feature, which will -# then be displayed by PRINT_ENABLED/DISABLED_FEATURES(). -# Example: SET_FEATURE_INFO(LibXml2 "XML processing library." -# "http://xmlsoft.org/") +# -- Enabled features: +# LibXml2 (required version >= 2.4) , XML processing library. , <http://xmlsoft.org> +# PNG , A PNG image library. , <http://www.libpng.org/pub/png/> +# -- Disabled features: +# Lua51 , The Lua scripting language. , <http://www.lua.org> +# Foo , Foo provides cool stuff. # +# +# FEATURE_SUMMARY( [FILENAME <file>] +# [APPEND] +# [VAR <variable_name>] +# [DESCRIPTION "Found packages:"] +# WHAT (ALL | PACKAGES_FOUND | PACKAGES_NOT_FOUND +# | ENABLED_FEATURES | DISABLED_FEATURES] +# ) +# +# The FEATURE_SUMMARY() macro can be used to print information about enabled +# or disabled features or packages of a project. +# By default, only the names of the features/packages will be printed and their +# required version when one was specified. Use SET_FEATURE_INFO() to add more +# useful information, like e.g. a download URL for the respective package. +# +# The WHAT option is the only mandatory option. Here you specify what information +# will be printed: +# ENABLED_FEATURES: the list of all features and packages which are enabled, +# excluding the QUIET packages +# DISABLED_FEATURES: the list of all features and packages which are disabled, +# excluding the QUIET packages +# PACKAGES_FOUND: the list of all packages which have been found +# PACKAGES_NOT_FOUND: the list of all packages which have not been found +# ALL: this will give all packages which have or have not been found +# +# If a FILENAME is given, the information is printed into this file. If APPEND +# is used, it is appended to this file, otherwise the file is overwritten if +# it already existed. +# If the VAR option is used, the information is "printed" into the specified +# variable. +# If FILENAME is not used, the information is printed to the terminal. +# Using the DESCRIPTION option a description or headline can be set which will +# be printed above the actual content. +# +# Example 1, append everything to a file: +# feature_summary(WHAT ALL +# FILENAME ${CMAKE_BINARY_DIR}/all.log APPEND) +# +# Example 2, print the enabled features into the variable enabledFeaturesText: +# feature_summary(WHAT ENABLED_FEATURES +# DESCRIPTION "Enabled Features:" +# VAR enabledFeaturesText) +# message(STATUS "${enabledFeaturesText}") +# +# +# SET_PACKAGE_INFO(<name> <description> [<url> [<comment>] ] ) +# Use this macro to set up information about the named package, which can +# then be displayed via FEATURE_SUMMARY(). +# This can be done either directly in the Find-module or in the project +# which uses the module after the FIND_PACKAGE() call. +# The features for which information can be set are added automatically by the +# find_package() command. +# +# Example for setting the info for a package: +# find_package(LibXml2) +# set_package_info(LibXml2 "XML processing library." "http://xmlsoft.org/") +# +# +# ADD_FEATURE_INFO(<name> <enabled> <description>) +# Use this macro to add information about a feature with the given <name>. +# <enabled> contains whether this feature is enabled or not, <description> +# is a text descibing the feature. +# The information can be displayed using feature_summary() for ENABLED_FEATURES +# and DISABLED_FEATURES respectively. +# +# Example for setting the info for a feature: +# option(WITH_FOO "Help for foo" ON) +# add_feature_info(Foo WITH_FOO "The Foo feature provides very cool stuff.") +# +# +# The following macros are provided for compatibility with previous CMake versions: +# +# PRINT_ENABLED_FEATURES() +# Does the same as FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") +# +# PRINT_DISABLED_FEATURES() +# Does the same as FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") +# +# SET_FEATURE_INFO(<name> <description> [<url> [<comment>] ] ) +# Does the same as SET_PACKAGE_INFO(<name> <description> <url> <comment> ) #============================================================================= # Copyright 2007-2009 Kitware, Inc. @@ -32,47 +109,121 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -FUNCTION(SET_FEATURE_INFO _name _desc) +INCLUDE(CMakeParseArguments) + + +FUNCTION(ADD_FEATURE_INFO _name _enabled _desc) + IF (${_enabled}) + SET_PROPERTY(GLOBAL APPEND PROPERTY ENABLED_FEATURES "${_name}") + ELSE () + SET_PROPERTY(GLOBAL APPEND PROPERTY DISABLED_FEATURES "${_name}") + ENDIF () + + SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" ) +ENDFUNCTION(SET_FEATURE_INFO) + + +FUNCTION(SET_FEATURE_INFO) + SET_PACKAGE_INFO(${ARGN}) +ENDFUNCTION(SET_FEATURE_INFO) + + +FUNCTION(SET_PACKAGE_INFO _name _desc) SET(_url "${ARGV2}") SET(_comment "${ARGV3}") - SET_PROPERTY(GLOBAL PROPERTY ${_name}_DESCRIPTION "${_desc}" ) + SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_DESCRIPTION "${_desc}" ) IF(_url MATCHES ".+") - SET_PROPERTY(GLOBAL PROPERTY ${_name}_URL "${_url}" ) + SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_URL "${_url}" ) ENDIF(_url MATCHES ".+") IF(_comment MATCHES ".+") - SET_PROPERTY(GLOBAL PROPERTY ${_name}_COMMENT "${_comment}" ) + SET_PROPERTY(GLOBAL PROPERTY _CMAKE_${_name}_COMMENT "${_comment}" ) ENDIF(_comment MATCHES ".+") -ENDFUNCTION(SET_FEATURE_INFO) +ENDFUNCTION(SET_PACKAGE_INFO) -FUNCTION(_PRINT_FEATURES _property _text) - SET(_currentFeatureText "${_text}") +FUNCTION(_FS_GET_FEATURE_SUMMARY _property _var) + SET(_currentFeatureText "") GET_PROPERTY(_EnabledFeatures GLOBAL PROPERTY ${_property}) FOREACH(_currentFeature ${_EnabledFeatures}) SET(_currentFeatureText "${_currentFeatureText}\n${_currentFeature}") - GET_PROPERTY(_info GLOBAL PROPERTY ${_currentFeature}_DESCRIPTION) + GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_REQUIRED_VERSION) + IF(_info) + SET(_currentFeatureText "${_currentFeatureText} (required version ${_info})") + ENDIF(_info) + GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_DESCRIPTION) IF(_info) SET(_currentFeatureText "${_currentFeatureText} , ${_info}") ENDIF(_info) - GET_PROPERTY(_info GLOBAL PROPERTY ${_currentFeature}_URL) + GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_URL) IF(_info) SET(_currentFeatureText "${_currentFeatureText} , <${_info}>") ENDIF(_info) - GET_PROPERTY(_info GLOBAL PROPERTY ${_currentFeature}_COMMENT) + GET_PROPERTY(_info GLOBAL PROPERTY _CMAKE_${_currentFeature}_COMMENT) IF(_info) SET(_currentFeatureText "${_currentFeatureText} , ${_info}") ENDIF(_info) ENDFOREACH(_currentFeature) - MESSAGE(STATUS "${_currentFeatureText}\n") -ENDFUNCTION(_PRINT_FEATURES) + SET(${_var} "${_currentFeatureText}" PARENT_SCOPE) +ENDFUNCTION(_FS_GET_FEATURE_SUMMARY) FUNCTION(PRINT_ENABLED_FEATURES) - _PRINT_FEATURES( ENABLED_FEATURES "Enabled features:") + FEATURE_SUMMARY(WHAT ENABLED_FEATURES DESCRIPTION "Enabled features:") ENDFUNCTION(PRINT_ENABLED_FEATURES) FUNCTION(PRINT_DISABLED_FEATURES) - _PRINT_FEATURES( DISABLED_FEATURES "Disabled features:") + FEATURE_SUMMARY(WHAT DISABLED_FEATURES DESCRIPTION "Disabled features:") ENDFUNCTION(PRINT_DISABLED_FEATURES) + + +FUNCTION(FEATURE_SUMMARY) +# CMAKE_PARSE_ARGUMENTS(<prefix> <options> <one_value_keywords> <multi_value_keywords> args...) + SET(options APPEND) + SET(oneValueArgs FILENAME VAR DESCRIPTION WHAT) + SET(multiValueArgs ) # none + + CMAKE_PARSE_ARGUMENTS(_FS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${_FIRST_ARG} ${ARGN}) + + IF(_FS_UNPARSED_ARGUMENTS) + MESSAGE(FATAL_ERROR "Unknown keywords given to FEATURE_SUMMARY(): \"${_FS_UNPARSED_ARGUMENTS}\"") + ENDIF(_FS_UNPARSED_ARGUMENTS) + + IF(NOT _FS_WHAT) + MESSAGE(FATAL_ERROR "The call to FEATURE_SUMMAY() doesn't set the required WHAT argument.") + ENDIF(NOT _FS_WHAT) + + IF( "${_FS_WHAT}" STREQUAL "ENABLED_FEATURES" + OR "${_FS_WHAT}" STREQUAL "DISABLED_FEATURES" + OR "${_FS_WHAT}" STREQUAL "PACKAGES_FOUND" + OR "${_FS_WHAT}" STREQUAL "PACKAGES_NOT_FOUND") + _FS_GET_FEATURE_SUMMARY( ${_FS_WHAT} _featureSummary) + ELSEIF("${_FS_WHAT}" STREQUAL "ALL") + _FS_GET_FEATURE_SUMMARY( PACKAGES_FOUND _tmp1) + _FS_GET_FEATURE_SUMMARY( PACKAGES_NOT_FOUND _tmp2) + SET(_featureSummary "${_tmp1}${_tmp2}") + ELSE() + MESSAGE(FATAL_ERROR "The WHAT argument of FEATURE_SUMMARY() is set to ${_FS_WHAT}, which is not a valid value.") + ENDIF() + + SET(_fullText "${_FS_DESCRIPTION}${_featureSummary}\n") + + IF(_FS_FILENAME) + IF(_FS_APPEND) + FILE(WRITE "${_FS_FILENAME}" "${_fullText}") + ELSE(_FS_APPEND) + FILE(APPEND "${_FS_FILENAME}" "${_fullText}") + ENDIF(_FS_APPEND) + + ELSE(_FS_FILENAME) + IF(NOT _FS_VAR) + MESSAGE(STATUS "${_fullText}") + ENDIF(NOT _FS_VAR) + ENDIF(_FS_FILENAME) + + IF(_FS_VAR) + SET(${_FS_VAR} "${_fullText}" PARENT_SCOPE) + ENDIF(_FS_VAR) + +ENDFUNCTION(FEATURE_SUMMARY) diff --git a/Modules/FindBISON.cmake b/Modules/FindBISON.cmake index 0c622fb..6021b12 100644 --- a/Modules/FindBISON.cmake +++ b/Modules/FindBISON.cmake @@ -96,7 +96,7 @@ IF(BISON_EXECUTABLE) # MACRO(BISON_TARGET Name BisonInput BisonOutput) SET(BISON_TARGET_output_header "") - SET(BISON_TARGET_command_opt "") + SET(BISON_TARGET_cmdopt "") SET(BISON_TARGET_outputs "${BisonOutput}") IF(NOT ${ARGC} EQUAL 3 AND NOT ${ARGC} EQUAL 5 AND NOT ${ARGC} EQUAL 7) MESSAGE(SEND_ERROR "Usage") diff --git a/Modules/FindCxxTest.cmake b/Modules/FindCxxTest.cmake index 759b4fd..6a66d21 100644 --- a/Modules/FindCxxTest.cmake +++ b/Modules/FindCxxTest.cmake @@ -5,20 +5,37 @@ # # INPUT Variables # -# CXXTEST_USE_PYTHON -# If true, the CXXTEST_ADD_TEST macro will use -# the Python test generator instead of Perl. +# CXXTEST_USE_PYTHON [deprecated since 1.3] +# Only used in the case both Python & Perl +# are detected on the system to control +# which CxxTest code generator is used. +# +# NOTE: In older versions of this Find Module, +# this variable controlled if the Python test +# generator was used instead of the Perl one, +# regardless of which scripting language the +# user had installed. +# +# CXXTEST_TESTGEN_ARGS (since CMake 2.8.3) +# Specify a list of options to pass to the CxxTest code +# generator. If not defined, --error-printer is +# passed. # # OUTPUT Variables # # CXXTEST_FOUND # True if the CxxTest framework was found -# CXXTEST_INCLUDE_DIR +# CXXTEST_INCLUDE_DIRS # Where to find the CxxTest include directory # CXXTEST_PERL_TESTGEN_EXECUTABLE -# The perl-based test generator. +# The perl-based test generator # CXXTEST_PYTHON_TESTGEN_EXECUTABLE -# The python-based test generator. +# The python-based test generator +# CXXTEST_TESTGEN_EXECUTABLE (since CMake 2.8.3) +# The test generator that is actually used (chosen using user preferences +# and interpreters found in the system) +# CXXTEST_TESTGEN_INTERPRETER (since CMake 2.8.3) +# The full path to the Perl or Python executable on the system # # MACROS for optional use by CMake users: # @@ -26,9 +43,11 @@ # Creates a CxxTest runner and adds it to the CTest testing suite # Parameters: # test_name The name of the test -# gen_source_file The generated source filename to be generated by CxxTest +# gen_source_file The generated source filename to be +# generated by CxxTest # input_files_to_testgen The list of header files containing the -# CxxTest::TestSuite's to be included in this runner +# CxxTest::TestSuite's to be included in +# this runner # # #============== # Example Usage: @@ -65,8 +84,8 @@ # #============================================================================= -# Copyright 2008-2009 Kitware, Inc. -# Copyright 2008-2009 Philip Lowman <philip@yhbt.com> +# Copyright 2008-2010 Kitware, Inc. +# Copyright 2008-2010 Philip Lowman <philip@yhbt.com> # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -78,6 +97,14 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) +# Version 1.3 (8/19/10) (CMake 2.8.3) +# Included patch by Simone Rossetto to check if either Python or Perl +# are present in the system. Whichever intepreter that is detected +# is now used to run the test generator program. If both interpreters +# are detected, the CXXTEST_USE_PYTHON variable is obeyed. +# +# Also added support for CXXTEST_TESTGEN_ARGS, for manually specifying +# options to the CxxTest code generator. # Version 1.2 (3/2/08) # Included patch from Tyler Roscoe to have the perl & python binaries # detected based on CXXTEST_INCLUDE_DIR @@ -95,17 +122,12 @@ #============================================================= macro(CXXTEST_ADD_TEST _cxxtest_testname _cxxtest_outfname) set(_cxxtest_real_outfname ${CMAKE_CURRENT_BINARY_DIR}/${_cxxtest_outfname}) - if(CXXTEST_USE_PYTHON) - set(_cxxtest_executable ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE}) - else() - set(_cxxtest_executable ${CXXTEST_PERL_TESTGEN_EXECUTABLE}) - endif() add_custom_command( OUTPUT ${_cxxtest_real_outfname} DEPENDS ${ARGN} - COMMAND ${_cxxtest_executable} - --error-printer -o ${_cxxtest_real_outfname} ${ARGN} + COMMAND ${CXXTEST_TESTGEN_INTERPRETER} + ${CXXTEST_TESTGEN_EXECUTABLE} ${CXXTEST_TESTGEN_ARGS} -o ${_cxxtest_real_outfname} ${ARGN} ) set_source_files_properties(${_cxxtest_real_outfname} PROPERTIES GENERATED true) @@ -124,14 +146,48 @@ endmacro(CXXTEST_ADD_TEST) #============================================================= # main() #============================================================= +if(NOT DEFINED CXXTEST_TESTGEN_ARGS) + set(CXXTEST_TESTGEN_ARGS --error-printer) +endif() + +find_package(PythonInterp QUIET) +find_package(Perl QUIET) find_path(CXXTEST_INCLUDE_DIR cxxtest/TestSuite.h) -find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl - PATHS ${CXXTEST_INCLUDE_DIR}) find_program(CXXTEST_PYTHON_TESTGEN_EXECUTABLE cxxtestgen.py - PATHS ${CXXTEST_INCLUDE_DIR}) + PATHS ${CXXTEST_INCLUDE_DIR}) +find_program(CXXTEST_PERL_TESTGEN_EXECUTABLE cxxtestgen.pl + PATHS ${CXXTEST_INCLUDE_DIR}) + +if(PYTHONINTERP_FOUND OR PERL_FOUND) + include(FindPackageHandleStandardArgs) + + if(PYTHONINTERP_FOUND AND (CXXTEST_USE_PYTHON OR NOT PERL_FOUND)) + set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PYTHON_TESTGEN_EXECUTABLE}) + set(CXXTEST_TESTGEN_INTERPRETER ${PYTHON_EXECUTABLE}) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG + CXXTEST_INCLUDE_DIR CXXTEST_PYTHON_TESTGEN_EXECUTABLE) + + elseif(PERL_FOUND) + set(CXXTEST_TESTGEN_EXECUTABLE ${CXXTEST_PERL_TESTGEN_EXECUTABLE}) + set(CXXTEST_TESTGEN_INTERPRETER ${PERL_EXECUTABLE}) + FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG + CXXTEST_INCLUDE_DIR CXXTEST_PERL_TESTGEN_EXECUTABLE) + endif() + + if(CXXTEST_FOUND) + set(CXXTEST_INCLUDE_DIRS ${CXXTEST_INCLUDE_DIR}) + endif() + +else() -include(FindPackageHandleStandardArgs) -FIND_PACKAGE_HANDLE_STANDARD_ARGS(CxxTest DEFAULT_MSG CXXTEST_INCLUDE_DIR) + set(CXXTEST_FOUND false) + if(NOT CxxTest_FIND_QUIETLY) + if(CxxTest_FIND_REQUIRED) + message(FATAL_ERROR "Neither Python nor Perl found, cannot use CxxTest, aborting!") + else() + message(STATUS "Neither Python nor Perl found, CxxTest will not be used.") + endif() + endif() -set(CXXTEST_INCLUDE_DIRS ${CXXTEST_INCLUDE_DIR}) +endif() diff --git a/Modules/GetPrerequisites.cmake b/Modules/GetPrerequisites.cmake index 17b32f6..847db34 100644 --- a/Modules/GetPrerequisites.cmake +++ b/Modules/GetPrerequisites.cmake @@ -1,14 +1,16 @@ -# GetPrerequisites.cmake -# -# This script provides functions to list the .dll, .dylib or .so files that an -# executable or shared library file depends on. (Its prerequisites.) +# - Functions to analyze and list executable file prerequisites. +# This module provides functions to list the .dll, .dylib or .so +# files that an executable or shared library file depends on. (Its +# prerequisites.) # # It uses various tools to obtain the list of required shared library files: # dumpbin (Windows) # ldd (Linux/Unix) # otool (Mac OSX) -# -# The following functions are provided by this script: +# The following functions are provided by this module: +# get_prerequisites +# list_prerequisites +# list_prerequisites_by_glob # gp_append_unique # is_file_executable # gp_item_default_embedded_path @@ -18,12 +20,91 @@ # gp_resolved_file_type # (projects can override with gp_resolved_file_type_override) # gp_file_type -# get_prerequisites -# list_prerequisites -# list_prerequisites_by_glob -# # Requires CMake 2.6 or greater because it uses function, break, return and # PARENT_SCOPE. +# +# GET_PREREQUISITES(<target> <prerequisites_var> <exclude_system> <recurse> +# <dirs>) +# Get the list of shared library files required by <target>. The list in +# the variable named <prerequisites_var> should be empty on first entry to +# this function. On exit, <prerequisites_var> will contain the list of +# required shared library files. +# +# <target> is the full path to an executable file. <prerequisites_var> is the +# name of a CMake variable to contain the results. <exclude_system> must be 0 +# or 1 indicating whether to include or exclude "system" prerequisites. If +# <recurse> is set to 1 all prerequisites will be found recursively, if set to +# 0 only direct prerequisites are listed. <exepath> is the path to the top +# level executable used for @executable_path replacment on the Mac. <dirs> is +# a list of paths where libraries might be found: these paths are searched +# first when a target without any path info is given. Then standard system +# locations are also searched: PATH, Framework locations, /usr/lib... +# +# LIST_PREREQUISITES(<target> [<recurse> [<exclude_system> [<verbose>]]]) +# Print a message listing the prerequisites of <target>. +# +# <target> is the name of a shared library or executable target or the full +# path to a shared library or executable file. If <recurse> is set to 1 all +# prerequisites will be found recursively, if set to 0 only direct +# prerequisites are listed. <exclude_system> must be 0 or 1 indicating whether +# to include or exclude "system" prerequisites. With <verbose> set to 0 only +# the full path names of the prerequisites are printed, set to 1 extra +# informatin will be displayed. +# +# LIST_PREREQUISITES_BY_GLOB(<glob_arg> <glob_exp>) +# Print the prerequisites of shared library and executable files matching a +# globbing pattern. <glob_arg> is GLOB or GLOB_RECURSE and <glob_exp> is a +# globbing expression used with "file(GLOB" or "file(GLOB_RECURSE" to retrieve +# a list of matching files. If a matching file is executable, its prerequisites +# are listed. +# +# Any additional (optional) arguments provided are passed along as the +# optional arguments to the list_prerequisites calls. +# +# GP_APPEND_UNIQUE(<list_var> <value>) +# Append <value> to the list variable <list_var> only if the value is not +# already in the list. +# +# IS_FILE_EXECUTABLE(<file> <result_var>) +# Return 1 in <result_var> if <file> is a binary executable, 0 otherwise. +# +# GP_ITEM_DEFAULT_EMBEDDED_PATH(<item> <default_embedded_path_var>) +# Return the path that others should refer to the item by when the item +# is embedded inside a bundle. +# +# Override on a per-project basis by providing a project-specific +# gp_item_default_embedded_path_override function. +# +# GP_RESOLVE_ITEM(<context> <item> <exepath> <dirs> <resolved_item_var>) +# Resolve an item into an existing full path file. +# +# Override on a per-project basis by providing a project-specific +# gp_resolve_item_override function. +# +# GP_RESOLVED_FILE_TYPE(<original_file> <file> <exepath> <dirs> <type_var>) +# Return the type of <file> with respect to <original_file>. String +# describing type of prerequisite is returned in variable named <type_var>. +# +# Use <exepath> and <dirs> if necessary to resolve non-absolute <file> +# values -- but only for non-embedded items. +# +# Possible types are: +# system +# local +# embedded +# other +# Override on a per-project basis by providing a project-specific +# gp_resolved_file_type_override function. +# +# GP_FILE_TYPE(<original_file> <file> <type_var>) +# Return the type of <file> with respect to <original_file>. String +# describing type of prerequisite is returned in variable named <type_var>. +# +# Possible types are: +# system +# local +# embedded +# other #============================================================================= # Copyright 2008-2009 Kitware, Inc. @@ -38,11 +119,6 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -# gp_append_unique list_var value -# -# Append value to the list variable ${list_var} only if the value is not -# already in the list. -# function(gp_append_unique list_var value) set(contains 0) @@ -59,12 +135,6 @@ function(gp_append_unique list_var value) endfunction(gp_append_unique) -# is_file_executable file result_var -# -# Return 1 in ${result_var} if ${file} is a binary executable. -# -# Return 0 in ${result_var} otherwise. -# function(is_file_executable file result_var) # # A file is not executable until proven otherwise: @@ -132,14 +202,6 @@ function(is_file_executable file result_var) endfunction(is_file_executable) -# gp_item_default_embedded_path item default_embedded_path_var -# -# Return the path that others should refer to the item by when the item -# is embedded inside a bundle. -# -# Override on a per-project basis by providing a project-specific -# gp_item_default_embedded_path_override function. -# function(gp_item_default_embedded_path item default_embedded_path_var) # On Windows and Linux, "embed" prerequisites in the same directory @@ -193,13 +255,6 @@ function(gp_item_default_embedded_path item default_embedded_path_var) endfunction(gp_item_default_embedded_path) -# gp_resolve_item context item exepath dirs resolved_item_var -# -# Resolve an item into an existing full path file. -# -# Override on a per-project basis by providing a project-specific -# gp_resolve_item_override function. -# function(gp_resolve_item context item exepath dirs resolved_item_var) set(resolved 0) set(resolved_item "${item}") @@ -332,23 +387,6 @@ warning: cannot resolve item '${item}' endfunction(gp_resolve_item) -# gp_resolved_file_type original_file file exepath dirs type_var -# -# Return the type of ${file} with respect to ${original_file}. String -# describing type of prerequisite is returned in variable named ${type_var}. -# -# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file} -# values -- but only for non-embedded items. -# -# Possible types are: -# system -# local -# embedded -# other -# -# Override on a per-project basis by providing a project-specific -# gp_resolved_file_type_override function. -# function(gp_resolved_file_type original_file file exepath dirs type_var) #message(STATUS "**") @@ -445,17 +483,6 @@ function(gp_resolved_file_type original_file file exepath dirs type_var) endfunction() -# gp_file_type original_file file type_var -# -# Return the type of ${file} with respect to ${original_file}. String -# describing type of prerequisite is returned in variable named ${type_var}. -# -# Possible types are: -# system -# local -# embedded -# other -# function(gp_file_type original_file file type_var) if(NOT IS_ABSOLUTE "${original_file}") message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file") @@ -470,30 +497,6 @@ function(gp_file_type original_file file type_var) endfunction(gp_file_type) -# get_prerequisites target prerequisites_var exclude_system recurse dirs -# -# Get the list of shared library files required by ${target}. The list in -# the variable named ${prerequisites_var} should be empty on first entry to -# this function. On exit, ${prerequisites_var} will contain the list of -# required shared library files. -# -# target is the full path to an executable file -# -# prerequisites_var is the name of a CMake variable to contain the results -# -# exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to -# exclude them -# -# recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites -# recursively -# -# exepath is the path to the top level executable used for @executable_path -# replacment on the Mac -# -# dirs is a list of paths where libraries might be found: these paths are -# searched first when a target without any path info is given. Then standard -# system locations are also searched: PATH, Framework locations, /usr/lib... -# function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs) set(verbose 0) set(eol_char "E") @@ -717,19 +720,6 @@ function(get_prerequisites target prerequisites_var exclude_system recurse exepa endfunction(get_prerequisites) -# list_prerequisites target all exclude_system verbose -# -# ARGV0 (target) is the full path to an executable file -# -# optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only, -# 1 for all prerequisites recursively -# -# optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system" -# prerequisites , 1 to exclude them -# -# optional ARGV3 (verbose) is 0 or 1: 0 to print only full path -# names of prerequisites, 1 to print extra information -# function(list_prerequisites target) if("${ARGV1}" STREQUAL "") set(all 1) @@ -782,17 +772,6 @@ function(list_prerequisites target) endfunction(list_prerequisites) -# list_prerequisites_by_glob glob_arg glob_exp -# -# glob_arg is GLOB or GLOB_RECURSE -# -# glob_exp is a globbing expression used with "file(GLOB" to retrieve a list -# of matching files. If a matching file is executable, its prerequisites are -# listed. -# -# Any additional (optional) arguments provided are passed along as the -# optional arguments to the list_prerequisites calls. -# function(list_prerequisites_by_glob glob_arg glob_exp) message(STATUS "=============================================================================") message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'") diff --git a/Modules/Qt4Macros.cmake b/Modules/Qt4Macros.cmake index 10cf1d1..700d3a2 100644 --- a/Modules/Qt4Macros.cmake +++ b/Modules/Qt4Macros.cmake @@ -129,7 +129,11 @@ MACRO (QT4_GENERATE_MOC infile outfile ) # get include dirs and flags QT4_GET_MOC_FLAGS(moc_flags) GET_FILENAME_COMPONENT(abs_infile ${infile} ABSOLUTE) - QT4_CREATE_MOC_COMMAND(${abs_infile} ${outfile} "${moc_flags}" "") + SET(_outfile "${outfile}") + IF(NOT IS_ABSOLUTE "${outfile}") + SET(_outfile "${CMAKE_CURRENT_BINARY_DIR}/${outfile}") + ENDIF(NOT IS_ABSOLUTE "${outfile}") + QT4_CREATE_MOC_COMMAND(${abs_infile} ${_outfile} "${moc_flags}" "") SET_SOURCE_FILES_PROPERTIES(${outfile} PROPERTIES SKIP_AUTOMOC TRUE) # dont run automoc on this file ENDMACRO (QT4_GENERATE_MOC) @@ -187,10 +191,9 @@ MACRO (QT4_ADD_RESOURCES outfiles ) SET(_RC_DEPENDS) FOREACH(_RC_FILE ${_RC_FILES}) STRING(REGEX REPLACE "^<file[^>]*>" "" _RC_FILE "${_RC_FILE}") - STRING(REGEX MATCH "^/|([A-Za-z]:/)" _ABS_PATH_INDICATOR "${_RC_FILE}") - IF(NOT _ABS_PATH_INDICATOR) + IF(NOT IS_ABSOLUTE "${_RC_FILE}") SET(_RC_FILE "${rc_path}/${_RC_FILE}") - ENDIF(NOT _ABS_PATH_INDICATOR) + ENDIF(NOT IS_ABSOLUTE "${_RC_FILE}") SET(_RC_DEPENDS ${_RC_DEPENDS} "${_RC_FILE}") ENDFOREACH(_RC_FILE) ADD_CUSTOM_COMMAND(OUTPUT ${outfile} diff --git a/Source/CPack/cmCPackArchiveGenerator.cxx b/Source/CPack/cmCPackArchiveGenerator.cxx index 8799330..79ccdd9 100644 --- a/Source/CPack/cmCPackArchiveGenerator.cxx +++ b/Source/CPack/cmCPackArchiveGenerator.cxx @@ -22,11 +22,12 @@ #include <errno.h> #include <cmsys/SystemTools.hxx> +#include <cmsys/Directory.hxx> #include <cm_libarchive.h> //---------------------------------------------------------------------- -cmCPackArchiveGenerator::cmCPackArchiveGenerator(CompressType t, - ArchiveType at) +cmCPackArchiveGenerator::cmCPackArchiveGenerator(cmArchiveWrite::Compress t, + cmArchiveWrite::Type at) { this->Compress = t; this->Archive = at; @@ -37,222 +38,269 @@ cmCPackArchiveGenerator::~cmCPackArchiveGenerator() { } -static const size_t cmCPackTGZ_Data_BlockSize = 16384; - -// make this an anonymous namespace so that archive.h does not -// have to be included in the .h file for this class -namespace +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::InitializeInternal() { -bool SetArchiveType(struct archive* a, - cmCPackArchiveGenerator::CompressType ct, - cmCPackArchiveGenerator::ArchiveType at) + this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1"); + return this->Superclass::InitializeInternal(); +} +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::addOneComponentToArchive(cmArchiveWrite& archive, + cmCPackComponent* component) { - int res = 0; - // pick the archive type - switch(at) - { - case cmCPackArchiveGenerator::TAR: - // maybe this: - res = archive_write_set_format_pax_restricted(a); - break; - case cmCPackArchiveGenerator::ZIP: - res = archive_write_set_format_zip(a); - break; - } - if(res != ARCHIVE_OK) - { - return false; - } - - // pick a compression type - switch(ct) - { - case cmCPackArchiveGenerator::GZIP: - res = archive_write_set_compression_gzip(a); - break; - case cmCPackArchiveGenerator::BZIP2: - res = archive_write_set_compression_bzip2(a); - break; - case cmCPackArchiveGenerator::COMPRESS: - res = archive_write_set_compression_compress(a); - break; - case cmCPackArchiveGenerator::LZMA: - res = archive_write_set_compression_lzma(a); - break; - case cmCPackArchiveGenerator::NONE: - default: - res = archive_write_set_compression_none(a); - } - if(res != ARCHIVE_OK) - { - return false; - } - // do not pad the last block!! - res = archive_write_set_bytes_in_last_block(a, 1); - if(res != ARCHIVE_OK) + cmCPackLogger(cmCPackLog::LOG_VERBOSE, " - packaging component: " + << component->Name + << std::endl); + // Add the files of this component to the archive + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + localToplevel += "/"+ component->Name; + std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); + // Change to local toplevel + cmSystemTools::ChangeDirectory(localToplevel.c_str()); + std::vector<std::string>::const_iterator fileIt; + for (fileIt = component->Files.begin(); fileIt != component->Files.end(); ++fileIt ) { - return false; + cmCPackLogger(cmCPackLog::LOG_DEBUG,"Adding file: " << (*fileIt) << std::endl); + archive.Add(*fileIt); + if (!archive) + { + cmCPackLogger(cmCPackLog::LOG_ERROR, "ERROR while packaging files: " + << archive.GetError() + << std::endl); + return 0; + } } - - return true; + // Go back to previous dir + cmSystemTools::ChangeDirectory(dir.c_str()); + return 1; } - -struct StreamData -{ - StreamData(cmGeneratedFileStream* gfs, - cmCPackArchiveGenerator* ag) - { - this->GeneratedFileStream = gfs; - this->Generator = ag; - } - cmGeneratedFileStream* GeneratedFileStream; - cmCPackArchiveGenerator* Generator; -}; +/* + * The macro will open/create a file 'filename' + * an declare and open the associated + * cmArchiveWrite 'archive' object. + */ +#define DECLARE_AND_OPEN_ARCHIVE(filename,archive) \ +cmGeneratedFileStream gf; \ +gf.Open(filename.c_str(), false, true); \ +if (!GenerateHeader(&gf)) \ + { \ + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to generate Header for archive < " \ + << filename \ + << ">." << std::endl); \ + return 0; \ + } \ +cmArchiveWrite archive(gf,this->Compress, this->Archive); \ +if (!archive) \ + { \ + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem to create archive < " \ + << filename \ + << ">. ERROR =" \ + << archive.GetError() \ + << std::endl); \ + return 0; \ + } -extern "C" -{ -int OpenArchive(struct archive *, void *client_data) +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::PackageComponents(bool ignoreComponentGroup) { - struct StreamData *data = (StreamData*)client_data; - if(data->GeneratedFileStream && - *data->GeneratedFileStream) + packageFileNames.clear(); + // The default behavior is to have one package by component group + // unless CPACK_COMPONENTS_IGNORE_GROUP is specified. + if (!ignoreComponentGroup) { - if(data->Generator-> - GenerateHeader(data->GeneratedFileStream)) + std::map<std::string, cmCPackComponentGroup>::iterator compGIt; + for (compGIt=this->ComponentGroups.begin(); + compGIt!=this->ComponentGroups.end(); ++compGIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " + << compGIt->first + << std::endl); + // Begin the archive for this group + std::string packageFileName= std::string(toplevel); + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compGIt->first + this->GetOutputExtension(); + // open a block in order to automatically close archive + // at the end of the block { - return ARCHIVE_OK; + DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); + // now iterate over the component of this group + std::vector<cmCPackComponent*>::iterator compIt; + for (compIt=(compGIt->second).Components.begin(); + compIt!=(compGIt->second).Components.end(); + ++compIt) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,*compIt); + } + } + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); } } - return (ARCHIVE_FATAL); -} - -__LA_SSIZE_T WriteArchive(struct archive *, - void *client_data, - const void *buff, - size_t n) -{ - struct StreamData *data = (StreamData*)client_data; - data->GeneratedFileStream-> - write(reinterpret_cast<const char*>(buff),n); - if(!data->GeneratedFileStream->bad()) + // CPACK_COMPONENTS_IGNORE_GROUPS is set + // We build 1 package per component + else { - return n; + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin();compIt!=this->Components.end(); ++compIt ) + { + std::string localToplevel(this->GetOption("CPACK_TEMPORARY_DIRECTORY")); + std::string packageFileName = std::string(toplevel); + + localToplevel += "/"+ compIt->first; + packageFileName += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-"+compIt->first + this->GetOutputExtension(); + { + DECLARE_AND_OPEN_ARCHIVE(packageFileName,archive); + // Add the files of this component to the archive + addOneComponentToArchive(archive,&(compIt->second)); + } + // add the generated package to package file names list + packageFileNames.push_back(packageFileName); + } } - return 0; + return 1; } - -int CloseArchive(struct archive *, void *client_data) +//---------------------------------------------------------------------- +int cmCPackArchiveGenerator::PackageComponentsAllInOne(bool allComponentInOne) { - struct StreamData *data = (StreamData*)client_data; - if(data->GeneratedFileStream->Close()) + // reset the package file names + packageFileNames.clear(); + packageFileNames.push_back(std::string(toplevel)); + packageFileNames[0] += "/"+std::string(this->GetOption("CPACK_PACKAGE_FILE_NAME"))+"-ALL" + this->GetOutputExtension(); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging all groups in one package...(CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE is set)" + << std::endl); + DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); + + // The ALL GROUP in ONE package case + if (! allComponentInOne) { + // iterate over the component groups + std::map<std::string, cmCPackComponentGroup>::iterator compGIt; + for (compGIt=this->ComponentGroups.begin(); + compGIt!=this->ComponentGroups.end(); ++compGIt) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Packaging component group: " + << compGIt->first + << std::endl); + // now iterate over the component of this group + std::vector<cmCPackComponent*>::iterator compIt; + for (compIt=(compGIt->second).Components.begin(); + compIt!=(compGIt->second).Components.end(); + ++compIt) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,*compIt); + } + } + } + // The ALL COMPONENT in ONE package case + else { - delete data->GeneratedFileStream; - return ARCHIVE_OK; + std::map<std::string, cmCPackComponent>::iterator compIt; + for (compIt=this->Components.begin();compIt!=this->Components.end(); ++compIt ) + { + // Add the files of this component to the archive + addOneComponentToArchive(archive,&(compIt->second)); + } } - return ARCHIVE_FATAL; + // archive goes out of scope so it will finalized and closed. + return 1; } -} //extern C -} // anon name space - //---------------------------------------------------------------------- -int cmCPackArchiveGenerator::InitializeInternal() -{ - this->SetOptionIfNotSet("CPACK_INCLUDE_TOPLEVEL_DIRECTORY", "1"); - return this->Superclass::InitializeInternal(); -} - int cmCPackArchiveGenerator::PackageFiles() { - int res = ARCHIVE_OK; -#define CHECK_ARCHIVE_ERROR(res, msg) \ - if(res != ARCHIVE_OK) \ - {\ - cmCPackLogger(cmCPackLog::LOG_ERROR, msg \ - << archive_error_string(a) \ - << cmSystemTools::GetLastSystemError() \ - << " " << res \ - << "\n"); \ - } cmCPackLogger(cmCPackLog::LOG_DEBUG, "Toplevel: " << toplevel << std::endl); - // create a new archive - struct archive* a = archive_write_new(); - // Set the compress and archive types for the archive - SetArchiveType(a, this->Compress, this->Archive); - // Open binary stream - cmGeneratedFileStream* gf = new cmGeneratedFileStream; - gf->Open(packageFileNames[0].c_str(), false, true); - StreamData data(gf, this); - // pass callbacks to archive_write_open to handle stream - res = archive_write_open(a, - &data, - OpenArchive, - WriteArchive, - CloseArchive); - CHECK_ARCHIVE_ERROR(res, "archive_write_open:"); - // create a new disk struct - struct archive* disk = archive_read_disk_new(); -#if !defined(_WIN32) || defined(__CYGWIN__) - res = archive_read_disk_set_standard_lookup(disk); -#endif - CHECK_ARCHIVE_ERROR(res, "archive_read_disk_set_standard_lookup:"); + // The default behavior is to create 1 package by component group + // unless the user asked to put all COMPONENTS in a single package + bool allGroupInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_GROUPS_IN_ONE_PACKAGE"))); + bool allComponentInOne = (NULL != (this->GetOption("CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE"))); + bool ignoreComponentGroup = ( NULL != (this->GetOption("CPACK_COMPONENTS_IGNORE_GROUPS"))); + + std::string groupingType; + + // Second way to specify grouping + if (NULL != this->GetOption("CPACK_COMPONENTS_GROUPING")) { + groupingType = this->GetOption("CPACK_COMPONENTS_GROUPING"); + } + + if (groupingType.length()>0) + { + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "[" + << this->Name << "]" + << " requested component grouping = "<< groupingType <<std::endl); + if (groupingType == "ALL_GROUP_IN_ONE") + { + allGroupInOne = true; + } + else if (groupingType == "ALL_COMPONENT_IN_ONE") + { + allComponentInOne = true; + } + else if (groupingType == "IGNORE") + { + ignoreComponentGroup = true; + } + else + { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " requested component grouping type <"<< groupingType + << "> UNKNOWN not in (ALL_GROUP_IN_ONE,ALL_COMPONENT_IN_ONE,IGNORE)" <<std::endl); + } + } + + // Some components were defined but NO group + // force ignoreGroups + if (this->ComponentGroups.empty() && (!this->Components.empty()) && (!ignoreComponentGroup)) { + cmCPackLogger(cmCPackLog::LOG_WARNING, "[" + << this->Name << "]" + << " Some Components defined but NO component group:" + << " Ignoring component group." + << std::endl); + ignoreComponentGroup = true; + } + // CASE 1 : COMPONENT ALL-IN-ONE package + // If ALL GROUPS or ALL COMPONENTS in ONE package has been requested + // then the package file is unique and should be open here. + if (allComponentInOne || (allGroupInOne && (!this->ComponentGroups.empty()))) + { + return PackageComponentsAllInOne(allComponentInOne); + } + // CASE 2 : COMPONENT CLASSICAL package(s) (i.e. not all-in-one) + // There will be 1 package for each component group + // however one may require to ignore component group and + // in this case you'll get 1 package for each component. + else if ((!this->ComponentGroups.empty()) || (ignoreComponentGroup)) + { + return PackageComponents(ignoreComponentGroup); + } + + // CASE 3 : NON COMPONENT package. + DECLARE_AND_OPEN_ARCHIVE(packageFileNames[0],archive); std::vector<std::string>::const_iterator fileIt; std::string dir = cmSystemTools::GetCurrentWorkingDirectory(); cmSystemTools::ChangeDirectory(toplevel.c_str()); for ( fileIt = files.begin(); fileIt != files.end(); ++ fileIt ) { - // create a new entry for each file - struct archive_entry *entry = archive_entry_new(); // Get the relative path to the file std::string rp = cmSystemTools::RelativePath(toplevel.c_str(), fileIt->c_str()); - // Set the name of the entry to the file name - archive_entry_set_pathname(entry, rp.c_str()); - res = archive_read_disk_entry_from_file(disk, entry, -1, 0); - CHECK_ARCHIVE_ERROR(res, "archive_read_disk_entry_from_file:"); - // write entry header - res = archive_write_header(a, entry); - CHECK_ARCHIVE_ERROR(res, "archive_write_header:"); - // the entry size can be 0 if it is a symlink - if(archive_entry_size(entry) > 0) + archive.Add(rp); + if(!archive) { - // now copy contents of file into archive a - FILE* file = fopen(fileIt->c_str(), "rb"); - if(!file) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem with fopen(): " - << fileIt->c_str() - << strerror(errno) - << std::endl); - return 0; - } - char buff[cmCPackTGZ_Data_BlockSize]; - size_t len = fread(buff, 1, sizeof(buff), file); - while (len > 0) - { - size_t wlen = archive_write_data(a, buff, len); - if(wlen != len) - { - cmCPackLogger(cmCPackLog::LOG_ERROR, "archive_write_data(): " - << "tried to write " << len << "\n" - << "write " << wlen << "\n"); - return 0; - } - len = fread(buff, 1, sizeof(buff), file); - } - // close the file and free the entry - fclose(file); + cmCPackLogger(cmCPackLog::LOG_ERROR, "Problem while adding file< " + << *fileIt + << "> to archive <" + << packageFileNames[0] << "> .ERROR =" + << archive.GetError() + << std::endl); + return 0; } - archive_entry_free(entry); } cmSystemTools::ChangeDirectory(dir.c_str()); - // close the archive and finish the write - archive_write_close(a); - archive_write_finish(a); - archive_read_finish(disk); + // The destructor of cmArchiveWrite will close and finish the write return 1; } @@ -261,3 +309,7 @@ int cmCPackArchiveGenerator::GenerateHeader(std::ostream*) { return 1; } + +bool cmCPackArchiveGenerator::SupportsComponentInstallation() const { + return true; +} diff --git a/Source/CPack/cmCPackArchiveGenerator.h b/Source/CPack/cmCPackArchiveGenerator.h index d3409ae..ae545c8 100644 --- a/Source/CPack/cmCPackArchiveGenerator.h +++ b/Source/CPack/cmCPackArchiveGenerator.h @@ -13,34 +13,61 @@ #ifndef cmCPackArchiveGenerator_h #define cmCPackArchiveGenerator_h +#include "cmArchiveWrite.h" #include "cmCPackGenerator.h" /** \class cmCPackArchiveGenerator - * \brief A generator base for libarchive generation + * \brief A generator base for libarchive generation. + * The generator itself uses the libarchive wrapper + * \ref cmArchiveWrite. * */ class cmCPackArchiveGenerator : public cmCPackGenerator -{ + { public: - enum CompressType{ GZIP, BZIP2, COMPRESS, LZMA, NONE}; - enum ArchiveType{ TAR, ZIP}; cmTypeMacro(cmCPackArchiveGenerator, cmCPackGenerator); /** * Construct generator */ - cmCPackArchiveGenerator(CompressType, ArchiveType); + cmCPackArchiveGenerator(cmArchiveWrite::Compress, cmArchiveWrite::Type); virtual ~cmCPackArchiveGenerator(); // Used to add a header to the archive virtual int GenerateHeader(std::ostream* os); - + // component support + virtual bool SupportsComponentInstallation() const; protected: virtual int InitializeInternal(); + /** + * Add the files belonging to the specified component + * to the provided (already opened) archive. + * @param[in,out] archive the archive object + * @param[in] component the component whose file will be added to archive + */ + int addOneComponentToArchive(cmArchiveWrite& archive, cmCPackComponent* component); + + /** + * The main package file method. + * If component install was required this + * method will call either PackageComponents or + * PackageComponentsAllInOne. + */ int PackageFiles(); + /** + * The method used to package files when component + * install is used. This will create one + * archive for each component group. + */ + int PackageComponents(bool ignoreComponentGroup); + /** + * Special case of component install where all + * components will be put in a single installer. + */ + int PackageComponentsAllInOne(bool allComponentInOne); virtual const char* GetOutputExtension() = 0; - CompressType Compress; - ArchiveType Archive; -}; + cmArchiveWrite::Compress Compress; + cmArchiveWrite::Type Archive; + }; #endif diff --git a/Source/CPack/cmCPackCygwinSourceGenerator.cxx b/Source/CPack/cmCPackCygwinSourceGenerator.cxx index f4ae35f..5979729 100644 --- a/Source/CPack/cmCPackCygwinSourceGenerator.cxx +++ b/Source/CPack/cmCPackCygwinSourceGenerator.cxx @@ -59,7 +59,7 @@ int cmCPackCygwinSourceGenerator::PackageFiles() // skip one parent up to the cmCPackTarBZip2Generator // to create tar.bz2 file with the list of source // files - this->Compress = BZIP2; + this->Compress = cmArchiveWrite::CompressBZip2; if ( !this->cmCPackTarBZip2Generator::PackageFiles() ) { return 0; diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx index 58c6dc3..ac2e151 100644 --- a/Source/CPack/cmCPackDebGenerator.cxx +++ b/Source/CPack/cmCPackDebGenerator.cxx @@ -43,7 +43,10 @@ cmCPackDebGenerator::~cmCPackDebGenerator() int cmCPackDebGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr"); - + if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) + { + this->SetOption("CPACK_SET_DESTDIR", "I_ON"); + } return this->Superclass::InitializeInternal(); } diff --git a/Source/CPack/cmCPackGenerator.cxx b/Source/CPack/cmCPackGenerator.cxx index 4ae2d1f..0abb0ff 100644 --- a/Source/CPack/cmCPackGenerator.cxx +++ b/Source/CPack/cmCPackGenerator.cxx @@ -171,7 +171,8 @@ int cmCPackGenerator::InstallProject() std::string bareTempInstallDirectory = this->GetOption("CPACK_TEMPORARY_INSTALL_DIRECTORY"); std::string tempInstallDirectoryStr = bareTempInstallDirectory; - bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR")); + bool setDestDir = cmSystemTools::IsOn(this->GetOption("CPACK_SET_DESTDIR")) + | cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR")); if (!setDestDir) { tempInstallDirectoryStr += this->GetPackagingInstallPrefix(); @@ -414,7 +415,8 @@ int cmCPackGenerator::InstallProjectViaInstallScript( // underneath the tempInstallDirectory. The value of the project's // CMAKE_INSTALL_PREFIX is sent in here as the value of the // CPACK_INSTALL_PREFIX variable. - std::string dir; + + std::string dir; if (this->GetOption("CPACK_INSTALL_PREFIX")) { dir += this->GetOption("CPACK_INSTALL_PREFIX"); @@ -459,6 +461,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( = this->GetOption("CPACK_INSTALL_CMAKE_PROJECTS"); const char* cmakeGenerator = this->GetOption("CPACK_CMAKE_GENERATOR"); + std::string absoluteDestFiles; if ( cmakeProjects && *cmakeProjects ) { if ( !cmakeGenerator ) @@ -643,6 +646,16 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( // value of the project's CMAKE_INSTALL_PREFIX is sent in here as // the value of the CPACK_INSTALL_PREFIX variable. // + // If DESTDIR has been 'internally set ON' this means that + // the underlying CPack specific generator did ask for that + // In this case we may overrode CPACK_INSTALL_PREFIX with + // CPACK_PACKAGING_INSTALL_PREFIX + // I know this is tricky and awkward but it's the price for + // CPACK_SET_DESTDIR backward compatibility. + if (cmSystemTools::IsInternallyOn(this->GetOption("CPACK_SET_DESTDIR"))) + { + this->SetOption("CPACK_INSTALL_PREFIX",this->GetOption("CPACK_PACKAGING_INSTALL_PREFIX")); + } std::string dir; if (this->GetOption("CPACK_INSTALL_PREFIX")) { @@ -723,6 +736,15 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( mf->AddDefinition("CMAKE_INSTALL_DO_STRIP", "1"); } int res = mf->ReadListFile(0, installFile.c_str()); + if (NULL !=mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES")) { + if (absoluteDestFiles.length()>0) { + absoluteDestFiles +=";"; + } + absoluteDestFiles += mf->GetDefinition("CPACK_ABSOLUTE_DESTINATION_FILES"); + cmCPackLogger(cmCPackLog::LOG_DEBUG, + "Got some ABSOLUTE DESTINATION FILES: " + << absoluteDestFiles << std::endl); + } if ( cmSystemTools::GetErrorOccuredFlag() || !res ) { return 0; @@ -730,6 +752,7 @@ int cmCPackGenerator::InstallProjectViaInstallCMakeProjects( } } } + this->SetOption("CPACK_ABSOLUTE_DESTINATION_FILES",absoluteDestFiles.c_str()); return 1; } @@ -828,8 +851,8 @@ int cmCPackGenerator::DoPackage() return 0; } - cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Compress package" << std::endl); - cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Compress files to: " + cmCPackLogger(cmCPackLog::LOG_OUTPUT, "Create package" << std::endl); + cmCPackLogger(cmCPackLog::LOG_VERBOSE, "Package files to: " << (tempPackageFileName ? tempPackageFileName : "(NULL)") << std::endl); if ( cmSystemTools::FileExists(tempPackageFileName) ) { @@ -853,7 +876,10 @@ int cmCPackGenerator::DoPackage() std::vector<std::string>::const_iterator it; for ( it = files.begin(); it != files.end(); ++ it ) { - std::string fileN = cmSystemTools::RelativePath(tempDirectory, + // beware we cannot just use tempDirectory as before + // because some generator will "CPACK_INCLUDE_TOPLEVEL_DIRECTORY" + // we really want "CPACK_TEMPORARY_DIRECTORY" + std::string fileN = cmSystemTools::RelativePath(this->GetOption("CPACK_TEMPORARY_DIRECTORY"), it->c_str()); // Determine which component we are in. @@ -864,6 +890,7 @@ int cmCPackGenerator::DoPackage() // Add this file to the list of files for the component. this->Components[componentName].Files.push_back(fileN); + cmCPackLogger(cmCPackLog::LOG_DEBUG, "Adding file <" <<fileN<<"> to component <"<<componentName<<">"<<std::endl); } } diff --git a/Source/CPack/cmCPackRPMGenerator.cxx b/Source/CPack/cmCPackRPMGenerator.cxx index 01b6b06..0641418 100644 --- a/Source/CPack/cmCPackRPMGenerator.cxx +++ b/Source/CPack/cmCPackRPMGenerator.cxx @@ -11,6 +11,7 @@ ============================================================================*/ #include "cmCPackRPMGenerator.h" #include "cmCPackLog.h" +#include "cmSystemTools.h" //---------------------------------------------------------------------- cmCPackRPMGenerator::cmCPackRPMGenerator() @@ -26,7 +27,10 @@ cmCPackRPMGenerator::~cmCPackRPMGenerator() int cmCPackRPMGenerator::InitializeInternal() { this->SetOptionIfNotSet("CPACK_PACKAGING_INSTALL_PREFIX", "/usr"); - + if (cmSystemTools::IsOff(this->GetOption("CPACK_SET_DESTDIR"))) + { + this->SetOption("CPACK_SET_DESTDIR", "I_ON"); + } return this->Superclass::InitializeInternal(); } diff --git a/Source/CPack/cmCPackTGZGenerator.cxx b/Source/CPack/cmCPackTGZGenerator.cxx index c6ef8ae..509c7f8 100644 --- a/Source/CPack/cmCPackTGZGenerator.cxx +++ b/Source/CPack/cmCPackTGZGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackTGZGenerator::cmCPackTGZGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::GZIP, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressGZip, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackTarBZip2Generator.cxx b/Source/CPack/cmCPackTarBZip2Generator.cxx index 52826dc..971d166 100644 --- a/Source/CPack/cmCPackTarBZip2Generator.cxx +++ b/Source/CPack/cmCPackTarBZip2Generator.cxx @@ -13,8 +13,8 @@ #include "cmCPackTarBZip2Generator.h" //---------------------------------------------------------------------- cmCPackTarBZip2Generator::cmCPackTarBZip2Generator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::BZIP2, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressBZip2, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackTarCompressGenerator.cxx b/Source/CPack/cmCPackTarCompressGenerator.cxx index e9b5e2e..7a8f697 100644 --- a/Source/CPack/cmCPackTarCompressGenerator.cxx +++ b/Source/CPack/cmCPackTarCompressGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackTarCompressGenerator::cmCPackTarCompressGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::COMPRESS, - cmCPackArchiveGenerator::TAR) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressCompress, + cmArchiveWrite::TypeTAR) { } diff --git a/Source/CPack/cmCPackZIPGenerator.cxx b/Source/CPack/cmCPackZIPGenerator.cxx index e195f83..e6e4e77 100644 --- a/Source/CPack/cmCPackZIPGenerator.cxx +++ b/Source/CPack/cmCPackZIPGenerator.cxx @@ -14,8 +14,8 @@ //---------------------------------------------------------------------- cmCPackZIPGenerator::cmCPackZIPGenerator() - :cmCPackArchiveGenerator(cmCPackArchiveGenerator::NONE, - cmCPackArchiveGenerator::ZIP) + :cmCPackArchiveGenerator(cmArchiveWrite::CompressNone, + cmArchiveWrite::TypeZIP) { } diff --git a/Source/cmComputeComponentGraph.cxx b/Source/cmComputeComponentGraph.cxx index 3f2a361..5bec6a1 100644 --- a/Source/cmComputeComponentGraph.cxx +++ b/Source/cmComputeComponentGraph.cxx @@ -71,8 +71,8 @@ void cmComputeComponentGraph::TarjanVisit(int i) this->TarjanStack.push(i); // Follow outgoing edges. - NodeList const& nl = this->InputGraph[i]; - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + EdgeList const& nl = this->InputGraph[i]; + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int j = *ni; @@ -142,14 +142,17 @@ void cmComputeComponentGraph::TransferEdges() for(int i=0; i < n; ++i) { int i_component = this->TarjanComponents[i]; - NodeList const& nl = this->InputGraph[i]; - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + EdgeList const& nl = this->InputGraph[i]; + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int j = *ni; int j_component = this->TarjanComponents[j]; if(i_component != j_component) { - this->ComponentGraph[i_component].push_back(j_component); + // We do not attempt to combine duplicate edges, but instead + // store the inter-component edges with suitable multiplicity. + this->ComponentGraph[i_component].push_back( + cmGraphEdge(j_component, ni->IsStrong())); } } } diff --git a/Source/cmComputeComponentGraph.h b/Source/cmComputeComponentGraph.h index 855a141..a2ce946 100644 --- a/Source/cmComputeComponentGraph.h +++ b/Source/cmComputeComponentGraph.h @@ -33,6 +33,7 @@ class cmComputeComponentGraph public: // Represent the graph with an adjacency list. typedef cmGraphNodeList NodeList; + typedef cmGraphEdgeList EdgeList; typedef cmGraphAdjacencyList Graph; cmComputeComponentGraph(Graph const& input); @@ -41,7 +42,7 @@ public: /** Get the adjacency list of the component graph. */ Graph const& GetComponentGraph() const { return this->ComponentGraph; } - NodeList const& GetComponentGraphEdges(int c) const + EdgeList const& GetComponentGraphEdges(int c) const { return this->ComponentGraph[c]; } /** Get map from component index to original node indices. */ diff --git a/Source/cmComputeLinkDepends.cxx b/Source/cmComputeLinkDepends.cxx index 24410ec..342c217 100644 --- a/Source/cmComputeLinkDepends.cxx +++ b/Source/cmComputeLinkDepends.cxx @@ -285,7 +285,7 @@ cmComputeLinkDepends::AllocateLinkEntry(std::string const& item) lei = this->LinkEntryIndex.insert(index_entry).first; this->EntryList.push_back(LinkEntry()); this->InferredDependSets.push_back(0); - this->EntryConstraintGraph.push_back(NodeList()); + this->EntryConstraintGraph.push_back(EdgeList()); return lei; } @@ -669,7 +669,7 @@ void cmComputeLinkDepends::CleanConstraintGraph() cmsys_stl::sort(i->begin(), i->end()); // Make the edge list unique. - NodeList::iterator last = cmsys_stl::unique(i->begin(), i->end()); + EdgeList::iterator last = cmsys_stl::unique(i->begin(), i->end()); i->erase(last, i->end()); } } @@ -681,9 +681,9 @@ void cmComputeLinkDepends::DisplayConstraintGraph() cmOStringStream e; for(unsigned int i=0; i < this->EntryConstraintGraph.size(); ++i) { - NodeList const& nl = this->EntryConstraintGraph[i]; + EdgeList const& nl = this->EntryConstraintGraph[i]; e << "item " << i << " is [" << this->EntryList[i].Item << "]\n"; - for(NodeList::const_iterator j = nl.begin(); j != nl.end(); ++j) + for(EdgeList::const_iterator j = nl.begin(); j != nl.end(); ++j) { e << " item " << *j << " must follow it\n"; } @@ -758,10 +758,11 @@ cmComputeLinkDepends::DisplayComponents() fprintf(stderr, " item %d [%s]\n", i, this->EntryList[i].Item.c_str()); } - NodeList const& ol = this->CCG->GetComponentGraphEdges(c); - for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) + EdgeList const& ol = this->CCG->GetComponentGraphEdges(c); + for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) { - fprintf(stderr, " followed by Component (%d)\n", *oi); + int i = *oi; + fprintf(stderr, " followed by Component (%d)\n", i); } fprintf(stderr, " topo order index %d\n", this->ComponentOrder[c]); @@ -784,8 +785,8 @@ void cmComputeLinkDepends::VisitComponent(unsigned int c) // Visit the neighbors of the component first. // Run in reverse order so the topological order will preserve the // original order where there are no constraints. - NodeList const& nl = this->CCG->GetComponentGraphEdges(c); - for(NodeList::const_reverse_iterator ni = nl.rbegin(); + EdgeList const& nl = this->CCG->GetComponentGraphEdges(c); + for(EdgeList::const_reverse_iterator ni = nl.rbegin(); ni != nl.rend(); ++ni) { this->VisitComponent(*ni); @@ -856,8 +857,8 @@ void cmComputeLinkDepends::VisitEntry(int index) // are now pending. if(completed) { - NodeList const& ol = this->CCG->GetComponentGraphEdges(component); - for(NodeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) + EdgeList const& ol = this->CCG->GetComponentGraphEdges(component); + for(EdgeList::const_iterator oi = ol.begin(); oi != ol.end(); ++oi) { // This entire component is now pending no matter whether it has // been partially seen already. diff --git a/Source/cmComputeLinkDepends.h b/Source/cmComputeLinkDepends.h index a08afb6..e196e00 100644 --- a/Source/cmComputeLinkDepends.h +++ b/Source/cmComputeLinkDepends.h @@ -117,6 +117,7 @@ private: // Ordering constraint graph adjacency list. typedef cmGraphNodeList NodeList; + typedef cmGraphEdgeList EdgeList; typedef cmGraphAdjacencyList Graph; Graph EntryConstraintGraph; void CleanConstraintGraph(); diff --git a/Source/cmComputeTargetDepends.cxx b/Source/cmComputeTargetDepends.cxx index 94b8527..313c680 100644 --- a/Source/cmComputeTargetDepends.cxx +++ b/Source/cmComputeTargetDepends.cxx @@ -129,7 +129,10 @@ bool cmComputeTargetDepends::Compute() } // Compute the final dependency graph. - this->ComputeFinalDepends(ccg); + if(!this->ComputeFinalDepends(ccg)) + { + return false; + } if(this->DebugMode) { this->DisplayGraph(this->FinalGraph, "final"); @@ -150,8 +153,8 @@ cmComputeTargetDepends::GetTargetDirectDepends(cmTarget* t, int i = tii->second; // Get its final dependencies. - NodeList const& nl = this->FinalGraph[i]; - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + EdgeList const& nl = this->FinalGraph[i]; + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { deps.insert(this->Targets[*ni]); } @@ -195,15 +198,13 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) // Get the depender. cmTarget* depender = this->Targets[depender_index]; - // Keep track of dependencies already listed. - std::set<cmStdString> emitted; - - // A target should not depend on itself. - emitted.insert(depender->GetName()); - // Loop over all targets linked directly. + { cmTarget::LinkLibraryVectorType const& tlibs = depender->GetOriginalLinkLibraries(); + std::set<cmStdString> emitted; + // A target should not depend on itself. + emitted.insert(depender->GetName()); for(cmTarget::LinkLibraryVectorType::const_iterator lib = tlibs.begin(); lib != tlibs.end(); ++lib) { @@ -213,9 +214,14 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) this->AddTargetDepend(depender_index, lib->first.c_str(), true); } } + } // Loop over all utility dependencies. + { std::set<cmStdString> const& tutils = depender->GetUtilities(); + std::set<cmStdString> emitted; + // A target should not depend on itself. + emitted.insert(depender->GetName()); for(std::set<cmStdString>::const_iterator util = tutils.begin(); util != tutils.end(); ++util) { @@ -225,6 +231,7 @@ void cmComputeTargetDepends::CollectTargetDepends(int depender_index) this->AddTargetDepend(depender_index, util->c_str(), false); } } + } } //---------------------------------------------------------------------------- @@ -272,7 +279,8 @@ void cmComputeTargetDepends::AddTargetDepend(int depender_index, int dependee_index = tii->second; // Add this entry to the dependency graph. - this->InitialGraph[depender_index].push_back(dependee_index); + this->InitialGraph[depender_index].push_back( + cmGraphEdge(dependee_index, !linking)); } //---------------------------------------------------------------------------- @@ -283,16 +291,16 @@ cmComputeTargetDepends::DisplayGraph(Graph const& graph, const char* name) int n = static_cast<int>(graph.size()); for(int depender_index = 0; depender_index < n; ++depender_index) { - NodeList const& nl = graph[depender_index]; + EdgeList const& nl = graph[depender_index]; cmTarget* depender = this->Targets[depender_index]; fprintf(stderr, "target %d is [%s]\n", depender_index, depender->GetName()); - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int dependee_index = *ni; cmTarget* dependee = this->Targets[dependee_index]; - fprintf(stderr, " depends on target %d [%s]\n", dependee_index, - dependee->GetName()); + fprintf(stderr, " depends on target %d [%s] (%s)\n", dependee_index, + dependee->GetName(), ni->IsStrong()? "strong" : "weak"); } } fprintf(stderr, "\n"); @@ -363,7 +371,8 @@ cmComputeTargetDepends //---------------------------------------------------------------------------- void cmComputeTargetDepends -::ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c) +::ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c, + bool strong) { // Construct the error message. cmOStringStream e; @@ -383,18 +392,27 @@ cmComputeTargetDepends << cmTarget::TargetTypeNames[depender->GetType()] << "\n"; // List its dependencies that are inside the component. - NodeList const& nl = this->InitialGraph[i]; - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + EdgeList const& nl = this->InitialGraph[i]; + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int j = *ni; if(cmap[j] == c) { cmTarget* dependee = this->Targets[j]; - e << " depends on \"" << dependee->GetName() << "\"\n"; + e << " depends on \"" << dependee->GetName() << "\"" + << " (" << (ni->IsStrong()? "strong" : "weak") << ")\n"; } } } - if(this->NoCycles) + if(strong) + { + // Custom command executable dependencies cannot occur within a + // component of static libraries. The cycle must appear in calls + // to add_dependencies. + e << "The component contains at least one cycle consisting of strong " + << "dependencies (created by add_dependencies) that cannot be broken."; + } + else if(this->NoCycles) { e << "The GLOBAL_DEPENDS_NO_CYCLES global property is enabled, so " << "cyclic dependencies are not allowed even among static libraries."; @@ -408,7 +426,49 @@ cmComputeTargetDepends } //---------------------------------------------------------------------------- -void +bool +cmComputeTargetDepends +::IntraComponent(std::vector<int> const& cmap, int c, int i, int* head, + std::set<int>& emitted, std::set<int>& visited) +{ + if(!visited.insert(i).second) + { + // Cycle in utility depends! + return false; + } + if(emitted.insert(i).second) + { + // Honor strong intra-component edges in the final order. + EdgeList const& el = this->InitialGraph[i]; + for(EdgeList::const_iterator ei = el.begin(); ei != el.end(); ++ei) + { + int j = *ei; + if(cmap[j] == c && ei->IsStrong()) + { + this->FinalGraph[i].push_back(j); + if(!this->IntraComponent(cmap, c, j, head, emitted, visited)) + { + return false; + } + } + } + + // Prepend to a linear linked-list of intra-component edges. + if(*head >= 0) + { + this->FinalGraph[i].push_back(*head); + } + else + { + this->ComponentTail[c] = i; + } + *head = i; + } + return true; +} + +//---------------------------------------------------------------------------- +bool cmComputeTargetDepends ::ComputeFinalDepends(cmComputeComponentGraph const& ccg) { @@ -420,34 +480,43 @@ cmComputeTargetDepends this->FinalGraph.resize(0); this->FinalGraph.resize(this->InitialGraph.size()); + // Choose intra-component edges to linearize dependencies. + std::vector<int> const& cmap = ccg.GetComponentMap(); + this->ComponentHead.resize(components.size()); + this->ComponentTail.resize(components.size()); + int nc = static_cast<int>(components.size()); + for(int c=0; c < nc; ++c) + { + int head = -1; + std::set<int> emitted; + NodeList const& nl = components[c]; + for(NodeList::const_reverse_iterator ni = nl.rbegin(); + ni != nl.rend(); ++ni) + { + std::set<int> visited; + if(!this->IntraComponent(cmap, c, *ni, &head, emitted, visited)) + { + // Cycle in add_dependencies within component! + this->ComplainAboutBadComponent(ccg, c, true); + return false; + } + } + this->ComponentHead[c] = head; + } + // Convert inter-component edges to connect component tails to heads. int n = static_cast<int>(cgraph.size()); for(int depender_component=0; depender_component < n; ++depender_component) { - int depender_component_tail = components[depender_component].back(); - NodeList const& nl = cgraph[depender_component]; - for(NodeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) + int depender_component_tail = this->ComponentTail[depender_component]; + EdgeList const& nl = cgraph[depender_component]; + for(EdgeList::const_iterator ni = nl.begin(); ni != nl.end(); ++ni) { int dependee_component = *ni; - int dependee_component_head = components[dependee_component].front(); + int dependee_component_head = this->ComponentHead[dependee_component]; this->FinalGraph[depender_component_tail] .push_back(dependee_component_head); } } - - // Compute intra-component edges. - int nc = static_cast<int>(components.size()); - for(int c=0; c < nc; ++c) - { - // Within the component each target depends on that following it. - NodeList const& nl = components[c]; - NodeList::const_iterator ni = nl.begin(); - int last_i = *ni; - for(++ni; ni != nl.end(); ++ni) - { - int i = *ni; - this->FinalGraph[last_i].push_back(i); - last_i = i; - } - } + return true; } diff --git a/Source/cmComputeTargetDepends.h b/Source/cmComputeTargetDepends.h index 68e3e47..240de76 100644 --- a/Source/cmComputeTargetDepends.h +++ b/Source/cmComputeTargetDepends.h @@ -45,7 +45,7 @@ private: void CollectTargetDepends(int depender_index); void AddTargetDepend(int depender_index, const char* dependee_name, bool linking); - void ComputeFinalDepends(cmComputeComponentGraph const& ccg); + bool ComputeFinalDepends(cmComputeComponentGraph const& ccg); cmGlobalGenerator* GlobalGenerator; bool DebugMode; @@ -59,6 +59,7 @@ private: // top-level index corresponds to a depender whose dependencies are // listed. typedef cmGraphNodeList NodeList; + typedef cmGraphEdgeList EdgeList; typedef cmGraphAdjacencyList Graph; Graph InitialGraph; Graph FinalGraph; @@ -67,7 +68,13 @@ private: // Deal with connected components. void DisplayComponents(cmComputeComponentGraph const& ccg); bool CheckComponents(cmComputeComponentGraph const& ccg); - void ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c); + void ComplainAboutBadComponent(cmComputeComponentGraph const& ccg, int c, + bool strong = false); + + std::vector<int> ComponentHead; + std::vector<int> ComponentTail; + bool IntraComponent(std::vector<int> const& cmap, int c, int i, int* head, + std::set<int>& emitted, std::set<int>& visited); }; #endif diff --git a/Source/cmFindPackageCommand.cxx b/Source/cmFindPackageCommand.cxx index eb86014..5c05ecb 100644 --- a/Source/cmFindPackageCommand.cxx +++ b/Source/cmFindPackageCommand.cxx @@ -1083,6 +1083,20 @@ void cmFindPackageCommand::AppendSuccessInformation() } } + // set a global property to record the required version of this package + std::string versionInfoPropName = "_CMAKE_"; + versionInfoPropName += this->Name; + versionInfoPropName += "_REQUIRED_VERSION"; + std::string versionInfo; + if(!this->Version.empty()) + { + versionInfo = this->VersionExact ? "==" : ">="; + versionInfo += " "; + versionInfo += this->Version; + } + this->Makefile->GetCMakeInstance()->SetProperty(versionInfoPropName.c_str(), + versionInfo.c_str()); + // Restore original state of "_FIND_" variables we set. this->RestoreFindDefinitions(); } diff --git a/Source/cmGlobalGenerator.cxx b/Source/cmGlobalGenerator.cxx index bd26b5f..fbc578b 100644 --- a/Source/cmGlobalGenerator.cxx +++ b/Source/cmGlobalGenerator.cxx @@ -1487,7 +1487,7 @@ void cmGlobalGenerator::FillLocalGeneratorToTargetMap() // Add dependencies of the included target. An excluded // target may still be included if it is a dependency of a // non-excluded target. - TargetDependSet & tgtdeps = this->GetTargetDirectDepends(target); + TargetDependSet const& tgtdeps = this->GetTargetDirectDepends(target); for(TargetDependSet::const_iterator ti = tgtdeps.begin(); ti != tgtdeps.end(); ++ti) { @@ -1879,7 +1879,7 @@ void cmGlobalGenerator::AppendDirectoryForConfig(const char*, const char*, } //---------------------------------------------------------------------------- -cmGlobalGenerator::TargetDependSet & +cmGlobalGenerator::TargetDependSet const& cmGlobalGenerator::GetTargetDirectDepends(cmTarget & target) { return this->TargetDependencies[&target]; diff --git a/Source/cmGlobalGenerator.h b/Source/cmGlobalGenerator.h index 878be11..9d5aa57 100644 --- a/Source/cmGlobalGenerator.h +++ b/Source/cmGlobalGenerator.h @@ -238,7 +238,7 @@ public: // what targets does the specified target depend on directly // via a target_link_libraries or add_dependencies - TargetDependSet & GetTargetDirectDepends(cmTarget & target); + TargetDependSet const& GetTargetDirectDepends(cmTarget & target); const std::map<cmStdString, std::vector<cmLocalGenerator*> >& GetProjectMap() const {return this->ProjectMap;} diff --git a/Source/cmGlobalVisualStudio10Generator.cxx b/Source/cmGlobalVisualStudio10Generator.cxx index 691502f..403507f 100644 --- a/Source/cmGlobalVisualStudio10Generator.cxx +++ b/Source/cmGlobalVisualStudio10Generator.cxx @@ -40,7 +40,7 @@ void cmGlobalVisualStudio10Generator::WriteSLNHeader(std::ostream& fout) cmLocalGenerator *cmGlobalVisualStudio10Generator::CreateLocalGenerator() { cmLocalVisualStudio10Generator* lg = new cmLocalVisualStudio10Generator; - lg->SetPlatformName(this->PlatformName.c_str()); + lg->SetPlatformName(this->GetPlatformName()); lg->SetGlobalGenerator(this); return lg; } diff --git a/Source/cmGlobalVisualStudio10Win64Generator.cxx b/Source/cmGlobalVisualStudio10Win64Generator.cxx index 1004fa9..109b60d 100644 --- a/Source/cmGlobalVisualStudio10Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio10Win64Generator.cxx @@ -16,7 +16,6 @@ //---------------------------------------------------------------------------- cmGlobalVisualStudio10Win64Generator::cmGlobalVisualStudio10Win64Generator() { - this->PlatformName = "x64"; } //---------------------------------------------------------------------------- diff --git a/Source/cmGlobalVisualStudio10Win64Generator.h b/Source/cmGlobalVisualStudio10Win64Generator.h index 98ba03c..39c9d08 100644 --- a/Source/cmGlobalVisualStudio10Win64Generator.h +++ b/Source/cmGlobalVisualStudio10Win64Generator.h @@ -27,6 +27,8 @@ public: return cmGlobalVisualStudio10Win64Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 10 Win64";} + virtual const char* GetPlatformName() const {return "x64";} + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; diff --git a/Source/cmGlobalVisualStudio8Generator.cxx b/Source/cmGlobalVisualStudio8Generator.cxx index 6e0f048..2612a08 100644 --- a/Source/cmGlobalVisualStudio8Generator.cxx +++ b/Source/cmGlobalVisualStudio8Generator.cxx @@ -21,7 +21,7 @@ cmGlobalVisualStudio8Generator::cmGlobalVisualStudio8Generator() { this->FindMakeProgramFile = "CMakeVS8FindMake.cmake"; this->ProjectConfigurationSectionName = "ProjectConfigurationPlatforms"; - this->PlatformName = "Win32"; + this->ArchitectureId = "X86"; } //---------------------------------------------------------------------------- @@ -30,6 +30,7 @@ cmLocalGenerator *cmGlobalVisualStudio8Generator::CreateLocalGenerator() { cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator; lg->SetVersion8(); + lg->SetPlatformName(this->GetPlatformName()); lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); lg->SetGlobalGenerator(this); return lg; @@ -55,8 +56,8 @@ void cmGlobalVisualStudio8Generator //---------------------------------------------------------------------------- void cmGlobalVisualStudio8Generator::AddPlatformDefinitions(cmMakefile* mf) { - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); + mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); + mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); mf->AddDefinition("MSVC80", "1"); } @@ -252,8 +253,8 @@ cmGlobalVisualStudio8Generator for(std::vector<std::string>::iterator i = this->Configurations.begin(); i != this->Configurations.end(); ++i) { - fout << "\t\t" << *i << "|" << this->PlatformName << " = " << *i << "|" - << this->PlatformName << "\n"; + fout << "\t\t" << *i << "|" << this->GetPlatformName() << " = " << *i << "|" + << this->GetPlatformName() << "\n"; } fout << "\tEndGlobalSection\n"; } @@ -269,13 +270,13 @@ cmGlobalVisualStudio8Generator i != this->Configurations.end(); ++i) { fout << "\t\t{" << guid << "}." << *i - << "|" << this->PlatformName << ".ActiveCfg = " - << *i << "|" << this->PlatformName << "\n"; + << "|" << this->GetPlatformName() << ".ActiveCfg = " + << *i << "|" << this->GetPlatformName() << "\n"; if(partOfDefaultBuild) { fout << "\t\t{" << guid << "}." << *i - << "|" << this->PlatformName << ".Build.0 = " - << *i << "|" << this->PlatformName << "\n"; + << "|" << this->GetPlatformName() << ".Build.0 = " + << *i << "|" << this->GetPlatformName() << "\n"; } } } diff --git a/Source/cmGlobalVisualStudio8Generator.h b/Source/cmGlobalVisualStudio8Generator.h index 9d836bd..e0d5d80 100644 --- a/Source/cmGlobalVisualStudio8Generator.h +++ b/Source/cmGlobalVisualStudio8Generator.h @@ -32,14 +32,14 @@ public: return cmGlobalVisualStudio8Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 8 2005";} + virtual const char* GetPlatformName() const {return "Win32";} + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; ///! Create a local generator appropriate to this Global Generator virtual cmLocalGenerator *CreateLocalGenerator(); - std::string const& GetPlatformName() const { return this->PlatformName; } - /** * Override Configure and Generate to add the build-system check * target. @@ -78,6 +78,7 @@ protected: virtual void WriteProjectConfigurations(std::ostream& fout, const char* name, bool partOfDefaultBuild); - std::string PlatformName; // Win32 or x64 + + const char* ArchitectureId; }; #endif diff --git a/Source/cmGlobalVisualStudio8Win64Generator.cxx b/Source/cmGlobalVisualStudio8Win64Generator.cxx index d5558bb..3469b17 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio8Win64Generator.cxx @@ -19,7 +19,7 @@ cmGlobalVisualStudio8Win64Generator::cmGlobalVisualStudio8Win64Generator() { - this->PlatformName = "x64"; + this->ArchitectureId = "x64"; } ///! Create a local generator appropriate to this Global Generator @@ -27,7 +27,7 @@ cmLocalGenerator *cmGlobalVisualStudio8Win64Generator::CreateLocalGenerator() { cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator; lg->SetVersion8(); - lg->SetPlatformName(this->PlatformName.c_str()); + lg->SetPlatformName(this->GetPlatformName()); lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); lg->SetGlobalGenerator(this); return lg; @@ -48,6 +48,4 @@ void cmGlobalVisualStudio8Win64Generator { this->cmGlobalVisualStudio8Generator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } diff --git a/Source/cmGlobalVisualStudio8Win64Generator.h b/Source/cmGlobalVisualStudio8Win64Generator.h index 44c237c..084ba69 100644 --- a/Source/cmGlobalVisualStudio8Win64Generator.h +++ b/Source/cmGlobalVisualStudio8Win64Generator.h @@ -33,6 +33,8 @@ public: return cmGlobalVisualStudio8Win64Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 8 2005 Win64";} + virtual const char* GetPlatformName() const {return "x64";} + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; diff --git a/Source/cmGlobalVisualStudio9Generator.cxx b/Source/cmGlobalVisualStudio9Generator.cxx index f6ae705..f8ceea0 100644 --- a/Source/cmGlobalVisualStudio9Generator.cxx +++ b/Source/cmGlobalVisualStudio9Generator.cxx @@ -25,8 +25,8 @@ cmGlobalVisualStudio9Generator::cmGlobalVisualStudio9Generator() //---------------------------------------------------------------------------- void cmGlobalVisualStudio9Generator::AddPlatformDefinitions(cmMakefile* mf) { - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "X86"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "X86"); + mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", this->ArchitectureId); + mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", this->ArchitectureId); mf->AddDefinition("MSVC90", "1"); } @@ -42,6 +42,7 @@ cmLocalGenerator *cmGlobalVisualStudio9Generator::CreateLocalGenerator() { cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator; lg->SetVersion9(); + lg->SetPlatformName(this->GetPlatformName()); lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); lg->SetGlobalGenerator(this); return lg; diff --git a/Source/cmGlobalVisualStudio9Win64Generator.cxx b/Source/cmGlobalVisualStudio9Win64Generator.cxx index c5b9bab..ff4fd4f 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.cxx +++ b/Source/cmGlobalVisualStudio9Win64Generator.cxx @@ -16,7 +16,7 @@ cmGlobalVisualStudio9Win64Generator::cmGlobalVisualStudio9Win64Generator() { - this->PlatformName = "x64"; + this->ArchitectureId = "x64"; } ///! Create a local generator appropriate to this Global Generator @@ -24,7 +24,7 @@ cmLocalGenerator *cmGlobalVisualStudio9Win64Generator::CreateLocalGenerator() { cmLocalVisualStudio7Generator *lg = new cmLocalVisualStudio7Generator; lg->SetVersion9(); - lg->SetPlatformName(this->PlatformName.c_str()); + lg->SetPlatformName(this->GetPlatformName()); lg->SetExtraFlagTable(this->GetExtraFlagTableVS8()); lg->SetGlobalGenerator(this); return lg; @@ -45,6 +45,4 @@ void cmGlobalVisualStudio9Win64Generator { cmGlobalVisualStudio9Generator::AddPlatformDefinitions(mf); mf->AddDefinition("CMAKE_FORCE_WIN64", "TRUE"); - mf->AddDefinition("MSVC_C_ARCHITECTURE_ID", "x64"); - mf->AddDefinition("MSVC_CXX_ARCHITECTURE_ID", "x64"); } diff --git a/Source/cmGlobalVisualStudio9Win64Generator.h b/Source/cmGlobalVisualStudio9Win64Generator.h index 55abcfc..f6dcc03 100644 --- a/Source/cmGlobalVisualStudio9Win64Generator.h +++ b/Source/cmGlobalVisualStudio9Win64Generator.h @@ -33,6 +33,8 @@ public: return cmGlobalVisualStudio9Win64Generator::GetActualName();} static const char* GetActualName() {return "Visual Studio 9 2008 Win64";} + virtual const char* GetPlatformName() const {return "x64";} + /** Get the documentation entry for this generator. */ virtual void GetDocumentation(cmDocumentationEntry& entry) const; diff --git a/Source/cmGraphAdjacencyList.h b/Source/cmGraphAdjacencyList.h index 7794840..0149d33 100644 --- a/Source/cmGraphAdjacencyList.h +++ b/Source/cmGraphAdjacencyList.h @@ -14,7 +14,27 @@ #include "cmStandardIncludes.h" +/** + * Graph edge representation. Most use cases just need the + * destination vertex, so we support conversion to/from an int. We + * also store boolean to indicate whether an edge is "strong". + */ +class cmGraphEdge +{ +public: + cmGraphEdge(): Dest(0), Strong(true) {} + cmGraphEdge(int n): Dest(n), Strong(true) {} + cmGraphEdge(int n, bool s): Dest(n), Strong(s) {} + cmGraphEdge(cmGraphEdge const& r): Dest(r.Dest), Strong(r.Strong) {} + operator int() const { return this->Dest; } + + bool IsStrong() const { return this->Strong; } +private: + int Dest; + bool Strong; +}; +struct cmGraphEdgeList: public std::vector<cmGraphEdge> {}; struct cmGraphNodeList: public std::vector<int> {}; -struct cmGraphAdjacencyList: public std::vector<cmGraphNodeList> {}; +struct cmGraphAdjacencyList: public std::vector<cmGraphEdgeList> {}; #endif diff --git a/Source/cmInstallCommand.h b/Source/cmInstallCommand.h index ea0a1ec..8f62322 100644 --- a/Source/cmInstallCommand.h +++ b/Source/cmInstallCommand.h @@ -175,6 +175,7 @@ public: "The EXPORT option associates the installed target files with an " "export called <export-name>. " "It must appear before any RUNTIME, LIBRARY, or ARCHIVE options. " + "To actually install the export file itself, call install(EXPORT). " "See documentation of the install(EXPORT ...) signature below for " "details." "\n" diff --git a/Source/cmInstallGenerator.cxx b/Source/cmInstallGenerator.cxx index 47ca769..9d5e416 100644 --- a/Source/cmInstallGenerator.cxx +++ b/Source/cmInstallGenerator.cxx @@ -60,6 +60,26 @@ void cmInstallGenerator } os << indent; std::string dest = this->GetInstallDestination(); + if (cmSystemTools::FileIsFullPath(dest.c_str())) + { + os << "list(APPEND CPACK_ABSOLUTE_DESTINATION_FILES\n"; + os << indent << " \""; + for(std::vector<std::string>::const_iterator fi = files.begin(); + fi != files.end(); ++fi) + { + if (fi!=files.begin()) os << ";"; + os << dest << cmSystemTools::ConvertToOutputPath("/"); + if (rename && *rename) + { + os << rename; + } + else + { + os << cmSystemTools::GetFilenameName(*fi); + } + } + os << "\")\n"; + } os << "FILE(INSTALL DESTINATION \"" << dest << "\" TYPE " << stype.c_str(); if(optional) { diff --git a/Source/cmLocalVisualStudio7Generator.cxx b/Source/cmLocalVisualStudio7Generator.cxx index e411d3e..cb34bb6 100644 --- a/Source/cmLocalVisualStudio7Generator.cxx +++ b/Source/cmLocalVisualStudio7Generator.cxx @@ -466,6 +466,8 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"GenerateManifest", "MANIFEST", "enable manifest generation", "TRUE", 0}, {"LinkIncremental", "INCREMENTAL:NO", "link incremental", "1", 0}, {"LinkIncremental", "INCREMENTAL:YES", "link incremental", "2", 0}, + {"EntryPointSymbol", "ENTRY:", "sets the starting address", "", + cmVS7FlagTable::UserValue}, {"IgnoreDefaultLibraryNames", "NODEFAULTLIB:", "default libs to ignore", "", cmVS7FlagTable::UserValue | cmVS7FlagTable::SemicolonAppendable}, {"IgnoreAllDefaultLibraries", "NODEFAULTLIB", "ignore all default libs", @@ -480,6 +482,21 @@ cmVS7FlagTable cmLocalVisualStudio7GeneratorLinkFlagTable[] = {"OptimizeReferences", "OPT:REF", "Eliminate unreferenced data", "2", 0}, {"TargetMachine", "MACHINE:I386", "Machine x86", "1", 0}, {"TargetMachine", "MACHINE:X86", "Machine x86", "1", 0}, + {"TargetMachine", "MACHINE:AM33", "Machine AM33", "2", 0}, + {"TargetMachine", "MACHINE:ARM", "Machine ARM", "3", 0}, + {"TargetMachine", "MACHINE:EBC", "Machine EBC", "4", 0}, + {"TargetMachine", "MACHINE:IA64", "Machine IA64", "5", 0}, + {"TargetMachine", "MACHINE:M32R", "Machine M32R", "6", 0}, + {"TargetMachine", "MACHINE:MIPS", "Machine MIPS", "7", 0}, + {"TargetMachine", "MACHINE:MIPS16", "Machine MIPS16", "8", 0}, + {"TargetMachine", "MACHINE:MIPSFPU)", "Machine MIPSFPU", "9", 0}, + {"TargetMachine", "MACHINE:MIPSFPU16", "Machine MIPSFPU16", "10", 0}, + {"TargetMachine", "MACHINE:MIPSR41XX", "Machine MIPSR41XX", "11", 0}, + {"TargetMachine", "MACHINE:SH3", "Machine SH3", "12", 0}, + {"TargetMachine", "MACHINE:SH3DSP", "Machine SH3DSP", "13", 0}, + {"TargetMachine", "MACHINE:SH4", "Machine SH4", "14", 0}, + {"TargetMachine", "MACHINE:SH5", "Machine SH5", "15", 0}, + {"TargetMachine", "MACHINE:THUMB", "Machine THUMB", "16", 0}, {"TargetMachine", "MACHINE:X64", "Machine x64", "17", 0}, {"ModuleDefinitionFile", "DEF:", "add an export def file", "", cmVS7FlagTable::UserValue}, diff --git a/Source/cmOptionCommand.h b/Source/cmOptionCommand.h index 8670fc4..fa5abd8 100644 --- a/Source/cmOptionCommand.h +++ b/Source/cmOptionCommand.h @@ -59,7 +59,10 @@ public: " option(<option_variable> \"help string describing option\"\n" " [initial value])\n" "Provide an option for the user to select as ON or OFF. If no " - "initial value is provided, OFF is used."; + "initial value is provided, OFF is used.\n" + "If you have options that depend on the values of other " + "options, see the module help for CMakeDependentOption." + ; } /** diff --git a/Source/cmSystemTools.cxx b/Source/cmSystemTools.cxx index 271a662..8378922 100644 --- a/Source/cmSystemTools.cxx +++ b/Source/cmSystemTools.cxx @@ -283,7 +283,22 @@ void cmSystemTools::ReportLastSystemError(const char* msg) cmSystemTools::Error(m.c_str()); } - +bool cmSystemTools::IsInternallyOn(const char* val) +{ + if (!val) + { + return false; + } + std::basic_string<char> v = val; + + for(std::basic_string<char>::iterator c = v.begin(); + c != v.end(); c++) + { + *c = static_cast<char>(toupper(*c)); + } + return (v == "I_ON" || v == "i_on"); +} + bool cmSystemTools::IsOn(const char* val) { if (!val) diff --git a/Source/cmSystemTools.h b/Source/cmSystemTools.h index 6a9d849..6f9147c 100644 --- a/Source/cmSystemTools.h +++ b/Source/cmSystemTools.h @@ -103,6 +103,12 @@ public: cmSystemTools::s_ErrorOccured = false; } + /** + * Does a string indicates that CMake/CPack/CTest internally + * forced this value. This is not the same as On, but this + * may be considered as "internally switched on". + */ + static bool IsInternallyOn(const char* val); /** * does a string indicate a true or on value ? This is not the same * as ifdef. diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx index ca522bb..70680ad 100644 --- a/Source/cmVisualStudio10TargetGenerator.cxx +++ b/Source/cmVisualStudio10TargetGenerator.cxx @@ -1422,7 +1422,7 @@ void cmVisualStudio10TargetGenerator::WriteEvent( void cmVisualStudio10TargetGenerator::WriteProjectReferences() { - cmGlobalGenerator::TargetDependSet& depends + cmGlobalGenerator::TargetDependSet const& depends = this->GlobalGenerator->GetTargetDirectDepends(*this->Target); this->WriteString("<ItemGroup>\n", 1); for( cmGlobalGenerator::TargetDependSet::const_iterator i = depends.begin(); diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index bcdb193..8aa99eb 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1405,6 +1405,10 @@ kwsys_stl::vector<kwsys::String> SystemTools::SplitString(const char* p, char se { kwsys_stl::string path = p; kwsys_stl::vector<kwsys::String> paths; + if(path.empty()) + { + return paths; + } if(isPath && path[0] == '/') { path.erase(path.begin()); @@ -3059,30 +3063,35 @@ kwsys_stl::string SystemTools::RelativePath(const char* local, const char* remot static int GetCasePathName(const kwsys_stl::string & pathIn, kwsys_stl::string & casePath) { - kwsys_stl::vector<kwsys::String> path_components = - SystemTools::SplitString(pathIn.c_str(), '/', true); - if(path_components.empty()) + kwsys_stl::vector<kwsys_stl::string> path_components; + SystemTools::SplitPath(pathIn.c_str(), path_components); + if(path_components[0].empty()) // First component always exists. { + // Relative paths cannot be converted. casePath = ""; return 0; } + + // Start with root component. kwsys_stl::vector<kwsys_stl::string>::size_type idx = 0; - // assume always absolute path, so just take first casePath = path_components[idx++]; + const char* sep = ""; + // If network path, fill casePath with server/share so FindFirstFile // will work after that. Maybe someday call other APIs to get // actual case of servers and shares. - if(path_components.size() > 2 && pathIn.size() >= 2 && - pathIn[0] == '/' && pathIn[1] == '/') + if(path_components.size() > 2 && path_components[0] == "//") { casePath += path_components[idx++]; casePath += "/"; casePath += path_components[idx++]; + sep = "/"; } for(; idx < path_components.size(); idx++) { - casePath += "/"; + casePath += sep; + sep = "/"; kwsys_stl::string test_str = casePath; test_str += path_components[idx]; diff --git a/Source/kwsys/SystemTools.hxx.in b/Source/kwsys/SystemTools.hxx.in index ec70320..cf47923 100644 --- a/Source/kwsys/SystemTools.hxx.in +++ b/Source/kwsys/SystemTools.hxx.in @@ -372,8 +372,8 @@ public: * "c:/" = Windows full path (can be any drive letter) * "c:" = Windows drive-letter relative path (can be any drive letter) * "//" = Network path - * "~" = Home path for current user - * "~u" = Home path for user 'u' + * "~/" = Home path for current user + * "~u/" = Home path for user 'u' * "" = Relative path * * A pointer to the rest of the path after the root component is @@ -385,7 +385,7 @@ public: /** * Split a path name into its basic components. The first component - * is one of the roots returned by SplitPathRootComponent. + * always exists and is the root returned by SplitPathRootComponent. * The remaining components form the path. If there is a trailing * slash then the last component is the empty string. The * components can be recombined as "c[0]c[1]/c[2]/.../c[n]" to diff --git a/Source/kwsys/kwsysDateStamp.cmake b/Source/kwsys/kwsysDateStamp.cmake index 7fe952b..8002939 100644 --- a/Source/kwsys/kwsysDateStamp.cmake +++ b/Source/kwsys/kwsysDateStamp.cmake @@ -18,4 +18,4 @@ SET(KWSYS_DATE_STAMP_YEAR 2010) SET(KWSYS_DATE_STAMP_MONTH 08) # KWSys version date day component. Format is DD. -SET(KWSYS_DATE_STAMP_DAY 27) +SET(KWSYS_DATE_STAMP_DAY 31) diff --git a/Tests/Dependency/Four/CMakeLists.txt b/Tests/Dependency/Four/CMakeLists.txt index ba3711f..df0f162 100644 --- a/Tests/Dependency/Four/CMakeLists.txt +++ b/Tests/Dependency/Four/CMakeLists.txt @@ -1,3 +1,6 @@ +INCLUDE_DIRECTORIES(${Dependency_BINARY_DIR}/Two) ADD_LIBRARY( Four FourSrc.c ) TARGET_LINK_LIBRARIES( Four One Two NoDepA ) +# TwoCustom must build before Four. +ADD_DEPENDENCIES(Four TwoCustom) diff --git a/Tests/Dependency/Four/FourSrc.c b/Tests/Dependency/Four/FourSrc.c index e8fefcd..23a66a4 100644 --- a/Tests/Dependency/Four/FourSrc.c +++ b/Tests/Dependency/Four/FourSrc.c @@ -1,3 +1,4 @@ +#include <two-test.h> /* Requires TwoCustom to be built first. */ void NoDepAFunction(); void OneFunction(); void TwoFunction(); |