diff --git a/Help/release/dev/CPack-updates.rst b/Help/release/dev/CPack-updates.rst index 7ac1ed714..ea0780f82 100644 --- a/Help/release/dev/CPack-updates.rst +++ b/Help/release/dev/CPack-updates.rst @@ -4,3 +4,8 @@ CPack-updates * The :module:`CPack` module no longer mangles settings with CMake-special characters when they're used as defaults for other settings. The macro ``cpack_set_if_not_set``, which was responsible for this, is now deprecated. + +* The :module:`CPack` module gained a new setting, ``CPACK_VERBATIM_VARIABLES``, + which can be used to ensure the cpack program receives the settings' values + exactly as they were set, even if they contain CMake-special characters. + For compatibility, it's off by default. diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 7d6d54c49..575600180 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -182,6 +182,17 @@ # will be a boolean variable which enables stripping of all files (a list # of files evaluates to TRUE in CMake, so this change is compatible). # +# .. variable:: CPACK_VERBATIM_VARIABLES +# +# If set to TRUE, values of variables prefixed with CPACK_ will be escaped +# before being written to the configuration files, so that the cpack program +# receives them exactly as they were specified. If not, characters like quotes +# and backslashes can cause parsing errors or alter the value received by the +# cpack program. Defaults to FALSE for backwards compatibility. +# +# * Mandatory : NO +# * Default : FALSE +# # The following CPack variables are specific to source packages, and # will not affect binary packages: # @@ -305,21 +316,28 @@ macro(cpack_set_if_not_set name value) _cpack_set_default("${name}" "${value}") endmacro() -# cpack_encode_variables - Macro to encode variables for the configuration file +# cpack_encode_variables - Function to encode variables for the configuration file # find any variable that starts with CPACK and create a variable # _CPACK_OTHER_VARIABLES_ that contains SET commands for # each cpack variable. _CPACK_OTHER_VARIABLES_ is then # used as an @ replacment in configure_file for the CPackConfig. -macro(cpack_encode_variables) - set(_CPACK_OTHER_VARIABLES_) +function(cpack_encode_variables) + set(commands "") get_cmake_property(res VARIABLES) foreach(var ${res}) if(var MATCHES "^CPACK") - set(_CPACK_OTHER_VARIABLES_ - "${_CPACK_OTHER_VARIABLES_}\nSET(${var} \"${${var}}\")") + if(CPACK_VERBATIM_VARIABLES) + _cpack_escape_for_cmake(value "${${var}}") + else() + set(value "${${var}}") endif() + + set(commands "${commands}\nSET(${var} \"${value}\")") + endif() endforeach() -endmacro() + + set(_CPACK_OTHER_VARIABLES_ "${commands}" PARENT_SCOPE) +endfunction() # Internal use functions function(_cpack_set_default name value) @@ -328,6 +346,11 @@ function(_cpack_set_default name value) endif() endfunction() +function(_cpack_escape_for_cmake var value) + string(REGEX REPLACE "([\\\$\"])" "\\\\\\1" escaped "${value}") + set("${var}" "${escaped}" PARENT_SCOPE) +endfunction() + # Set the package name _cpack_set_default(CPACK_PACKAGE_NAME "${CMAKE_PROJECT_NAME}") _cpack_set_default(CPACK_PACKAGE_VERSION_MAJOR "0") @@ -608,8 +631,15 @@ _cpack_set_default(CPACK_SOURCE_INSTALLED_DIRECTORIES _cpack_set_default(CPACK_SOURCE_TOPLEVEL_TAG "${CPACK_SYSTEM_NAME}-Source") _cpack_set_default(CPACK_SOURCE_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}-Source") -_cpack_set_default(CPACK_SOURCE_IGNORE_FILES - "/CVS/;/\\\\.svn/;/\\\\.bzr/;/\\\\.hg/;/\\\\.git/;\\\\.swp$;\\\\.#;/#") + +set(__cpack_source_ignore_files_default + "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#") +if(NOT CPACK_VERBATIM_VARIABLES) + _cpack_escape_for_cmake(__cpack_source_ignore_files_default + "${__cpack_source_ignore_files_default}") +endif() +_cpack_set_default(CPACK_SOURCE_IGNORE_FILES "${__cpack_source_ignore_files_default}") + set(CPACK_INSTALL_CMAKE_PROJECTS "${CPACK_SOURCE_INSTALL_CMAKE_PROJECTS}") set(CPACK_INSTALLED_DIRECTORIES "${CPACK_SOURCE_INSTALLED_DIRECTORIES}") set(CPACK_GENERATOR "${CPACK_SOURCE_GENERATOR}") diff --git a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake index ef018b5ee..16d2cf39f 100644 --- a/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake +++ b/Tests/RunCMake/CPackConfig/RunCMakeTest.cmake @@ -2,3 +2,5 @@ include(RunCMake) run_cmake(Simple) run_cmake(Default) +run_cmake(Special) +run_cmake(Verbatim) diff --git a/Tests/RunCMake/CPackConfig/Special-check.cmake b/Tests/RunCMake/CPackConfig/Special-check.cmake new file mode 100644 index 000000000..0624b7908 --- /dev/null +++ b/Tests/RunCMake/CPackConfig/Special-check.cmake @@ -0,0 +1,5 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_variable(CPACK_BACKSLASH "\\") +test_variable(CPACK_QUOTE "a;b;c") +test_variable(CPACK_DOLLAR "ab") diff --git a/Tests/RunCMake/CPackConfig/Special.cmake b/Tests/RunCMake/CPackConfig/Special.cmake new file mode 100644 index 000000000..9442c934c --- /dev/null +++ b/Tests/RunCMake/CPackConfig/Special.cmake @@ -0,0 +1,3 @@ +set(CPACK_BACKSLASH "\\\\") +set(CPACK_QUOTE "a\" b \"c") +set(CPACK_DOLLAR "a\${NOTHING}b") diff --git a/Tests/RunCMake/CPackConfig/Verbatim-check.cmake b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake new file mode 100644 index 000000000..958547dbb --- /dev/null +++ b/Tests/RunCMake/CPackConfig/Verbatim-check.cmake @@ -0,0 +1,10 @@ +include(${RunCMake_SOURCE_DIR}/check.cmake) + +test_variable(CPACK_BACKSLASH "\\\\") +test_variable(CPACK_QUOTE "a\" b \"c") +test_variable(CPACK_DOLLAR "a\${NOTHING}b") + +# make sure the default for this is still set correctly with +# CPACK_VERBATIM_VARIABLES on +test_variable(CPACK_SOURCE_IGNORE_FILES + "/CVS/;/\\.svn/;/\\.bzr/;/\\.hg/;/\\.git/;\\.swp$;\\.#;/#") diff --git a/Tests/RunCMake/CPackConfig/Verbatim.cmake b/Tests/RunCMake/CPackConfig/Verbatim.cmake new file mode 100644 index 000000000..4d271c33f --- /dev/null +++ b/Tests/RunCMake/CPackConfig/Verbatim.cmake @@ -0,0 +1,5 @@ +set(CPACK_VERBATIM_VARIABLES YES) + +set(CPACK_BACKSLASH "\\\\") +set(CPACK_QUOTE "a\" b \"c") +set(CPACK_DOLLAR "a\${NOTHING}b")