diff options
Diffstat (limited to 'Modules/Internal')
-rw-r--r-- | Modules/Internal/CPack/CPackDeb.cmake | 581 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackExt.cmake | 53 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackFreeBSD.cmake | 107 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackNuGet.cmake | 363 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackRPM.cmake | 1867 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackWIX.cmake | 20 | ||||
-rw-r--r-- | Modules/Internal/CPack/CPackZIP.cmake | 30 |
7 files changed, 3021 insertions, 0 deletions
diff --git a/Modules/Internal/CPack/CPackDeb.cmake b/Modules/Internal/CPack/CPackDeb.cmake new file mode 100644 index 0000000..4ef4539 --- /dev/null +++ b/Modules/Internal/CPack/CPackDeb.cmake @@ -0,0 +1,581 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# CPack script for creating Debian package +# Author: Mathieu Malaterre +# +# http://wiki.debian.org/HowToPackageForDebian + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackDeb.cmake may only be used by CPack internally.") +endif() + +function(cpack_deb_variable_fallback OUTPUT_VAR_NAME) + set(FALLBACK_VAR_NAMES ${ARGN}) + + foreach(variable_name IN LISTS FALLBACK_VAR_NAMES) + if(${variable_name}) + set(${OUTPUT_VAR_NAME} "${${variable_name}}" PARENT_SCOPE) + break() + endif() + endforeach() +endfunction() + +function(get_component_package_name var component) + string(TOUPPER "${component}" component_upcase) + if(CPACK_DEBIAN_${component_upcase}_PACKAGE_NAME) + string(TOLOWER "${CPACK_DEBIAN_${component_upcase}_PACKAGE_NAME}" package_name) + else() + string(TOLOWER "${CPACK_DEBIAN_PACKAGE_NAME}-${component}" package_name) + endif() + + set("${var}" "${package_name}" PARENT_SCOPE) +endfunction() + +#extract library name and version for given shared object +function(extract_so_info shared_object libname version) + if(READELF_EXECUTABLE) + execute_process(COMMAND "${READELF_EXECUTABLE}" -d "${shared_object}" + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + RESULT_VARIABLE result + OUTPUT_VARIABLE output + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(result EQUAL 0) + string(REGEX MATCH "\\(SONAME\\)[^\n]*\\[([^\n]+)\\.so\\.([^\n]*)\\]" soname "${output}") + set(${libname} "${CMAKE_MATCH_1}" PARENT_SCOPE) + set(${version} "${CMAKE_MATCH_2}" PARENT_SCOPE) + else() + message(WARNING "Error running readelf for \"${shared_object}\"") + endif() + else() + message(FATAL_ERROR "Readelf utility is not available.") + endif() +endfunction() + +function(cpack_deb_prepare_package_vars) + # CPACK_DEBIAN_PACKAGE_SHLIBDEPS + # If specify OFF, only user depends are used + if(NOT DEFINED CPACK_DEBIAN_PACKAGE_SHLIBDEPS) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OFF) + endif() + + set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_DEB_PACKAGE_COMPONENT_PART_PATH}") + + # per component automatic discover: some of the component might not have + # binaries. + if(CPACK_DEB_PACKAGE_COMPONENT) + string(TOUPPER "${CPACK_DEB_PACKAGE_COMPONENT}" _local_component_name) + set(_component_shlibdeps_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_SHLIBDEPS") + + # if set, overrides the global configuration + if(DEFINED ${_component_shlibdeps_var}) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS "${${_component_shlibdeps_var}}") + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb Debug: component '${CPACK_DEB_PACKAGE_COMPONENT}' dpkg-shlibdeps set to ${CPACK_DEBIAN_PACKAGE_SHLIBDEPS}") + endif() + endif() + endif() + + if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS OR CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS) + # Generating binary list - Get type of all install files + file(GLOB_RECURSE FILE_PATHS_ LIST_DIRECTORIES false RELATIVE "${WDIR}" "${WDIR}/*") + + find_program(FILE_EXECUTABLE file) + if(NOT FILE_EXECUTABLE) + message(FATAL_ERROR "CPackDeb: file utility is not available. CPACK_DEBIAN_PACKAGE_SHLIBDEPS and CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS options are not available.") + endif() + + # get file info so that we can determine if file is executable or not + unset(CPACK_DEB_INSTALL_FILES) + foreach(FILE_ IN LISTS FILE_PATHS_) + execute_process(COMMAND env LC_ALL=C ${FILE_EXECUTABLE} "./${FILE_}" + WORKING_DIRECTORY "${WDIR}" + RESULT_VARIABLE FILE_RESULT_ + OUTPUT_VARIABLE INSTALL_FILE_) + if(NOT FILE_RESULT_ EQUAL 0) + message (FATAL_ERROR "CPackDeb: execution of command: '${FILE_EXECUTABLE} ./${FILE_}' failed with exit code: ${FILE_RESULT_}") + endif() + list(APPEND CPACK_DEB_INSTALL_FILES "${INSTALL_FILE_}") + endforeach() + + # Only dynamically linked ELF files are included + # Extract only file name infront of ":" + foreach(_FILE IN LISTS CPACK_DEB_INSTALL_FILES) + if(_FILE MATCHES "ELF.*dynamically linked") + string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}") + list(APPEND CPACK_DEB_BINARY_FILES "${CMAKE_MATCH_1}") + set(CONTAINS_EXECUTABLE_FILES_ TRUE) + endif() + if(_FILE MATCHES "ELF.*shared object") + string(REGEX MATCH "(^.*):" _FILE_NAME "${_FILE}") + list(APPEND CPACK_DEB_SHARED_OBJECT_FILES "${CMAKE_MATCH_1}") + endif() + endforeach() + endif() + + if(CPACK_DEBIAN_PACKAGE_SHLIBDEPS) + # dpkg-shlibdeps is a Debian utility for generating dependency list + find_program(SHLIBDEPS_EXECUTABLE dpkg-shlibdeps) + + if(SHLIBDEPS_EXECUTABLE) + # Check version of the dpkg-shlibdeps tool using CPackDEB method + execute_process(COMMAND env LC_ALL=C ${SHLIBDEPS_EXECUTABLE} --version + OUTPUT_VARIABLE _TMP_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(_TMP_VERSION MATCHES "dpkg-shlibdeps version ([0-9]+\\.[0-9]+\\.[0-9]+)") + set(SHLIBDEPS_EXECUTABLE_VERSION "${CMAKE_MATCH_1}") + else() + set(SHLIBDEPS_EXECUTABLE_VERSION "") + endif() + + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb Debug: dpkg-shlibdeps --version output is '${_TMP_VERSION}'") + message("CPackDeb Debug: dpkg-shlibdeps version is <${SHLIBDEPS_EXECUTABLE_VERSION}>") + endif() + + if(CONTAINS_EXECUTABLE_FILES_) + message("CPackDeb: - Generating dependency list") + + # Create blank control file for running dpkg-shlibdeps + # There might be some other way to invoke dpkg-shlibdeps without creating this file + # but standard debian package should not have anything that can collide with this file or directory + file(MAKE_DIRECTORY ${CPACK_TEMPORARY_DIRECTORY}/debian) + file(WRITE ${CPACK_TEMPORARY_DIRECTORY}/debian/control "") + + # Create a DEBIAN directory so that dpkg-shlibdeps can find the package dir when resolving $ORIGIN. + file(MAKE_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}/DEBIAN") + + # Add --ignore-missing-info if the tool supports it + execute_process(COMMAND env LC_ALL=C ${SHLIBDEPS_EXECUTABLE} --help + OUTPUT_VARIABLE _TMP_HELP + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(_TMP_HELP MATCHES "--ignore-missing-info") + set(IGNORE_MISSING_INFO_FLAG "--ignore-missing-info") + endif() + + # Execute dpkg-shlibdeps + # --ignore-missing-info : allow dpkg-shlibdeps to run even if some libs do not belong to a package + # -O : print to STDOUT + execute_process(COMMAND ${SHLIBDEPS_EXECUTABLE} ${IGNORE_MISSING_INFO_FLAG} -O ${CPACK_DEB_BINARY_FILES} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + OUTPUT_VARIABLE SHLIBDEPS_OUTPUT + RESULT_VARIABLE SHLIBDEPS_RESULT + ERROR_VARIABLE SHLIBDEPS_ERROR + OUTPUT_STRIP_TRAILING_WHITESPACE ) + if(CPACK_DEBIAN_PACKAGE_DEBUG) + # dpkg-shlibdeps will throw some warnings if some input files are not binary + message( "CPackDeb Debug: dpkg-shlibdeps warnings \n${SHLIBDEPS_ERROR}") + endif() + if(NOT SHLIBDEPS_RESULT EQUAL 0) + message (FATAL_ERROR "CPackDeb: dpkg-shlibdeps: '${SHLIBDEPS_ERROR}';\n" + "executed command: '${SHLIBDEPS_EXECUTABLE} ${IGNORE_MISSING_INFO_FLAG} -O ${CPACK_DEB_BINARY_FILES}';\n" + "found files: '${INSTALL_FILE_}';\n" + "files info: '${CPACK_DEB_INSTALL_FILES}';\n" + "binary files: '${CPACK_DEB_BINARY_FILES}'") + endif() + + #Get rid of prefix generated by dpkg-shlibdeps + string(REGEX REPLACE "^.*Depends=" "" CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS "${SHLIBDEPS_OUTPUT}") + + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb Debug: Found dependency: ${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS} from output ${SHLIBDEPS_OUTPUT}") + endif() + + # Remove blank control file + # Might not be safe if package actual contain file or directory named debian + file(REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/debian") + + # remove temporary directory that was created only for dpkg-shlibdeps execution + file(REMOVE_RECURSE "${CPACK_TEMPORARY_DIRECTORY}/DEBIAN") + else() + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message(AUTHOR_WARNING "CPackDeb Debug: Using only user-provided depends because package does not contain executable files that link to shared libraries.") + endif() + endif() + else() + message("CPackDeb: Using only user-provided dependencies because dpkg-shlibdeps is not found.") + endif() + + else() + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb Debug: Using only user-provided dependencies") + endif() + endif() + + # Let's define the control file found in debian package: + + # Binary package: + # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-binarycontrolfiles + + # DEBIAN/control + # debian policy enforce lower case for package name + # Package: (mandatory) + if(NOT CPACK_DEBIAN_PACKAGE_NAME) + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_DEBIAN_PACKAGE_NAME) + endif() + + # Version: (mandatory) + if(NOT CPACK_DEBIAN_PACKAGE_VERSION) + if(NOT CPACK_PACKAGE_VERSION) + message(FATAL_ERROR "CPackDeb: Debian package requires a package version") + endif() + set(CPACK_DEBIAN_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}) + endif() + + if(DEFINED CPACK_DEBIAN_PACKAGE_RELEASE OR DEFINED CPACK_DEBIAN_PACKAGE_EPOCH) + # only test the version format if CPACK_DEBIAN_PACKAGE_RELEASE or + # CPACK_DEBIAN_PACKAGE_EPOCH is set + if(NOT CPACK_DEBIAN_PACKAGE_VERSION MATCHES "^[0-9][A-Za-z0-9.+~-]*$") + message(FATAL_ERROR + "CPackDeb: Debian package version must confirm to \"^[0-9][A-Za-z0-9.+~-]*$\" regex!") + endif() + else() + # before CMake 3.10 version format was not tested so only warn to preserve + # backward compatibility + if(NOT CPACK_DEBIAN_PACKAGE_VERSION MATCHES "^([0-9]+:)?[0-9][A-Za-z0-9.+~-]*$") + message(AUTHOR_WARNING + "CPackDeb: Debian package versioning ([<epoch>:]<version>[-<release>])" + " should confirm to \"^([0-9]+:)?[0-9][A-Za-z0-9.+~-]*$\" regex in" + " order to satisfy Debian packaging rules.") + endif() + endif() + + if(CPACK_DEBIAN_PACKAGE_RELEASE) + if(NOT CPACK_DEBIAN_PACKAGE_RELEASE MATCHES "^[A-Za-z0-9.+~]+$") + message(FATAL_ERROR + "CPackDeb: Debian package release must confirm to \"^[A-Za-z0-9.+~]+$\" regex!") + endif() + string(APPEND CPACK_DEBIAN_PACKAGE_VERSION + "-${CPACK_DEBIAN_PACKAGE_RELEASE}") + elseif(DEFINED CPACK_DEBIAN_PACKAGE_EPOCH) + # only test the version format if CPACK_DEBIAN_PACKAGE_RELEASE or + # CPACK_DEBIAN_PACKAGE_EPOCH is set - versions CPack/Deb generator before + # CMake 3.10 did not check for version format so we have to preserve + # backward compatibility + if(CPACK_DEBIAN_PACKAGE_VERSION MATCHES ".*-.*") + message(FATAL_ERROR + "CPackDeb: Debian package version must not contain hyphens when CPACK_DEBIAN_PACKAGE_RELEASE is not provided!") + endif() + endif() + + if(CPACK_DEBIAN_PACKAGE_EPOCH) + if(NOT CPACK_DEBIAN_PACKAGE_EPOCH MATCHES "^[0-9]+$") + message(FATAL_ERROR + "CPackDeb: Debian package epoch must confirm to \"^[0-9]+$\" regex!") + endif() + set(CPACK_DEBIAN_PACKAGE_VERSION + "${CPACK_DEBIAN_PACKAGE_EPOCH}:${CPACK_DEBIAN_PACKAGE_VERSION}") + endif() + + # Architecture: (mandatory) + if(CPACK_DEB_PACKAGE_COMPONENT AND CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE) + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_${_local_component_name}_PACKAGE_ARCHITECTURE}") + elseif(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE) + # There is no such thing as i686 architecture on debian, you should use i386 instead + # $ dpkg --print-architecture + find_program(DPKG_CMD dpkg) + if(NOT DPKG_CMD) + message(STATUS "CPackDeb: Can not find dpkg in your path, default to i386.") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386) + endif() + execute_process(COMMAND "${DPKG_CMD}" --print-architecture + OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() + + # Source: (optional) + # in case several packages are constructed from a unique source + # (multipackaging), the source may be indicated as well. + # The source might contain a version if the generated package + # version is different from the source version + if(NOT CPACK_DEBIAN_PACKAGE_SOURCE) + set(CPACK_DEBIAN_PACKAGE_SOURCE "") + endif() + + # have a look at get_property(result GLOBAL PROPERTY ENABLED_FEATURES), + # this returns the successful find_package() calls, maybe this can help + # Depends: + # You should set: DEBIAN_PACKAGE_DEPENDS + # TODO: automate 'objdump -p | grep NEEDED' + + # if per-component variable, overrides the global CPACK_DEBIAN_PACKAGE_${variable_type_} + # automatic dependency discovery will be performed afterwards. + if(CPACK_DEB_PACKAGE_COMPONENT) + foreach(value_type_ DEPENDS RECOMMENDS SUGGESTS PREDEPENDS ENHANCES BREAKS CONFLICTS PROVIDES REPLACES SOURCE SECTION PRIORITY NAME) + set(_component_var "CPACK_DEBIAN_${_local_component_name}_PACKAGE_${value_type_}") + + # if set, overrides the global variable + if(DEFINED ${_component_var}) + set(CPACK_DEBIAN_PACKAGE_${value_type_} "${${_component_var}}") + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb Debug: component '${_local_component_name}' ${value_type_} " + "value set to '${CPACK_DEBIAN_PACKAGE_${value_type_}}'") + endif() + endif() + endforeach() + + if(CPACK_DEBIAN_ENABLE_COMPONENT_DEPENDS) + set(COMPONENT_DEPENDS "") + foreach (_PACK ${CPACK_COMPONENT_${_local_component_name}_DEPENDS}) + get_component_package_name(_PACK_NAME "${_PACK}") + if(COMPONENT_DEPENDS) + set(COMPONENT_DEPENDS "${_PACK_NAME} (= ${CPACK_DEBIAN_PACKAGE_VERSION}), ${COMPONENT_DEPENDS}") + else() + set(COMPONENT_DEPENDS "${_PACK_NAME} (= ${CPACK_DEBIAN_PACKAGE_VERSION})") + endif() + endforeach() + if(COMPONENT_DEPENDS) + if(CPACK_DEBIAN_PACKAGE_DEPENDS) + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${COMPONENT_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_DEPENDS}") + else() + set(CPACK_DEBIAN_PACKAGE_DEPENDS "${COMPONENT_DEPENDS}") + endif() + endif() + endif() + endif() + + # at this point, the CPACK_DEBIAN_PACKAGE_DEPENDS is properly set + # to the minimal dependency of the package + # Append automatically discovered dependencies . + if(NOT "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}" STREQUAL "") + if (CPACK_DEBIAN_PACKAGE_DEPENDS) + set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}, ${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}") + else () + set (CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_AUTO_DEPENDS}") + endif () + endif() + + if(NOT CPACK_DEBIAN_PACKAGE_DEPENDS) + message(STATUS "CPACK_DEBIAN_PACKAGE_DEPENDS not set, the package will have no dependencies.") + endif() + + # Maintainer: (mandatory) + if(NOT CPACK_DEBIAN_PACKAGE_MAINTAINER) + if(NOT CPACK_PACKAGE_CONTACT) + message(FATAL_ERROR "CPackDeb: Debian package requires a maintainer for a package, set CPACK_PACKAGE_CONTACT or CPACK_DEBIAN_PACKAGE_MAINTAINER") + endif() + set(CPACK_DEBIAN_PACKAGE_MAINTAINER ${CPACK_PACKAGE_CONTACT}) + endif() + + # Description: (mandatory) + if(NOT CPACK_DEB_PACKAGE_COMPONENT) + if(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION) + if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) + message(FATAL_ERROR "CPackDeb: Debian package requires a summary for a package, set CPACK_PACKAGE_DESCRIPTION_SUMMARY or CPACK_DEBIAN_PACKAGE_DESCRIPTION") + endif() + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + endif() + else() + set(component_description_var CPACK_COMPONENT_${_local_component_name}_DESCRIPTION) + + # component description overrides package description + if(${component_description_var}) + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${${component_description_var}}) + elseif(NOT CPACK_DEBIAN_PACKAGE_DESCRIPTION) + if(NOT CPACK_PACKAGE_DESCRIPTION_SUMMARY) + message(FATAL_ERROR "CPackDeb: Debian package requires a summary for a package, set CPACK_PACKAGE_DESCRIPTION_SUMMARY or CPACK_DEBIAN_PACKAGE_DESCRIPTION or ${component_description_var}") + endif() + set(CPACK_DEBIAN_PACKAGE_DESCRIPTION ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + endif() + endif() + + # Homepage: (optional) + if(NOT CPACK_DEBIAN_PACKAGE_HOMEPAGE AND CMAKE_PROJECT_HOMEPAGE_URL) + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CMAKE_PROJECT_HOMEPAGE_URL}") + endif() + + # Section: (recommended) + if(NOT CPACK_DEBIAN_PACKAGE_SECTION) + set(CPACK_DEBIAN_PACKAGE_SECTION "devel") + endif() + + # Priority: (recommended) + if(NOT CPACK_DEBIAN_PACKAGE_PRIORITY) + set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional") + endif() + + if(CPACK_DEBIAN_ARCHIVE_TYPE) + set(archive_types_ "paxr;gnutar") + if(NOT CPACK_DEBIAN_ARCHIVE_TYPE IN_LIST archive_types_) + message(FATAL_ERROR "CPACK_DEBIAN_ARCHIVE_TYPE set to unsupported" + "type ${CPACK_DEBIAN_ARCHIVE_TYPE}") + endif() + else() + set(CPACK_DEBIAN_ARCHIVE_TYPE "paxr") + endif() + + # Compression: (recommended) + if(NOT CPACK_DEBIAN_COMPRESSION_TYPE) + set(CPACK_DEBIAN_COMPRESSION_TYPE "gzip") + endif() + + # Recommends: + # You should set: CPACK_DEBIAN_PACKAGE_RECOMMENDS + + # Suggests: + # You should set: CPACK_DEBIAN_PACKAGE_SUGGESTS + + # CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + # This variable allow advanced user to add custom script to the control.tar.gz (inside the .deb archive) + # Typical examples are: + # - conffiles + # - postinst + # - postrm + # - prerm + # Usage: + # set(CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA + # "${CMAKE_CURRENT_SOURCE_DIR}/prerm;${CMAKE_CURRENT_SOURCE_DIR}/postrm") + + # Are we packaging components ? + if(CPACK_DEB_PACKAGE_COMPONENT) + # override values with per component version if set + foreach(VAR_NAME_ "PACKAGE_CONTROL_EXTRA" "PACKAGE_CONTROL_STRICT_PERMISSION") + if(CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}) + set(CPACK_DEBIAN_${VAR_NAME_} "${CPACK_DEBIAN_${_local_component_name}_${VAR_NAME_}}") + endif() + endforeach() + get_component_package_name(CPACK_DEBIAN_PACKAGE_NAME ${_local_component_name}) + endif() + + set(CPACK_DEBIAN_PACKAGE_SHLIBS_LIST "") + + if (NOT CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY) + set(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY "=") + endif() + + find_program(READELF_EXECUTABLE NAMES readelf) + + if(CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS) + if(READELF_EXECUTABLE) + foreach(_FILE IN LISTS CPACK_DEB_SHARED_OBJECT_FILES) + extract_so_info("${_FILE}" libname soversion) + if(libname AND DEFINED soversion) + list(APPEND CPACK_DEBIAN_PACKAGE_SHLIBS_LIST + "${libname} ${soversion} ${CPACK_DEBIAN_PACKAGE_NAME} (${CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS_POLICY} ${CPACK_DEBIAN_PACKAGE_VERSION})") + else() + message(AUTHOR_WARNING "Shared library '${_FILE}' is missing soname or soversion. Library will not be added to DEBIAN/shlibs control file.") + endif() + endforeach() + if (CPACK_DEBIAN_PACKAGE_SHLIBS_LIST) + string(REPLACE ";" "\n" CPACK_DEBIAN_PACKAGE_SHLIBS_LIST "${CPACK_DEBIAN_PACKAGE_SHLIBS_LIST}") + endif() + else() + message(FATAL_ERROR "Readelf utility is not available. CPACK_DEBIAN_PACKAGE_GENERATE_SHLIBS option is not available.") + endif() + endif() + + # add ldconfig call in default postrm and postint + set(CPACK_ADD_LDCONFIG_CALL 0) + foreach(_FILE ${CPACK_DEB_SHARED_OBJECT_FILES}) + get_filename_component(_DIR ${_FILE} DIRECTORY) + # all files in CPACK_DEB_SHARED_OBJECT_FILES have dot at the beginning + if(_DIR STREQUAL "./lib" OR _DIR STREQUAL "./usr/lib") + set(CPACK_ADD_LDCONFIG_CALL 1) + endif() + endforeach() + + if(CPACK_ADD_LDCONFIG_CALL) + set(CPACK_DEBIAN_GENERATE_POSTINST 1) + set(CPACK_DEBIAN_GENERATE_POSTRM 1) + foreach(f ${PACKAGE_CONTROL_EXTRA}) + get_filename_component(n "${f}" NAME) + if("${n}" STREQUAL "postinst") + set(CPACK_DEBIAN_GENERATE_POSTINST 0) + endif() + if("${n}" STREQUAL "postrm") + set(CPACK_DEBIAN_GENERATE_POSTRM 0) + endif() + endforeach() + else() + set(CPACK_DEBIAN_GENERATE_POSTINST 0) + set(CPACK_DEBIAN_GENERATE_POSTRM 0) + endif() + + cpack_deb_variable_fallback("CPACK_DEBIAN_FILE_NAME" + "CPACK_DEBIAN_${_local_component_name}_FILE_NAME" + "CPACK_DEBIAN_FILE_NAME") + if(CPACK_DEBIAN_FILE_NAME) + if(CPACK_DEBIAN_FILE_NAME STREQUAL "DEB-DEFAULT") + # Patch package file name to be in correct debian format: + # <foo>_<VersionNumber>-<DebianRevisionNumber>_<DebianArchitecture>.deb + set(CPACK_OUTPUT_FILE_NAME + "${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}.deb") + else() + if(NOT CPACK_DEBIAN_FILE_NAME MATCHES ".*\\.(deb|ipk)") + message(FATAL_ERROR "'${CPACK_DEBIAN_FILE_NAME}' is not a valid DEB package file name as it must end with '.deb' or '.ipk'!") + endif() + + set(CPACK_OUTPUT_FILE_NAME "${CPACK_DEBIAN_FILE_NAME}") + endif() + + set(CPACK_TEMPORARY_PACKAGE_FILE_NAME "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_OUTPUT_FILE_NAME}") + get_filename_component(BINARY_DIR "${CPACK_OUTPUT_FILE_PATH}" DIRECTORY) + set(CPACK_OUTPUT_FILE_PATH "${BINARY_DIR}/${CPACK_OUTPUT_FILE_NAME}") + endif() # else() back compatibility - don't change the name + + # Print out some debug information if we were asked for that + if(CPACK_DEBIAN_PACKAGE_DEBUG) + message("CPackDeb:Debug: CPACK_TOPLEVEL_DIRECTORY = '${CPACK_TOPLEVEL_DIRECTORY}'") + message("CPackDeb:Debug: CPACK_TOPLEVEL_TAG = '${CPACK_TOPLEVEL_TAG}'") + message("CPackDeb:Debug: CPACK_TEMPORARY_DIRECTORY = '${CPACK_TEMPORARY_DIRECTORY}'") + message("CPackDeb:Debug: CPACK_OUTPUT_FILE_NAME = '${CPACK_OUTPUT_FILE_NAME}'") + message("CPackDeb:Debug: CPACK_OUTPUT_FILE_PATH = '${CPACK_OUTPUT_FILE_PATH}'") + message("CPackDeb:Debug: CPACK_PACKAGE_FILE_NAME = '${CPACK_PACKAGE_FILE_NAME}'") + message("CPackDeb:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = '${CPACK_PACKAGE_INSTALL_DIRECTORY}'") + message("CPackDeb:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = '${CPACK_TEMPORARY_PACKAGE_FILE_NAME}'") + message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION = '${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}'") + message("CPackDeb:Debug: CPACK_DEBIAN_PACKAGE_SOURCE = '${CPACK_DEBIAN_PACKAGE_SOURCE}'") + endif() + + # For debian source packages: + # debian/control + # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-sourcecontrolfiles + + # .dsc + # http://www.debian.org/doc/debian-policy/ch-controlfields.html#s-debiansourcecontrolfiles + + # Builds-Depends: + #if(NOT CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS) + # set(CPACK_DEBIAN_PACKAGE_BUILDS_DEPENDS + # "debhelper (>> 5.0.0), libncurses5-dev, tcl8.4" + # ) + #endif() + + # move variables to parent scope so that they may be used to create debian package + set(GEN_CPACK_OUTPUT_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}" PARENT_SCOPE) + set(GEN_CPACK_TEMPORARY_PACKAGE_FILE_NAME "${CPACK_TEMPORARY_PACKAGE_FILE_NAME}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_NAME "${CPACK_DEBIAN_PACKAGE_NAME}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_DEBIAN_PACKAGE_VERSION}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_SECTION "${CPACK_DEBIAN_PACKAGE_SECTION}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_PRIORITY "${CPACK_DEBIAN_PACKAGE_PRIORITY}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_MAINTAINER "${CPACK_DEBIAN_PACKAGE_MAINTAINER}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_DESCRIPTION "${CPACK_DEBIAN_PACKAGE_DESCRIPTION}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_DEPENDS "${CPACK_DEBIAN_PACKAGE_DEPENDS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_ARCHIVE_TYPE "${CPACK_DEBIAN_ARCHIVE_TYPE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_COMPRESSION_TYPE "${CPACK_DEBIAN_COMPRESSION_TYPE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_RECOMMENDS "${CPACK_DEBIAN_PACKAGE_RECOMMENDS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_SUGGESTS "${CPACK_DEBIAN_PACKAGE_SUGGESTS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_HOMEPAGE "${CPACK_DEBIAN_PACKAGE_HOMEPAGE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_PREDEPENDS "${CPACK_DEBIAN_PACKAGE_PREDEPENDS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_ENHANCES "${CPACK_DEBIAN_PACKAGE_ENHANCES}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_BREAKS "${CPACK_DEBIAN_PACKAGE_BREAKS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_CONFLICTS "${CPACK_DEBIAN_PACKAGE_CONFLICTS}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_PROVIDES "${CPACK_DEBIAN_PACKAGE_PROVIDES}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_REPLACES "${CPACK_DEBIAN_PACKAGE_REPLACES}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_SHLIBS "${CPACK_DEBIAN_PACKAGE_SHLIBS_LIST}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION + "${CPACK_DEBIAN_PACKAGE_CONTROL_STRICT_PERMISSION}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_PACKAGE_SOURCE + "${CPACK_DEBIAN_PACKAGE_SOURCE}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_GENERATE_POSTINST "${CPACK_DEBIAN_GENERATE_POSTINST}" PARENT_SCOPE) + set(GEN_CPACK_DEBIAN_GENERATE_POSTRM "${CPACK_DEBIAN_GENERATE_POSTRM}" PARENT_SCOPE) + set(GEN_WDIR "${WDIR}" PARENT_SCOPE) +endfunction() + +cpack_deb_prepare_package_vars() diff --git a/Modules/Internal/CPack/CPackExt.cmake b/Modules/Internal/CPack/CPackExt.cmake new file mode 100644 index 0000000..e52d978 --- /dev/null +++ b/Modules/Internal/CPack/CPackExt.cmake @@ -0,0 +1,53 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +if(NOT "${CPACK_EXT_REQUESTED_VERSIONS}" STREQUAL "") + unset(_found_major) + + foreach(_req_version IN LISTS CPACK_EXT_REQUESTED_VERSIONS) + if(_req_version MATCHES "^([0-9]+)\\.([0-9]+)$") + set(_req_major "${CMAKE_MATCH_1}") + set(_req_minor "${CMAKE_MATCH_2}") + + foreach(_known_version IN LISTS CPACK_EXT_KNOWN_VERSIONS) + string(REGEX MATCH + "^([0-9]+)\\.([0-9]+)$" + _known_version_dummy + "${_known_version}" + ) + + set(_known_major "${CMAKE_MATCH_1}") + set(_known_minor "${CMAKE_MATCH_2}") + + if(_req_major EQUAL _known_major AND NOT _known_minor LESS _req_minor) + set(_found_major "${_known_major}") + set(_found_minor "${_known_minor}") + break() + endif() + endforeach() + + if(DEFINED _found_major) + break() + endif() + endif() + endforeach() + + if(DEFINED _found_major) + set(CPACK_EXT_SELECTED_MAJOR "${_found_major}") + set(CPACK_EXT_SELECTED_MINOR "${_found_minor}") + set(CPACK_EXT_SELECTED_VERSION "${_found_major}.${_found_minor}") + else() + message(FATAL_ERROR + "Could not find a suitable version in CPACK_EXT_REQUESTED_VERSIONS" + ) + endif() +else() + list(GET CPACK_EXT_KNOWN_VERSIONS 0 CPACK_EXT_SELECTED_VERSION) + string(REGEX MATCH + "^([0-9]+)\\.([0-9]+)$" + _dummy + "${CPACK_EXT_SELECTED_VERSION}" + ) + set(CPACK_EXT_SELECTED_MAJOR "${CMAKE_MATCH_1}") + set(CPACK_EXT_SELECTED_MINOR "${CMAKE_MATCH_2}") +endif() diff --git a/Modules/Internal/CPack/CPackFreeBSD.cmake b/Modules/Internal/CPack/CPackFreeBSD.cmake new file mode 100644 index 0000000..16f906c --- /dev/null +++ b/Modules/Internal/CPack/CPackFreeBSD.cmake @@ -0,0 +1,107 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackFreeBSD.cmake may only be used by CPack internally.") +endif() + +if(NOT UNIX) + message(FATAL_ERROR "CPackFreeBSD.cmake may only be used under UNIX.") +endif() + + +### +# +# These bits are copied from the Debian packaging file; slightly modified. +# They are used for filling in FreeBSD-packaging variables that can take +# on values from elsewhere -- e.g. the package description may as well be +# copied from Debian. +# +function(_cpack_freebsd_fallback_var OUTPUT_VAR_NAME) + set(FALLBACK_VAR_NAMES ${ARGN}) + + set(VALUE "${${OUTPUT_VAR_NAME}}") + if(VALUE) + return() + endif() + + foreach(variable_name IN LISTS FALLBACK_VAR_NAMES) + if(${variable_name}) + set(${OUTPUT_VAR_NAME} "${${variable_name}}" PARENT_SCOPE) + set(VALUE "${${variable_name}}") + break() + endif() + endforeach() + if(NOT VALUE) + message(WARNING "Variable ${OUTPUT_VAR_NAME} could not be given a fallback value from any variable ${FALLBACK_VAR_NAMES}.") + endif() +endfunction() + +function(check_required_var VAR_NAME) + if(NOT ${VAR_NAME}) + message(FATAL_ERROR "Variable ${VAR_NAME} is not set.") + endif() +endfunction() + +set(_cpack_freebsd_fallback_origin "misc/bogus") + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_NAME" + "CPACK_PACKAGE_NAME" + "CMAKE_PROJECT_NAME" + ) + +set(_cpack_freebsd_fallback_www "http://example.com/?pkg=${CPACK_FREEBSD_PACKAGE_NAME}") + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_COMMENT" + "CPACK_PACKAGE_DESCRIPTION_SUMMARY" + ) + +# TODO: maybe read the PACKAGE_DESCRIPTION file for the longer +# FreeBSD pkg-descr? +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION" + "CPACK_DEBIAN_PACKAGE_DESCRIPTION" + "CPACK_PACKAGE_DESCRIPTION_SUMMARY" + "PACKAGE_DESCRIPTION" + ) + +# There's really only one homepage for a project, so +# re-use the Debian setting if it's there. +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_WWW" + "CMAKE_PROJECT_HOMEPAGE_URL" + "CPACK_DEBIAN_PACKAGE_HOMEPAGE" + "_cpack_freebsd_fallback_www" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_VERSION" + "CMAKE_PROJECT_VERSION" + "${CMAKE_PROJECT_NAME}_VERSION" + "PROJECT_VERSION" + "CPACK_PACKAGE_VERSION" + "CPACK_PACKAGE_VERSION" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_MAINTAINER" + "CPACK_PACKAGE_CONTACT" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_LICENSE" + "CPACK_RPM_PACKAGE_LICENSE" + ) + +_cpack_freebsd_fallback_var("CPACK_FREEBSD_PACKAGE_ORIGIN" + "_cpack_freebsd_fallback_origin" + ) + +if(NOT CPACK_FREEBSD_PACKAGE_CATEGORIES) + string(REGEX REPLACE "/.*" "" CPACK_FREEBSD_PACKAGE_CATEGORIES ${CPACK_FREEBSD_PACKAGE_ORIGIN}) +endif() + +check_required_var("CPACK_FREEBSD_PACKAGE_NAME") +check_required_var("CPACK_FREEBSD_PACKAGE_ORIGIN") +check_required_var("CPACK_FREEBSD_PACKAGE_VERSION") +check_required_var("CPACK_FREEBSD_PACKAGE_MAINTAINER") +check_required_var("CPACK_FREEBSD_PACKAGE_COMMENT") +check_required_var("CPACK_FREEBSD_PACKAGE_DESCRIPTION") +check_required_var("CPACK_FREEBSD_PACKAGE_WWW") +check_required_var("CPACK_FREEBSD_PACKAGE_LICENSE") diff --git a/Modules/Internal/CPack/CPackNuGet.cmake b/Modules/Internal/CPack/CPackNuGet.cmake new file mode 100644 index 0000000..198ccad --- /dev/null +++ b/Modules/Internal/CPack/CPackNuGet.cmake @@ -0,0 +1,363 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Author: Alex Turbov + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackNuGet.cmake may only be used by CPack internally.") +endif() + +function(_cpack_nuget_debug) + if(CPACK_NUGET_PACKAGE_DEBUG) + message("CPackNuGet:Debug: " ${ARGN}) + endif() +endfunction() + +function(_cpack_nuget_debug_var NAME) + if(CPACK_NUGET_PACKAGE_DEBUG) + message("CPackNuGet:Debug: ${NAME}=`${${NAME}}`") + endif() +endfunction() + +function(_cpack_nuget_variable_fallback OUTPUT_VAR_NAME NUGET_VAR_NAME) + if(ARGN) + list(JOIN ARGN "`, `" _va_args) + set(_va_args ", ARGN: `${_va_args}`") + endif() + _cpack_nuget_debug( + "_cpack_nuget_variable_fallback: " + "OUTPUT_VAR_NAME=`${OUTPUT_VAR_NAME}`, " + "NUGET_VAR_NAME=`${NUGET_VAR_NAME}`" + "${_va_args}" + ) + + set(_options USE_CDATA) + set(_one_value_args LIST_GLUE) + set(_multi_value_args FALLBACK_VARS) + cmake_parse_arguments(PARSE_ARGV 0 _args "${_options}" "${_one_value_args}" "${_multi_value_args}") + + if(CPACK_NUGET_PACKAGE_COMPONENT) + string( + TOUPPER "${CPACK_NUGET_PACKAGE_COMPONENT}" + CPACK_NUGET_PACKAGE_COMPONENT_UPPER + ) + endif() + + if(CPACK_NUGET_PACKAGE_COMPONENT + AND CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME} + ) + set( + _result + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME}}" + ) + _cpack_nuget_debug( + " CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT}_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + elseif(CPACK_NUGET_PACKAGE_COMPONENT_UPPER + AND CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME} + ) + set( + _result + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME}}" + ) + _cpack_nuget_debug( + " CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + elseif(CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}) + set(_result "${CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}}") + _cpack_nuget_debug( + " CPACK_NUGET_PACKAGE_${NUGET_VAR_NAME}: " + "OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + + else() + foreach(_var IN LISTS _args_FALLBACK_VARS) + _cpack_nuget_debug(" Fallback: ${_var} ...") + if(${_var}) + _cpack_nuget_debug(" ${_var}=`${${_var}}`") + set(_result "${${_var}}") + _cpack_nuget_debug( + " ${_var}: OUTPUT_VAR_NAME->${OUTPUT_VAR_NAME}=`${_result}`" + ) + break() + endif() + endforeach() + endif() + + if(_result) + if(_args_USE_CDATA) + set(_value_before "<![CDATA[") + set(_value_after "]]>") + endif() + + list(LENGTH _result _result_len) + if(_result_len GREATER 1 AND _args_LIST_GLUE) + list(JOIN _result "${_args_LIST_GLUE}" _result) + endif() + + set(${OUTPUT_VAR_NAME} "${_value_before}${_result}${_value_after}" PARENT_SCOPE) + endif() + +endfunction() + +function(_cpack_nuget_variable_fallback_and_wrap_into_element ELEMENT NUGET_VAR_NAME) + set(_options) + set(_one_value_args) + set(_multi_value_args FALLBACK_VARS) + cmake_parse_arguments(PARSE_ARGV 0 _args "${_options}" "${_one_value_args}" "${_multi_value_args}") + + _cpack_nuget_variable_fallback(_value ${NUGET_VAR_NAME} ${ARGN} USE_CDATA) + + if(_value) + string(TOUPPER "${ELEMENT}" _ELEMENT_UP) + set( + _CPACK_NUGET_${_ELEMENT_UP}_TAG + "<${ELEMENT}>${_value}</${ELEMENT}>" + PARENT_SCOPE + ) + endif() +endfunction() + +# Print some debug info +_cpack_nuget_debug("---[CPack NuGet Input Variables]---") +_cpack_nuget_debug_var(CPACK_PACKAGE_NAME) +_cpack_nuget_debug_var(CPACK_PACKAGE_VERSION) +_cpack_nuget_debug_var(CPACK_TOPLEVEL_TAG) +_cpack_nuget_debug_var(CPACK_TOPLEVEL_DIRECTORY) +_cpack_nuget_debug_var(CPACK_TEMPORARY_DIRECTORY) +_cpack_nuget_debug_var(CPACK_NUGET_GROUPS) +if(CPACK_NUGET_GROUPS) + foreach(_group IN LISTS CPACK_NUGET_GROUPS) + string(MAKE_C_IDENTIFIER "${_group}" _group_up) + string(TOUPPER "${_group_up}" _group_up) + _cpack_nuget_debug_var(CPACK_NUGET_${_group_up}_GROUP_COMPONENTS) + endforeach() +endif() +_cpack_nuget_debug_var(CPACK_NUGET_COMPONENTS) +_cpack_nuget_debug_var(CPACK_NUGET_ALL_IN_ONE) +_cpack_nuget_debug_var(CPACK_NUGET_ORDINAL_MONOLITIC) +_cpack_nuget_debug("-----------------------------------") + +function(_cpack_nuget_render_spec) + # Make a variable w/ upper-cased component name + if(CPACK_NUGET_PACKAGE_COMPONENT) + string(TOUPPER "${CPACK_NUGET_PACKAGE_COMPONENT}" CPACK_NUGET_PACKAGE_COMPONENT_UPPER) + endif() + + # Set mandatory variables (not wrapped into XML elements) + # https://docs.microsoft.com/en-us/nuget/reference/nuspec#required-metadata-elements + if(CPACK_NUGET_PACKAGE_COMPONENT) + if(CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME) + set( + CPACK_NUGET_PACKAGE_NAME + "${CPACK_NUGET_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME}" + ) + elseif(NOT CPACK_NUGET_PACKAGE_COMPONENT STREQUAL "Unspecified") + set( + CPACK_NUGET_PACKAGE_NAME + "${CPACK_PACKAGE_NAME}.${CPACK_NUGET_PACKAGE_COMPONENT}" + ) + else() + set(CPACK_NUGET_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") + endif() + elseif(NOT CPACK_NUGET_PACKAGE_NAME) + set(CPACK_NUGET_PACKAGE_NAME "${CPACK_PACKAGE_NAME}") + endif() + + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_VERSION VERSION + FALLBACK_VARS + CPACK_PACKAGE_VERSION + ) + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_DESCRIPTION DESCRIPTION + FALLBACK_VARS + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT}_DESCRIPTION + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DESCRIPTION + CPACK_COMPONENT_GROUP_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DESCRIPTION + CPACK_PACKAGE_DESCRIPTION + USE_CDATA + ) + _cpack_nuget_variable_fallback( + CPACK_NUGET_PACKAGE_AUTHORS AUTHORS + FALLBACK_VARS + CPACK_PACKAGE_VENDOR + USE_CDATA + LIST_GLUE "," + ) + + # Set optional variables (wrapped into XML elements) + # https://docs.microsoft.com/en-us/nuget/reference/nuspec#optional-metadata-elements + _cpack_nuget_variable_fallback_and_wrap_into_element( + title + TITLE + FALLBACK_VARS + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT}_DISPLAY_NAME + CPACK_COMPONENT_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DISPLAY_NAME + CPACK_COMPONENT_GROUP_${CPACK_NUGET_PACKAGE_COMPONENT_UPPER}_DISPLAY_NAME + ) + _cpack_nuget_variable_fallback_and_wrap_into_element(owners OWNERS LIST_GLUE ",") + _cpack_nuget_variable_fallback_and_wrap_into_element( + projectUrl + HOMEPAGE_URL + FALLBACK_VARS + CPACK_PACKAGE_HOMEPAGE_URL + ) + _cpack_nuget_variable_fallback_and_wrap_into_element(licenseUrl LICENSEURL) + _cpack_nuget_variable_fallback_and_wrap_into_element(iconUrl ICONURL) + _cpack_nuget_variable_fallback_and_wrap_into_element( + summary DESCRIPTION_SUMMARY + FALLBACK_VARS + CPACK_PACKAGE_DESCRIPTION_SUMMARY + ) + if(CPACK_NUGET_PACKAGE_REQUIRE_LICENSE_ACCEPTANCE) + set( + _CPACK_NUGET_REQUIRELICENSEACCEPTANCE_TAG + "<requireLicenseAcceptance>true</requireLicenseAcceptance>" + ) + endif() + _cpack_nuget_variable_fallback_and_wrap_into_element(releaseNotes RELEASE_NOTES) + _cpack_nuget_variable_fallback_and_wrap_into_element(copyright COPYRIGHT) + _cpack_nuget_variable_fallback_and_wrap_into_element(tags TAGS LIST_GLUE " ") + + # Handle dependencies + _cpack_nuget_variable_fallback(_deps DEPENDENCIES) + set(_collected_deps) + foreach(_dep IN LISTS _deps) + _cpack_nuget_debug(" checking dependency `${_dep}`") + + string(MAKE_C_IDENTIFIER "${_dep}" _dep_id) + + _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION) + + if(NOT _ver) + string(TOUPPER "${_dep_id}" _dep_id) + _cpack_nuget_variable_fallback(_ver DEPENDENCIES_${_dep_id}_VERSION) + endif() + + if(_ver) + _cpack_nuget_debug(" got `${_dep}` dependency version ${_ver}") + list(APPEND _collected_deps "<dependency id=\"${_dep}\" version=\"${_ver}\" />") + endif() + endforeach() + + # Render deps into the variable + if(_collected_deps) + set(_CPACK_NUGET_DEPENDENCIES_TAG "<dependencies>\n") + foreach(_line IN LISTS _collected_deps) + string( + APPEND _CPACK_NUGET_DEPENDENCIES_TAG + " ${_line}\n" + ) + endforeach() + string(APPEND _CPACK_NUGET_DEPENDENCIES_TAG " </dependencies>") + endif() + + # Render the spec file + # NOTE The spec filename doesn't matter. Being included into a package, + # NuGet will name it properly. + _cpack_nuget_debug("Rendering `${CPACK_TEMPORARY_DIRECTORY}/CPack.NuGet.nuspec` file...") + configure_file( + "${CMAKE_ROOT}/Modules/CPack.NuGet.nuspec.in" + "${CPACK_TEMPORARY_DIRECTORY}/CPack.NuGet.nuspec" + @ONLY + ) +endfunction() + +function(_cpack_nuget_make_files_tag) + set(_files) + foreach(_comp IN LISTS ARGN) + string(APPEND _files " <file src=\"${_comp}\\**\" target=\".\" />\n") + endforeach() + set(_CPACK_NUGET_FILES_TAG "<files>\n${_files} </files>" PARENT_SCOPE) +endfunction() + +find_program(NUGET_EXECUTABLE NuGet) +_cpack_nuget_debug_var(NUGET_EXECUTABLE) +if(NOT NUGET_EXECUTABLE) + message(FATAL_ERROR "NuGet executable not found") +endif() + +# Add details for debug run +if(CPACK_NUGET_PACKAGE_DEBUG) + list(APPEND CPACK_NUGET_PACK_ADDITIONAL_OPTIONS "-Verbosity" "detailed") +endif() + +# Case one: ordinal all-in-one package +if(CPACK_NUGET_ORDINAL_MONOLITIC) + # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code: + # Meaning to pack all installed files into a single package + _cpack_nuget_debug("---[Making an ordinal monolitic package]---") + _cpack_nuget_render_spec() + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + +elseif(CPACK_NUGET_ALL_IN_ONE) + # This variable `CPACK_NUGET_ALL_IN_ONE` set by C++ code: + # Meaning to pack all installed components into a single package + _cpack_nuget_debug("---[Making a monolitic package from installed components]---") + + # Prepare the `files` element which include files from several components + _cpack_nuget_make_files_tag(${CPACK_NUGET_COMPONENTS}) + _cpack_nuget_render_spec() + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + +else() + # Is there any grouped component? + if(CPACK_NUGET_GROUPS) + _cpack_nuget_debug("---[Making grouped component(s) package(s)]---") + foreach(_group IN LISTS CPACK_NUGET_GROUPS) + _cpack_nuget_debug("Starting to make the package for group `${_group}`") + string(MAKE_C_IDENTIFIER "${_group}" _group_up) + string(TOUPPER "${_group_up}" _group_up) + + # Render a spec file which includes all components in the current group + unset(_CPACK_NUGET_FILES_TAG) + _cpack_nuget_make_files_tag(${CPACK_NUGET_${_group_up}_GROUP_COMPONENTS}) + # Temporary set `CPACK_NUGET_PACKAGE_COMPONENT` to the group name + # to properly collect various per group settings + set(CPACK_NUGET_PACKAGE_COMPONENT ${_group}) + _cpack_nuget_render_spec() + unset(CPACK_NUGET_PACKAGE_COMPONENT) + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + endforeach() + endif() + # Is there any single component package needed? + if(CPACK_NUGET_COMPONENTS) + _cpack_nuget_debug("---[Making single-component(s) package(s)]---") + foreach(_comp IN LISTS CPACK_NUGET_COMPONENTS) + _cpack_nuget_debug("Starting to make the package for component `${_comp}`") + # Render a spec file which includes only given component + unset(_CPACK_NUGET_FILES_TAG) + _cpack_nuget_make_files_tag(${_comp}) + # Temporary set `CPACK_NUGET_PACKAGE_COMPONENT` to the current + # component name to properly collect various per group settings + set(CPACK_NUGET_PACKAGE_COMPONENT ${_comp}) + _cpack_nuget_render_spec() + unset(CPACK_NUGET_PACKAGE_COMPONENT) + execute_process( + COMMAND "${NUGET_EXECUTABLE}" pack ${CPACK_NUGET_PACK_ADDITIONAL_OPTIONS} + WORKING_DIRECTORY "${CPACK_TEMPORARY_DIRECTORY}" + ) + endforeach() + endif() +endif() + +file(GLOB_RECURSE GEN_CPACK_OUTPUT_FILES "${CPACK_TEMPORARY_DIRECTORY}/*.nupkg") +if(NOT GEN_CPACK_OUTPUT_FILES) + message(FATAL_ERROR "NuGet package was not generated at `${CPACK_TEMPORARY_DIRECTORY}`!") +endif() + +_cpack_nuget_debug("Generated files: ${GEN_CPACK_OUTPUT_FILES}") diff --git a/Modules/Internal/CPack/CPackRPM.cmake b/Modules/Internal/CPack/CPackRPM.cmake new file mode 100644 index 0000000..06298d7 --- /dev/null +++ b/Modules/Internal/CPack/CPackRPM.cmake @@ -0,0 +1,1867 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Author: Eric Noulard with the help of Alexander Neundorf. + +function(get_file_permissions FILE RETURN_VAR) + execute_process(COMMAND ls -l ${FILE} + OUTPUT_VARIABLE permissions_ + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + + string(REPLACE " " ";" permissions_ "${permissions_}") + list(GET permissions_ 0 permissions_) + + unset(text_notation_) + set(any_chars_ ".") + foreach(PERMISSION_TYPE "OWNER" "GROUP" "WORLD") + if(permissions_ MATCHES "${any_chars_}r.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_READ") + endif() + string(APPEND any_chars_ ".") + if(permissions_ MATCHES "${any_chars_}w.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_WRITE") + endif() + string(APPEND any_chars_ ".") + if(permissions_ MATCHES "${any_chars_}x.*") + list(APPEND text_notation_ "${PERMISSION_TYPE}_EXECUTE") + endif() + endforeach() + + set(${RETURN_VAR} "${text_notation_}" PARENT_SCOPE) +endfunction() + +function(get_unix_permissions_octal_notation PERMISSIONS_VAR RETURN_VAR) + set(PERMISSIONS ${${PERMISSIONS_VAR}}) + list(LENGTH PERMISSIONS PERM_LEN_PRE) + list(REMOVE_DUPLICATES PERMISSIONS) + list(LENGTH PERMISSIONS PERM_LEN_POST) + + if(NOT ${PERM_LEN_PRE} EQUAL ${PERM_LEN_POST}) + message(FATAL_ERROR "${PERMISSIONS_VAR} contains duplicate values.") + endif() + + foreach(PERMISSION_TYPE "OWNER" "GROUP" "WORLD") + set(${PERMISSION_TYPE}_PERMISSIONS 0) + + foreach(PERMISSION ${PERMISSIONS}) + if("${PERMISSION}" STREQUAL "${PERMISSION_TYPE}_READ") + math(EXPR ${PERMISSION_TYPE}_PERMISSIONS "${${PERMISSION_TYPE}_PERMISSIONS} + 4") + elseif("${PERMISSION}" STREQUAL "${PERMISSION_TYPE}_WRITE") + math(EXPR ${PERMISSION_TYPE}_PERMISSIONS "${${PERMISSION_TYPE}_PERMISSIONS} + 2") + elseif("${PERMISSION}" STREQUAL "${PERMISSION_TYPE}_EXECUTE") + math(EXPR ${PERMISSION_TYPE}_PERMISSIONS "${${PERMISSION_TYPE}_PERMISSIONS} + 1") + elseif(PERMISSION MATCHES "${PERMISSION_TYPE}.*") + message(FATAL_ERROR "${PERMISSIONS_VAR} contains invalid values.") + endif() + endforeach() + endforeach() + + set(${RETURN_VAR} "${OWNER_PERMISSIONS}${GROUP_PERMISSIONS}${WORLD_PERMISSIONS}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_prepare_relocation_paths) + # set appropriate prefix, remove possible trailing slash and convert backslashes to slashes + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_PREFIX) + file(TO_CMAKE_PATH "${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_PREFIX}" PATH_PREFIX) + elseif(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_PREFIX) + file(TO_CMAKE_PATH "${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_PREFIX}" PATH_PREFIX) + else() + file(TO_CMAKE_PATH "${CPACK_PACKAGING_INSTALL_PREFIX}" PATH_PREFIX) + endif() + + set(RPM_RELOCATION_PATHS "${CPACK_RPM_RELOCATION_PATHS}") + list(REMOVE_DUPLICATES RPM_RELOCATION_PATHS) + + # set base path prefix + if(EXISTS "${WDIR}/${PATH_PREFIX}") + if(NOT CPACK_RPM_NO_INSTALL_PREFIX_RELOCATION AND + NOT CPACK_RPM_NO_${CPACK_RPM_PACKAGE_COMPONENT}_INSTALL_PREFIX_RELOCATION AND + NOT CPACK_RPM_NO_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_INSTALL_PREFIX_RELOCATION) + string(APPEND TMP_RPM_PREFIXES "Prefix: ${PATH_PREFIX}\n") + list(APPEND RPM_USED_PACKAGE_PREFIXES "${PATH_PREFIX}") + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: removing '${PATH_PREFIX}' from relocation paths") + endif() + endif() + endif() + + # set other path prefixes + foreach(RELOCATION_PATH ${RPM_RELOCATION_PATHS}) + if(IS_ABSOLUTE "${RELOCATION_PATH}") + set(PREPARED_RELOCATION_PATH "${RELOCATION_PATH}") + elseif(PATH_PREFIX STREQUAL "/") + # don't prefix path with a second slash as "//" is treated as network path + # by get_filename_component() so it remains in path even inside rpm + # package where it may cause problems with relocation + set(PREPARED_RELOCATION_PATH "/${RELOCATION_PATH}") + else() + set(PREPARED_RELOCATION_PATH "${PATH_PREFIX}/${RELOCATION_PATH}") + endif() + + # handle cases where path contains extra slashes (e.g. /a//b/ instead of + # /a/b) + get_filename_component(PREPARED_RELOCATION_PATH + "${PREPARED_RELOCATION_PATH}" ABSOLUTE) + + if(EXISTS "${WDIR}/${PREPARED_RELOCATION_PATH}") + string(APPEND TMP_RPM_PREFIXES "Prefix: ${PREPARED_RELOCATION_PATH}\n") + list(APPEND RPM_USED_PACKAGE_PREFIXES "${PREPARED_RELOCATION_PATH}") + endif() + endforeach() + + # warn about all the paths that are not relocatable + file(GLOB_RECURSE FILE_PATHS_ "${WDIR}/*") + foreach(TMP_PATH ${FILE_PATHS_}) + string(LENGTH "${WDIR}" WDIR_LEN) + string(SUBSTRING "${TMP_PATH}" ${WDIR_LEN} -1 TMP_PATH) + unset(TMP_PATH_FOUND_) + + foreach(RELOCATION_PATH ${RPM_USED_PACKAGE_PREFIXES}) + file(RELATIVE_PATH REL_PATH_ "${RELOCATION_PATH}" "${TMP_PATH}") + string(SUBSTRING "${REL_PATH_}" 0 2 PREFIX_) + + if(NOT "${PREFIX_}" STREQUAL "..") + set(TPM_PATH_FOUND_ TRUE) + break() + endif() + endforeach() + + if(NOT TPM_PATH_FOUND_) + message(AUTHOR_WARNING "CPackRPM:Warning: Path ${TMP_PATH} is not on one of the relocatable paths! Package will be partially relocatable.") + endif() + endforeach() + + set(RPM_USED_PACKAGE_PREFIXES "${RPM_USED_PACKAGE_PREFIXES}" PARENT_SCOPE) + set(TMP_RPM_PREFIXES "${TMP_RPM_PREFIXES}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_prepare_content_list) + # get files list + file(GLOB_RECURSE CPACK_RPM_INSTALL_FILES LIST_DIRECTORIES true RELATIVE "${WDIR}" "${WDIR}/*") + set(CPACK_RPM_INSTALL_FILES "/${CPACK_RPM_INSTALL_FILES}") + string(REPLACE ";" ";/" CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}") + + # if we are creating a relocatable package, omit parent directories of + # CPACK_RPM_PACKAGE_PREFIX. This is achieved by building a "filter list" + # which is passed to the find command that generates the content-list + if(CPACK_RPM_PACKAGE_RELOCATABLE) + # get a list of the elements in CPACK_RPM_PACKAGE_PREFIXES that are + # destinct parent paths of other relocation paths and remove the + # final element (so the install-prefix dir itself is not omitted + # from the RPM's content-list) + list(SORT RPM_USED_PACKAGE_PREFIXES) + set(_DISTINCT_PATH "NOT_SET") + foreach(_RPM_RELOCATION_PREFIX ${RPM_USED_PACKAGE_PREFIXES}) + if(NOT "${_RPM_RELOCATION_PREFIX}" MATCHES "${_DISTINCT_PATH}/.*") + set(_DISTINCT_PATH "${_RPM_RELOCATION_PREFIX}") + + string(REPLACE "/" ";" _CPACK_RPM_PACKAGE_PREFIX_ELEMS " ${_RPM_RELOCATION_PREFIX}") + list(REMOVE_AT _CPACK_RPM_PACKAGE_PREFIX_ELEMS -1) + unset(_TMP_LIST) + # Now generate all of the parent dirs of the relocation path + foreach(_PREFIX_PATH_ELEM ${_CPACK_RPM_PACKAGE_PREFIX_ELEMS}) + list(APPEND _TMP_LIST "${_PREFIX_PATH_ELEM}") + string(REPLACE ";" "/" _OMIT_DIR "${_TMP_LIST}") + separate_arguments(_OMIT_DIR) + list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR}) + endforeach() + endif() + endforeach() + endif() + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Initial list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") + endif() + + if(NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/bin + /usr/include /usr/lib /usr/libx32 /usr/lib64 + /usr/share /usr/share/aclocal /usr/share/doc ) + if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.") + endif() + list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}") + endif() + endif() + + if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}") + endif() + list(APPEND _RPM_DIRS_TO_OMIT ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}) + endif() + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") + endif() + + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES ${_RPM_DIRS_TO_OMIT}) + + # add man paths that will be compressed + # (copied from /usr/lib/rpm/brp-compress - script that does the actual + # compressing) + list(APPEND MAN_LOCATIONS "/usr/man/man.*" "/usr/man/.*/man.*" "/usr/info.*" + "/usr/share/man/man.*" "/usr/share/man/.*/man.*" "/usr/share/info.*" + "/usr/kerberos/man.*" "/usr/X11R6/man/man.*" "/usr/lib/perl5/man/man.*" + "/usr/share/doc/.*/man/man.*" "/usr/lib/.*/man/man.*") + + if(CPACK_RPM_ADDITIONAL_MAN_DIRS) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_ADDITIONAL_MAN_DIRS= ${CPACK_RPM_ADDITIONAL_MAN_DIRS}") + endif() + list(APPEND MAN_LOCATIONS ${CPACK_RPM_ADDITIONAL_MAN_DIRS}) + endif() + + foreach(PACK_LOCATION IN LISTS CPACK_RPM_INSTALL_FILES) + foreach(MAN_LOCATION IN LISTS MAN_LOCATIONS) + # man pages are files inside a certain location + if(PACK_LOCATION MATCHES "${MAN_LOCATION}/" + AND NOT IS_DIRECTORY "${WDIR}${PACK_LOCATION}" + AND NOT IS_SYMLINK "${WDIR}${PACK_LOCATION}") + list(FIND CPACK_RPM_INSTALL_FILES "${PACK_LOCATION}" INDEX) + # insert file location that covers compressed man pages + # even if using a wildcard causes duplicates as those are + # handled by RPM and we still keep the same file list + # in spec file - wildcard only represents file type (e.g. .gz) + list(INSERT CPACK_RPM_INSTALL_FILES ${INDEX} "${PACK_LOCATION}*") + # remove file location that doesn't cover compressed man pages + math(EXPR INDEX ${INDEX}+1) + list(REMOVE_AT CPACK_RPM_INSTALL_FILES ${INDEX}) + + break() + endif() + endforeach() + endforeach() + + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_symlink_get_relocation_prefixes LOCATION PACKAGE_PREFIXES RETURN_VARIABLE) + foreach(PKG_PREFIX IN LISTS PACKAGE_PREFIXES) + string(REGEX MATCH "^${PKG_PREFIX}/.*" FOUND_ "${LOCATION}") + if(FOUND_) + list(APPEND TMP_PREFIXES "${PKG_PREFIX}") + endif() + endforeach() + + set(${RETURN_VARIABLE} "${TMP_PREFIXES}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_symlink_create_relocation_script PACKAGE_PREFIXES) + list(LENGTH PACKAGE_PREFIXES LAST_INDEX) + set(SORTED_PACKAGE_PREFIXES "${PACKAGE_PREFIXES}") + list(SORT SORTED_PACKAGE_PREFIXES) + list(REVERSE SORTED_PACKAGE_PREFIXES) + math(EXPR LAST_INDEX ${LAST_INDEX}-1) + + foreach(SYMLINK_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${SYMLINK_INDEX} SRC_PATH) + list(FIND PACKAGE_PREFIXES "${SRC_PATH}" SYMLINK_INDEX) # reverse magic + string(LENGTH "${SRC_PATH}" SRC_PATH_LEN) + + set(PARTS_CNT 0) + set(SCRIPT_PART "if [ \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}\" != \"${SRC_PATH}\" ]; then\n") + + # both paths relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + if("${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + set(INDENT "") + else() + string(APPEND SCRIPT_PART " if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + set(INDENT " ") + endif() + + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) + + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + string(APPEND SCRIPT_PART " ${INDENT}if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + string(APPEND SCRIPT_PART " ${INDENT}ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + string(APPEND SCRIPT_PART " ${INDENT}CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + string(APPEND SCRIPT_PART " ${INDENT}fi\n") + endforeach() + + if(NOT "${SYMLINK_INDEX}" EQUAL "${POINT_INDEX}") + string(APPEND SCRIPT_PART " fi\n") + endif() + endif() + endforeach() + + # source path relocated + if(_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X) + math(EXPR PARTS_CNT ${PARTS_CNT}+1) + + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + math(EXPR SRC_PATH_END ${SPLIT_INDEX}-${SRC_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${SRC_PATH_LEN} ${SRC_PATH_END} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + string(APPEND SCRIPT_PART " if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + string(APPEND SCRIPT_PART " ln -s \"${POINT_}\" \"$RPM_INSTALL_PREFIX${SYMLINK_INDEX}${SYMLINK_}\"\n") + string(APPEND SCRIPT_PART " CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + string(APPEND SCRIPT_PART " fi\n") + endforeach() + endif() + + if(PARTS_CNT) + set(SCRIPT "${SCRIPT_PART}") + string(APPEND SCRIPT "fi\n") + endif() + endforeach() + + # point path relocated + foreach(POINT_INDEX RANGE ${LAST_INDEX}) + list(GET SORTED_PACKAGE_PREFIXES ${POINT_INDEX} POINT_PATH) + list(FIND PACKAGE_PREFIXES "${POINT_PATH}" POINT_INDEX) # reverse magic + string(LENGTH "${POINT_PATH}" POINT_PATH_LEN) + + if(_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + string(APPEND SCRIPT "if [ \"$RPM_INSTALL_PREFIX${POINT_INDEX}\" != \"${POINT_PATH}\" ]; then\n") + + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1+${POINT_PATH_LEN}) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + string(APPEND SCRIPT " if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + string(APPEND SCRIPT " ln -s \"$RPM_INSTALL_PREFIX${POINT_INDEX}${POINT_}\" \"${SYMLINK_}\"\n") + string(APPEND SCRIPT " CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}=true\n") + string(APPEND SCRIPT " fi\n") + endforeach() + + string(APPEND SCRIPT "fi\n") + endif() + endforeach() + + # no path relocated + if(_RPM_RELOCATION_SCRIPT_X_X) + foreach(RELOCATION_NO IN LISTS _RPM_RELOCATION_SCRIPT_X_X) + math(EXPR RELOCATION_INDEX ${RELOCATION_NO}-1) + list(GET _RPM_RELOCATION_SCRIPT_PAIRS ${RELOCATION_INDEX} RELOCATION_SCRIPT_PAIR) + string(FIND "${RELOCATION_SCRIPT_PAIR}" ":" SPLIT_INDEX) + + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} 0 ${SPLIT_INDEX} SYMLINK_) + + math(EXPR POINT_PATH_START ${SPLIT_INDEX}+1) + string(SUBSTRING ${RELOCATION_SCRIPT_PAIR} ${POINT_PATH_START} -1 POINT_) + + string(APPEND SCRIPT "if [ -z \"$CPACK_RPM_RELOCATED_SYMLINK_${RELOCATION_INDEX}\" ]; then\n") + string(APPEND SCRIPT " ln -s \"${POINT_}\" \"${SYMLINK_}\"\n") + string(APPEND SCRIPT "fi\n") + endforeach() + endif() + + set(RPM_SYMLINK_POSTINSTALL "${SCRIPT}" PARENT_SCOPE) +endfunction() + +function(cpack_rpm_symlink_add_for_relocation_script PACKAGE_PREFIXES SYMLINK SYMLINK_RELOCATION_PATHS POINT POINT_RELOCATION_PATHS) + list(LENGTH SYMLINK_RELOCATION_PATHS SYMLINK_PATHS_COUTN) + list(LENGTH POINT_RELOCATION_PATHS POINT_PATHS_COUNT) + + list(APPEND _RPM_RELOCATION_SCRIPT_PAIRS "${SYMLINK}:${POINT}") + list(LENGTH _RPM_RELOCATION_SCRIPT_PAIRS PAIR_NO) + + if(SYMLINK_PATHS_COUTN) + foreach(SYMLINK_RELOC_PATH IN LISTS SYMLINK_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${SYMLINK_RELOC_PATH}" SYMLINK_INDEX) + + # source path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_X") + + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) + + # both paths relocated + list(APPEND _RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_${SYMLINK_INDEX}_${POINT_INDEX}") + + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() + endforeach() + elseif(POINT_PATHS_COUNT) + foreach(POINT_RELOC_PATH IN LISTS POINT_RELOCATION_PATHS) + list(FIND PACKAGE_PREFIXES "${POINT_RELOC_PATH}" POINT_INDEX) + + # point path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_${POINT_INDEX} "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_${POINT_INDEX}") + endforeach() + endif() + + # no path relocated + list(APPEND _RPM_RELOCATION_SCRIPT_X_X "${PAIR_NO}") + list(APPEND RELOCATION_VARS "_RPM_RELOCATION_SCRIPT_X_X") + + # place variables into parent scope + foreach(VAR IN LISTS RELOCATION_VARS) + set(${VAR} "${${VAR}}" PARENT_SCOPE) + endforeach() + set(_RPM_RELOCATION_SCRIPT_PAIRS "${_RPM_RELOCATION_SCRIPT_PAIRS}" PARENT_SCOPE) + set(REQUIRES_SYMLINK_RELOCATION_SCRIPT "true" PARENT_SCOPE) + set(DIRECTIVE "%ghost " PARENT_SCOPE) +endfunction() + +function(cpack_rpm_prepare_install_files INSTALL_FILES_LIST WDIR PACKAGE_PREFIXES IS_RELOCATABLE) + # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir + # This is necessary to avoid duplicate files since rpmbuild does + # recursion on its own when encountering a pathname which is a directory + # which is not flagged as %dir + string(STRIP "${INSTALL_FILES_LIST}" INSTALL_FILES_LIST) + string(REPLACE "\n" ";" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(REPLACE "\"" "" INSTALL_FILES_LIST + "${INSTALL_FILES_LIST}") + string(LENGTH "${WDIR}" WDR_LEN_) + + list(SORT INSTALL_FILES_LIST) # make file order consistent on all platforms + + foreach(F IN LISTS INSTALL_FILES_LIST) + unset(DIRECTIVE) + + if(IS_SYMLINK "${WDIR}/${F}") + if(IS_RELOCATABLE) + # check that symlink has relocatable format + get_filename_component(SYMLINK_LOCATION_ "${WDIR}/${F}" DIRECTORY) + execute_process(COMMAND ls -la "${WDIR}/${F}" + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE SYMLINK_POINT_ + OUTPUT_STRIP_TRAILING_WHITESPACE) + + string(FIND "${SYMLINK_POINT_}" "->" SYMLINK_POINT_INDEX_ REVERSE) + math(EXPR SYMLINK_POINT_INDEX_ ${SYMLINK_POINT_INDEX_}+3) + string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_) + + # get destination path + string(SUBSTRING "${SYMLINK_POINT_}" ${SYMLINK_POINT_INDEX_} ${SYMLINK_POINT_LENGTH_} SYMLINK_POINT_) + + # check if path is relative or absolute + string(SUBSTRING "${SYMLINK_POINT_}" 0 1 SYMLINK_IS_ABSOLUTE_) + + if(${SYMLINK_IS_ABSOLUTE_} STREQUAL "/") + # prevent absolute paths from having /../ or /./ section inside of them + get_filename_component(SYMLINK_POINT_ "${SYMLINK_POINT_}" ABSOLUTE) + else() + # handle relative path + get_filename_component(SYMLINK_POINT_ "${SYMLINK_LOCATION_}/${SYMLINK_POINT_}" ABSOLUTE) + endif() + + # recalculate path length after conversion to canonical form + string(LENGTH "${SYMLINK_POINT_}" SYMLINK_POINT_LENGTH_) + + if(SYMLINK_POINT_ MATCHES "${WDIR}/.*") + # only symlinks that are pointing inside the packaging structure should be checked for relocation + string(SUBSTRING "${SYMLINK_POINT_}" ${WDR_LEN_} -1 SYMLINK_POINT_WD_) + cpack_rpm_symlink_get_relocation_prefixes("${F}" "${PACKAGE_PREFIXES}" "SYMLINK_RELOCATIONS") + cpack_rpm_symlink_get_relocation_prefixes("${SYMLINK_POINT_WD_}" "${PACKAGE_PREFIXES}" "POINT_RELOCATIONS") + + list(LENGTH SYMLINK_RELOCATIONS SYMLINK_RELOCATIONS_COUNT) + list(LENGTH POINT_RELOCATIONS POINT_RELOCATIONS_COUNT) + else() + # location pointed to is ouside WDR so it should be treated as a permanent symlink + set(SYMLINK_POINT_WD_ "${SYMLINK_POINT_}") + + unset(SYMLINK_RELOCATIONS) + unset(POINT_RELOCATIONS) + unset(SYMLINK_RELOCATIONS_COUNT) + unset(POINT_RELOCATIONS_COUNT) + + message(AUTHOR_WARNING "CPackRPM:Warning: Symbolic link '${F}' points to location that is outside packaging path! Link will possibly not be relocatable.") + endif() + + if(SYMLINK_RELOCATIONS_COUNT AND POINT_RELOCATIONS_COUNT) + # find matching + foreach(SYMLINK_RELOCATION_PREFIX IN LISTS SYMLINK_RELOCATIONS) + list(FIND POINT_RELOCATIONS "${SYMLINK_RELOCATION_PREFIX}" FOUND_INDEX) + if(NOT ${FOUND_INDEX} EQUAL -1) + break() + endif() + endforeach() + + if(NOT ${FOUND_INDEX} EQUAL -1) + # symlinks have the same subpath + if(${SYMLINK_RELOCATIONS_COUNT} EQUAL 1 AND ${POINT_RELOCATIONS_COUNT} EQUAL 1) + # permanent symlink + get_filename_component(SYMLINK_LOCATION_ "${F}" DIRECTORY) + file(RELATIVE_PATH FINAL_PATH_ ${SYMLINK_LOCATION_} ${SYMLINK_POINT_WD_}) + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${FINAL_PATH_}" "${WDIR}/${F}") + else() + # relocation subpaths + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + else() + # not on the same relocation path + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + endif() + elseif(POINT_RELOCATIONS_COUNT) + # point is relocatable + cpack_rpm_symlink_add_for_relocation_script("${PACKAGE_PREFIXES}" "${F}" "${SYMLINK_RELOCATIONS}" + "${SYMLINK_POINT_WD_}" "${POINT_RELOCATIONS}") + else() + # is not relocatable or points to non relocatable path - permanent symlink + execute_process(COMMAND "${CMAKE_COMMAND}" -E create_symlink "${SYMLINK_POINT_WD_}" "${WDIR}/${F}") + endif() + endif() + elseif(IS_DIRECTORY "${WDIR}/${F}") + set(DIRECTIVE "%dir ") + endif() + + string(APPEND INSTALL_FILES "${DIRECTIVE}\"${F}\"\n") + endforeach() + + if(REQUIRES_SYMLINK_RELOCATION_SCRIPT) + cpack_rpm_symlink_create_relocation_script("${PACKAGE_PREFIXES}") + endif() + + set(RPM_SYMLINK_POSTINSTALL "${RPM_SYMLINK_POSTINSTALL}" PARENT_SCOPE) + set(CPACK_RPM_INSTALL_FILES "${INSTALL_FILES}" PARENT_SCOPE) +endfunction() + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackRPM.cmake may only be used by CPack internally.") +endif() + +if(NOT UNIX) + message(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.") +endif() + +# We need to check if the binaries were compiled with debug symbols +# because without them the package will be useless +function(cpack_rpm_debugsymbol_check INSTALL_FILES WORKING_DIR) + if(NOT CPACK_BUILD_SOURCE_DIRS) + message(FATAL_ERROR "CPackRPM: CPACK_BUILD_SOURCE_DIRS variable is not set!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + # With objdump we should check the debug symbols + find_program(OBJDUMP_EXECUTABLE objdump) + if(NOT OBJDUMP_EXECUTABLE) + message(FATAL_ERROR "CPackRPM: objdump binary could not be found!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + # With debugedit we prepare source files list + find_program(DEBUGEDIT_EXECUTABLE debugedit "/usr/lib/rpm/") + if(NOT DEBUGEDIT_EXECUTABLE) + message(FATAL_ERROR "CPackRPM: debugedit binary could not be found!" + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + unset(mkdir_list_) + unset(cp_list_) + unset(additional_sources_) + + foreach(F IN LISTS INSTALL_FILES) + if(IS_DIRECTORY "${WORKING_DIR}/${F}" OR IS_SYMLINK "${WORKING_DIR}/${F}") + continue() + endif() + + execute_process(COMMAND "${OBJDUMP_EXECUTABLE}" -h ${WORKING_DIR}/${F} + WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}" + RESULT_VARIABLE OBJDUMP_EXEC_RESULT + OUTPUT_VARIABLE OBJDUMP_OUT + ERROR_QUIET) + # Check if the given file is an executable or not + if(NOT OBJDUMP_EXEC_RESULT) + string(FIND "${OBJDUMP_OUT}" "debug" FIND_RESULT) + if(FIND_RESULT GREATER -1) + set(index_ 0) + foreach(source_dir_ IN LISTS CPACK_BUILD_SOURCE_DIRS) + string(LENGTH "${source_dir_}" source_dir_len_) + string(LENGTH "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" debuginfo_dir_len) + if(source_dir_len_ LESS debuginfo_dir_len) + message(FATAL_ERROR "CPackRPM: source dir path '${source_dir_}' is" + " shorter than debuginfo sources dir path '${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}'!" + " Source dir path must be longer than debuginfo sources dir path." + " Set CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX variable to a shorter value" + " or make source dir path longer." + " Required for debuginfo packaging. See documentation of" + " CPACK_RPM_DEBUGINFO_PACKAGE variable for details.") + endif() + + file(REMOVE "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list") + execute_process(COMMAND "${DEBUGEDIT_EXECUTABLE}" -b "${source_dir_}" -d "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}" -i -l "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list" "${WORKING_DIR}/${F}" + RESULT_VARIABLE res_ + OUTPUT_VARIABLE opt_ + ERROR_VARIABLE err_ + ) + + file(STRINGS + "${CPACK_RPM_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}/debugsources_add.list" + sources_) + list(REMOVE_DUPLICATES sources_) + + foreach(source_ IN LISTS sources_) + if(EXISTS "${source_dir_}/${source_}" AND NOT IS_DIRECTORY "${source_dir_}/${source_}") + get_filename_component(path_part_ "${source_}" DIRECTORY) + list(APPEND mkdir_list_ "%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}") + list(APPEND cp_list_ "cp \"${source_dir_}/${source_}\" \"%{buildroot}${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${path_part_}\"") + + list(APPEND additional_sources_ "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}/src_${index_}/${source_}") + endif() + endforeach() + + math(EXPR index_ "${index_} + 1") + endforeach() + else() + message(WARNING "CPackRPM: File: ${F} does not contain debug symbols. They will possibly be missing from debuginfo package!") + endif() + + get_file_permissions("${WORKING_DIR}/${F}" permissions_) + if(NOT "USER_EXECUTE" IN_LIST permissions_ AND + NOT "GROUP_EXECUTE" IN_LIST permissions_ AND + NOT "WORLD_EXECUTE" IN_LIST permissions_) + if(CPACK_RPM_INSTALL_WITH_EXEC) + execute_process(COMMAND chmod a+x ${WORKING_DIR}/${F} + RESULT_VARIABLE res_ + ERROR_VARIABLE err_ + OUTPUT_QUIET) + + if(res_) + message(FATAL_ERROR "CPackRPM: could not apply execute permissions " + "requested by CPACK_RPM_INSTALL_WITH_EXEC variable on " + "'${WORKING_DIR}/${F}'! Reason: '${err_}'") + endif() + else() + message(AUTHOR_WARNING "CPackRPM: File: ${WORKING_DIR}/${F} does not " + "have execute permissions. Debuginfo symbols will not be extracted" + "! Missing debuginfo may cause packaging failure. Consider setting " + "execute permissions or setting 'CPACK_RPM_INSTALL_WITH_EXEC' " + "variable.") + endif() + endif() + endif() + endforeach() + + list(LENGTH mkdir_list_ len_) + if(len_) + list(REMOVE_DUPLICATES mkdir_list_) + unset(TMP_RPM_DEBUGINFO_INSTALL) + foreach(part_ IN LISTS mkdir_list_) + string(APPEND TMP_RPM_DEBUGINFO_INSTALL "mkdir -p \"${part_}\"\n") + endforeach() + endif() + + list(LENGTH cp_list_ len_) + if(len_) + list(REMOVE_DUPLICATES cp_list_) + foreach(part_ IN LISTS cp_list_) + string(APPEND TMP_RPM_DEBUGINFO_INSTALL "${part_}\n") + endforeach() + endif() + + if(NOT DEFINED CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS) + set(CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS /usr /usr/src /usr/src/debug) + if(CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Adding ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION} to builtin omit list.") + endif() + list(APPEND CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS "${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS_ADDITION}") + endif() + endif() + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS= ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS}") + endif() + + list(LENGTH additional_sources_ len_) + if(len_) + list(REMOVE_DUPLICATES additional_sources_) + unset(additional_sources_all_) + foreach(source_ IN LISTS additional_sources_) + string(REPLACE "/" ";" split_source_ " ${source_}") + list(REMOVE_AT split_source_ 0) + unset(tmp_path_) + # Now generate all segments of the path + foreach(segment_ IN LISTS split_source_) + string(APPEND tmp_path_ "/${segment_}") + list(APPEND additional_sources_all_ "${tmp_path_}") + endforeach() + endforeach() + + list(REMOVE_DUPLICATES additional_sources_all_) + list(REMOVE_ITEM additional_sources_all_ + ${CPACK_RPM_DEBUGINFO_EXCLUDE_DIRS}) + + unset(TMP_DEBUGINFO_ADDITIONAL_SOURCES) + foreach(source_ IN LISTS additional_sources_all_) + string(APPEND TMP_DEBUGINFO_ADDITIONAL_SOURCES "${source_}\n") + endforeach() + endif() + + set(TMP_RPM_DEBUGINFO_INSTALL "${TMP_RPM_DEBUGINFO_INSTALL}" PARENT_SCOPE) + set(TMP_DEBUGINFO_ADDITIONAL_SOURCES "${TMP_DEBUGINFO_ADDITIONAL_SOURCES}" + PARENT_SCOPE) +endfunction() + +function(cpack_rpm_variable_fallback OUTPUT_VAR_NAME) + set(FALLBACK_VAR_NAMES ${ARGN}) + + foreach(variable_name IN LISTS FALLBACK_VAR_NAMES) + if(${variable_name}) + set(${OUTPUT_VAR_NAME} "${${variable_name}}" PARENT_SCOPE) + break() + endif() + endforeach() +endfunction() + +function(cpack_rpm_generate_package) + # rpmbuild is the basic command for building RPM package + # it may be a simple (symbolic) link to rpm command. + find_program(RPMBUILD_EXECUTABLE rpmbuild) + + # Check version of the rpmbuild tool this would be easier to + # track bugs with users and CPackRPM debug mode. + # We may use RPM version in order to check for available version dependent features + if(RPMBUILD_EXECUTABLE) + execute_process(COMMAND ${RPMBUILD_EXECUTABLE} --version + OUTPUT_VARIABLE _TMP_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "^.* " "" + RPMBUILD_EXECUTABLE_VERSION + ${_TMP_VERSION}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>") + endif() + endif() + + if(NOT RPMBUILD_EXECUTABLE) + message(FATAL_ERROR "RPM package requires rpmbuild executable") + endif() + + # Display lsb_release output if DEBUG mode enable + # This will help to diagnose problem with CPackRPM + # because we will know on which kind of Linux we are + if(CPACK_RPM_PACKAGE_DEBUG) + find_program(LSB_RELEASE_EXECUTABLE lsb_release) + if(LSB_RELEASE_EXECUTABLE) + execute_process(COMMAND ${LSB_RELEASE_EXECUTABLE} -a + OUTPUT_VARIABLE _TMP_LSB_RELEASE_OUTPUT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REGEX REPLACE "\n" ", " + LSB_RELEASE_OUTPUT + ${_TMP_LSB_RELEASE_OUTPUT}) + else () + set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!") + endif() + message("CPackRPM:Debug: LSB_RELEASE = ${LSB_RELEASE_OUTPUT}") + endif() + + # We may use RPM version in the future in order + # to shut down warning about space in buildtree + # some recent RPM version should support space in different places. + # not checked [yet]. + if(CPACK_TOPLEVEL_DIRECTORY MATCHES ".* .*") + message(FATAL_ERROR "${RPMBUILD_EXECUTABLE} can't handle paths with spaces, use a build directory without spaces for building RPMs.") + endif() + + # If rpmbuild is found + # we try to discover alien since we may be on non RPM distro like Debian. + # In this case we may try to to use more advanced features + # like generating RPM directly from DEB using alien. + # FIXME feature not finished (yet) + find_program(ALIEN_EXECUTABLE alien) + if(ALIEN_EXECUTABLE) + message(STATUS "alien found, we may be on a Debian based distro.") + endif() + + # Are we packaging components ? + if(CPACK_RPM_PACKAGE_COMPONENT) + string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) + endif() + + set(WDIR "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}") + + # + # Use user-defined RPM specific variables value + # or generate reasonable default value from + # CPACK_xxx generic values. + # The variables comes from the needed (mandatory or not) + # values found in the RPM specification file aka ".spec" file. + # The variables which may/should be defined are: + # + + # CPACK_RPM_PACKAGE_SUMMARY (mandatory) + + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_SUMMARY" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_SUMMARY") + endif() + + if(NOT CPACK_RPM_PACKAGE_SUMMARY) + if(CPACK_PACKAGE_DESCRIPTION_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + else() + # if neither var is defined lets use the name as summary + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) + endif() + endif() + + if(NOT CPACK_RPM_PACKAGE_URL AND CMAKE_PROJECT_HOMEPAGE_URL) + set(CPACK_RPM_PACKAGE_URL "${CMAKE_PROJECT_HOMEPAGE_URL}") + endif() + + # CPACK_RPM_PACKAGE_NAME (mandatory) + if(NOT CPACK_RPM_PACKAGE_NAME) + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) + endif() + + if(CPACK_RPM_PACKAGE_COMPONENT) + string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}" + CPACK_RPM_MAIN_COMPONENT_UPPER) + + if(NOT CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER) + string(APPEND CPACK_RPM_PACKAGE_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") + + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_NAME") + endif() + endif() + + # CPACK_RPM_PACKAGE_VERSION (mandatory) + if(NOT CPACK_RPM_PACKAGE_VERSION) + if(NOT CPACK_PACKAGE_VERSION) + message(FATAL_ERROR "RPM package requires a package version") + endif() + set(CPACK_RPM_PACKAGE_VERSION ${CPACK_PACKAGE_VERSION}) + endif() + # Replace '-' in version with '_' + # '-' character is an Illegal RPM version character + # it is illegal because it is used to separate + # RPM "Version" from RPM "Release" + string(REPLACE "-" "_" CPACK_RPM_PACKAGE_VERSION ${CPACK_RPM_PACKAGE_VERSION}) + + # CPACK_RPM_PACKAGE_ARCHITECTURE (mandatory) + if(NOT CPACK_RPM_PACKAGE_ARCHITECTURE) + execute_process(COMMAND uname "-m" + OUTPUT_VARIABLE CPACK_RPM_PACKAGE_ARCHITECTURE + OUTPUT_STRIP_TRAILING_WHITESPACE) + else() + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}") + endif() + endif() + + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_ARCHITECTURE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_ARCHITECTURE") + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using component build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}") + endif() + endif() + + if(${CPACK_RPM_PACKAGE_ARCHITECTURE} STREQUAL "noarch") + set(TMP_RPM_BUILDARCH "Buildarch: ${CPACK_RPM_PACKAGE_ARCHITECTURE}") + else() + set(TMP_RPM_BUILDARCH "") + endif() + + # CPACK_RPM_PACKAGE_RELEASE + # The RPM release is the numbering of the RPM package ITSELF + # this is the version of the PACKAGING and NOT the version + # of the CONTENT of the package. + # You may well need to generate a new RPM package release + # without changing the version of the packaged software. + # This is the case when the packaging is buggy (not) the software :=) + # If not set, 1 is a good candidate + if(NOT CPACK_RPM_PACKAGE_RELEASE) + set(CPACK_RPM_PACKAGE_RELEASE "1") + endif() + + if(CPACK_RPM_PACKAGE_RELEASE_DIST) + string(APPEND CPACK_RPM_PACKAGE_RELEASE "%{?dist}") + endif() + + # CPACK_RPM_PACKAGE_LICENSE + if(NOT CPACK_RPM_PACKAGE_LICENSE) + set(CPACK_RPM_PACKAGE_LICENSE "unknown") + endif() + + # CPACK_RPM_PACKAGE_GROUP + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_GROUP" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_GROUP" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_GROUP") + endif() + + if(NOT CPACK_RPM_PACKAGE_GROUP) + set(CPACK_RPM_PACKAGE_GROUP "unknown") + endif() + + # CPACK_RPM_PACKAGE_VENDOR + if(NOT CPACK_RPM_PACKAGE_VENDOR) + if(CPACK_PACKAGE_VENDOR) + set(CPACK_RPM_PACKAGE_VENDOR "${CPACK_PACKAGE_VENDOR}") + else() + set(CPACK_RPM_PACKAGE_VENDOR "unknown") + endif() + endif() + + # CPACK_RPM_PACKAGE_SOURCE + # The name of the source tarball in case we generate a source RPM + + # CPACK_RPM_PACKAGE_DESCRIPTION + # The variable content may be either + # - explicitly given by the user or + # - filled with the content of CPACK_PACKAGE_DESCRIPTION_FILE + # if it is defined + # - set to a default value + # + + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_DESCRIPTION" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_DESCRIPTION" + "CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION") + endif() + + if(NOT CPACK_RPM_PACKAGE_DESCRIPTION) + if(CPACK_PACKAGE_DESCRIPTION_FILE) + file(READ ${CPACK_PACKAGE_DESCRIPTION_FILE} CPACK_RPM_PACKAGE_DESCRIPTION) + else () + set(CPACK_RPM_PACKAGE_DESCRIPTION "no package description available") + endif () + endif () + + # CPACK_RPM_COMPRESSION_TYPE + # + if (CPACK_RPM_COMPRESSION_TYPE) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User Specified RPM compression type: ${CPACK_RPM_COMPRESSION_TYPE}") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "lzma") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.lzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "xz") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w7.xzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "bzip2") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.bzdio") + endif() + if(CPACK_RPM_COMPRESSION_TYPE STREQUAL "gzip") + set(CPACK_RPM_COMPRESSION_TYPE_TMP "%define _binary_payload w9.gzdio") + endif() + else() + set(CPACK_RPM_COMPRESSION_TYPE_TMP "") + endif() + + if(NOT CPACK_RPM_PACKAGE_SOURCES) + if(CPACK_PACKAGE_RELOCATABLE OR CPACK_RPM_PACKAGE_RELOCATABLE) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Trying to build a relocatable package") + endif() + 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.") + set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE) + else() + set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files) + cpack_rpm_prepare_relocation_paths() + set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) + endif() + endif() + else() + if(CPACK_RPM_PACKAGE_COMPONENT) + message(FATAL_ERROR "CPACK_RPM_PACKAGE_SOURCES parameter can not be used" + " in combination with CPACK_RPM_PACKAGE_COMPONENT parameter!") + endif() + + set(CPACK_RPM_PACKAGE_RELOCATABLE FALSE) # disable relocatable option if building source RPM + endif() + + execute_process( + COMMAND "${RPMBUILD_EXECUTABLE}" --querytags + OUTPUT_VARIABLE RPMBUILD_TAG_LIST + OUTPUT_STRIP_TRAILING_WHITESPACE) + string(REPLACE "\n" ";" RPMBUILD_TAG_LIST "${RPMBUILD_TAG_LIST}") + + if(CPACK_RPM_PACKAGE_EPOCH) + set(TMP_RPM_EPOCH "Epoch: ${CPACK_RPM_PACKAGE_EPOCH}") + endif() + + # Check if additional fields for RPM spec header are given + # There may be some COMPONENT specific variables as well + # If component specific var is not provided we use the global one + # for each component + foreach(_RPM_SPEC_HEADER URL REQUIRES SUGGESTS PROVIDES OBSOLETES PREFIX CONFLICTS AUTOPROV AUTOREQ AUTOREQPROV REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}") + endif() + + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_PACKAGE_${_RPM_SPEC_HEADER}") + endif() + + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + # Prefix can be replaced by Prefixes but the old version still works so we'll ignore it for now + # Requires* is a special case because it gets transformed to Requires(pre/post/preun/postun) + # Auto* is a special case because the tags can not be queried by querytags rpmbuild flag + set(special_case_tags_ PREFIX REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN AUTOPROV AUTOREQ AUTOREQPROV) + if(NOT _RPM_SPEC_HEADER IN_LIST RPMBUILD_TAG_LIST AND NOT _RPM_SPEC_HEADER IN_LIST special_case_tags_) + message(AUTHOR_WARNING "CPackRPM:Warning: ${_RPM_SPEC_HEADER} not " + "supported in provided rpmbuild. Tag will not be used.") + continue() + endif() + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + endif() + + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) + endif() + + # Treat the RPM Spec keyword iff it has been properly defined + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) + # Transform NAME --> Name e.g. PROVIDES --> Provides + # The Upper-case first letter and lowercase tail is the + # appropriate value required in the final RPM spec file. + string(SUBSTRING ${_RPM_SPEC_HEADER} 1 -1 _PACKAGE_HEADER_TAIL) + string(TOLOWER "${_PACKAGE_HEADER_TAIL}" _PACKAGE_HEADER_TAIL) + string(SUBSTRING ${_RPM_SPEC_HEADER} 0 1 _PACKAGE_HEADER_NAME) + string(APPEND _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_TAIL}") + # The following keywords require parentheses around the "pre" or "post" suffix in the final RPM spec file. + set(SCRIPTS_REQUIREMENTS_LIST REQUIRES_PRE REQUIRES_POST REQUIRES_PREUN REQUIRES_POSTUN) + list(FIND SCRIPTS_REQUIREMENTS_LIST ${_RPM_SPEC_HEADER} IS_SCRIPTS_REQUIREMENT_FOUND) + if(NOT ${IS_SCRIPTS_REQUIREMENT_FOUND} EQUAL -1) + string(REPLACE "_" "(" _PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME}") + string(APPEND _PACKAGE_HEADER_NAME ")") + endif() + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User defined ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") + endif() + set(TMP_RPM_${_RPM_SPEC_HEADER} "${_PACKAGE_HEADER_NAME}: ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") + unset(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP) + endif() + endforeach() + + # CPACK_RPM_SPEC_INSTALL_POST + # May be used to define a RPM post intallation script + # for example setting it to "/bin/true" may prevent + # rpmbuild from stripping binaries. + if(CPACK_RPM_SPEC_INSTALL_POST) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}") + endif() + set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}") + endif() + + # CPACK_RPM_POST_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_INSTALL_SCRIPT_FILE) + # CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_POST_UNINSTALL_SCRIPT_FILE) + # May be used to embed a post (un)installation script in the spec file. + # The referred script file(s) will be read and directly + # put after the %post or %postun section + # ---------------------------------------------------------------- + # CPACK_RPM_PRE_INSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_INSTALL_SCRIPT_FILE) + # CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE (or CPACK_RPM_<COMPONENT>_PRE_UNINSTALL_SCRIPT_FILE) + # May be used to embed a pre (un)installation script in the spec file. + # The referred script file(s) will be read and directly + # put after the %pre or %preun section + foreach(RPM_SCRIPT_FILE_TYPE_ "INSTALL" "UNINSTALL") + foreach(RPM_SCRIPT_FILE_TIME_ "PRE" "POST") + set("CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE" + "${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE}") + + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE") + endif() + + # Handle file if it has been specified + if(CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE) + if(EXISTS ${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE}) + file(READ ${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE} + "CPACK_RPM_SPEC_${RPM_SCRIPT_FILE_TIME_}${RPM_SCRIPT_FILE_TYPE_}") + else() + message("CPackRPM:Warning: CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_SCRIPT_FILE <${CPACK_RPM_${RPM_SCRIPT_FILE_TIME_}_${RPM_SCRIPT_FILE_TYPE_}_READ_FILE}> does not exists - ignoring") + endif() + else() + # reset SPEC var value if no file has been specified + # (either globally or component-wise) + set("CPACK_RPM_SPEC_${RPM_SCRIPT_FILE_TIME_}${RPM_SCRIPT_FILE_TYPE_}" "") + endif() + endforeach() + endforeach() + + # CPACK_RPM_CHANGELOG_FILE + # May be used to embed a changelog in the spec file. + # The referred file will be read and directly put after the %changelog section + if(CPACK_RPM_CHANGELOG_FILE) + if(EXISTS ${CPACK_RPM_CHANGELOG_FILE}) + file(READ ${CPACK_RPM_CHANGELOG_FILE} CPACK_RPM_SPEC_CHANGELOG) + else() + message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring") + endif() + else() + set(CPACK_RPM_SPEC_CHANGELOG "* Sun Jul 4 2010 Eric Noulard <eric.noulard@gmail.com> - ${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}\n Generated by CPack RPM (no Changelog file were provided)") + endif() + + # CPACK_RPM_SPEC_MORE_DEFINE + # This is a generated spec rpm file spaceholder + if(CPACK_RPM_SPEC_MORE_DEFINE) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: User defined more define spec line specified:\n ${CPACK_RPM_SPEC_MORE_DEFINE}") + endif() + endif() + + # Now we may create the RPM build tree structure + set(CPACK_RPM_ROOTDIR "${CPACK_TOPLEVEL_DIRECTORY}") + message(STATUS "CPackRPM:Debug: Using CPACK_RPM_ROOTDIR=${CPACK_RPM_ROOTDIR}") + # Prepare RPM build tree + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/tmp) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/BUILD) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/RPMS) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SOURCES) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SPECS) + file(MAKE_DIRECTORY ${CPACK_RPM_ROOTDIR}/SRPMS) + + # it seems rpmbuild can't handle spaces in the path + # neither escaping (as below) nor putting quotes around the path seem to help + #string(REGEX REPLACE " " "\\\\ " CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") + set(CPACK_RPM_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}") + + cpack_rpm_prepare_content_list() + + # In component case, put CPACK_ABSOLUTE_DESTINATION_FILES_<COMPONENT> + # into CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + # otherwise, put CPACK_ABSOLUTE_DESTINATION_FILES + # This must be done BEFORE the CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL handling + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_ABSOLUTE_DESTINATION_FILES) + cpack_rpm_variable_fallback("COMPONENT_FILES_TAG" + "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}" + "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}") + set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${${COMPONENT_FILES_TAG}}") + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling Absolute Destination Files: <${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}>") + message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + endif() + endif() + else() + if(CPACK_ABSOLUTE_DESTINATION_FILES) + set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}") + endif() + endif() + + # In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST. + set(CPACK_RPM_USER_FILELIST_INTERNAL "") + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_USER_FILELIST_INTERNAL" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_USER_FILELIST") + + if(CPACK_RPM_PACKAGE_DEBUG AND CPACK_RPM_USER_FILELIST_INTERNAL) + message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") + message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + endif() + elseif(CPACK_RPM_USER_FILELIST) + set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}") + endif() + + # Handle user specified file line list in CPACK_RPM_USER_FILELIST_INTERNAL + # Remove those files from CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + # or CPACK_RPM_INSTALL_FILES, + # hence it must be done before these auto-generated lists are processed. + if(CPACK_RPM_USER_FILELIST_INTERNAL) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") + endif() + + # Create CMake list from CPACK_RPM_INSTALL_FILES + string(STRIP "${CPACK_RPM_INSTALL_FILES}" CPACK_RPM_INSTALL_FILES_LIST) + string(REPLACE "\n" ";" CPACK_RPM_INSTALL_FILES_LIST + "${CPACK_RPM_INSTALL_FILES_LIST}") + string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST + "${CPACK_RPM_INSTALL_FILES_LIST}") + + set(CPACK_RPM_USER_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_USER_FILELIST_INTERNAL) + string(REGEX REPLACE "%[A-Za-z]+(\\([^()]*\\))? " "" F_PATH ${F}) + string(REGEX MATCH "(%[A-Za-z]+(\\([^()]*\\))? )*" F_PREFIX ${F}) + string(STRIP ${F_PREFIX} F_PREFIX) + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>") + endif() + if(F_PREFIX) + string(APPEND F_PREFIX " ") + endif() + # Rebuild the user list file + string(APPEND CPACK_RPM_USER_INSTALL_FILES "${F_PREFIX}\"${F_PATH}\"\n") + + # Remove from CPACK_RPM_INSTALL_FILES and CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${F_PATH}) + # ABSOLUTE destination files list may not exists at all + if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + list(REMOVE_ITEM CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL ${F_PATH}) + endif() + endforeach() + + # Rebuild CPACK_RPM_INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + string(APPEND CPACK_RPM_INSTALL_FILES "\"${F}\"\n") + endforeach() + else() + set(CPACK_RPM_USER_INSTALL_FILES "") + endif() + + if (CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling Absolute Destination Files: ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}") + endif() + # 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 unnecessary 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_INTERNAL}) + # Rebuild INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + string(APPEND CPACK_RPM_INSTALL_FILES "\"${F}\"\n") + endforeach() + # Build ABSOLUTE_INSTALL_FILES + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + string(APPEND CPACK_RPM_ABSOLUTE_INSTALL_FILES "%config \"${F}\"\n") + endforeach() + 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() + else() + # reset vars in order to avoid leakage of value(s) from one component to another + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + endif() + + cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_PACKAGE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_PACKAGE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_PACKAGE" + "CPACK_RPM_DEBUGINFO_PACKAGE") + if(CPACK_RPM_DEBUGINFO_PACKAGE OR (CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND NOT GENERATE_SPEC_PARTS)) + cpack_rpm_variable_fallback("CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_BUILD_SOURCE_DIRS_PREFIX" + "CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX") + if(NOT CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX) + set(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX "/usr/src/debug/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}") + endif() + + # handle cases where path contains extra slashes (e.g. /a//b/ instead of + # /a/b) + get_filename_component(CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX + "${CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX}" ABSOLUTE) + + if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS) + file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.files" + "${CPACK_RPM_INSTALL_FILES}") + else() + if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND CPACK_RPM_PACKAGE_COMPONENT) + # this part is only required by components packaging - with monolithic + # packages we can be certain that there are no other components present + # so CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE is a noop + if(CPACK_RPM_DEBUGINFO_PACKAGE) + # only add current package files to debuginfo list if debuginfo + # generation is enabled for current package + string(STRIP "${CPACK_RPM_INSTALL_FILES}" install_files_) + string(REPLACE "\n" ";" install_files_ "${install_files_}") + string(REPLACE "\"" "" install_files_ "${install_files_}") + else() + unset(install_files_) + endif() + + file(GLOB files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.files") + + foreach(f_ IN LISTS files_) + file(READ "${f_}" tmp_) + string(APPEND install_files_ ";${tmp_}") + endforeach() + + # if there were other components/groups so we need to move files from them + # to current component otherwise those files won't be found + file(GLOB components_ LIST_DIRECTORIES true RELATIVE + "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}" + "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/*") + foreach(component_ IN LISTS components_) + string(TOUPPER "${component_}" component_dir_upper_) + if(component_dir_upper_ STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER) + # skip current component + continue() + endif() + + file(GLOB_RECURSE files_for_move_ LIST_DIRECTORIES false RELATIVE + "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}" + "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/*") + + foreach(f_ IN LISTS files_for_move_) + get_filename_component(dir_path_ "${f_}" DIRECTORY) + set(src_file_ + "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}/${component_}/${f_}") + + # check that we are not overriding an existing file that doesn't + # match the file that we want to copy + if(EXISTS "${src_file_}" AND EXISTS "${WDIR}/${f_}") + execute_process( + COMMAND ${CMAKE_COMMAND} -E compare_files "${src_file_}" "${WDIR}/${f_}" + RESULT_VARIABLE res_ + ) + if(res_) + message(FATAL_ERROR "CPackRPM:Error: File on path '${WDIR}/${f_}'" + " already exists but is a different than the one in component" + " '${component_}'! Packages will not be generated.") + endif() + endif() + + file(MAKE_DIRECTORY "${WDIR}/${dir_path_}") + file(RENAME "${src_file_}" + "${WDIR}/${f_}") + endforeach() + endforeach() + + cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}") + else() + string(STRIP "${CPACK_RPM_INSTALL_FILES}" install_files_) + string(REPLACE "\n" ";" install_files_ "${install_files_}") + string(REPLACE "\"" "" install_files_ "${install_files_}") + + cpack_rpm_debugsymbol_check("${install_files_}" "${WDIR}") + endif() + + if(TMP_DEBUGINFO_ADDITIONAL_SOURCES) + set(TMP_RPM_DEBUGINFO " +# Modified version of %%debug_package macro +# defined in /usr/lib/rpm/macros as that one +# can't handle injection of extra source files. +%ifnarch noarch +%global __debug_package 1 +%package debuginfo +Summary: Debug information for package %{name} +Group: Development/Debug +AutoReqProv: 0 +%description debuginfo +This package provides debug information for package %{name}. +Debug information is useful when developing applications that use this +package or when debugging this package. +%files debuginfo -f debugfiles.list +%defattr(-,root,root) +${TMP_DEBUGINFO_ADDITIONAL_SOURCES} +%endif +") + elseif(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE) + message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested" + " but will not be generated as no source files were found!") + else() + message(AUTHOR_WARNING "CPackRPM:Warning: debuginfo package was requested" + " but will not be generated as no source files were found! Component: '" + "${CPACK_RPM_PACKAGE_COMPONENT}'.") + endif() + endif() + endif() + + # Prepare install files + cpack_rpm_prepare_install_files( + "${CPACK_RPM_INSTALL_FILES}" + "${WDIR}" + "${RPM_USED_PACKAGE_PREFIXES}" + "${CPACK_RPM_PACKAGE_RELOCATABLE}" + ) + + # set default user and group + foreach(_PERM_TYPE "USER" "GROUP") + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEFAULT_${_PERM_TYPE}) + set(TMP_DEFAULT_${_PERM_TYPE} "${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEFAULT_${_PERM_TYPE}}") + elseif(CPACK_RPM_DEFAULT_${_PERM_TYPE}) + set(TMP_DEFAULT_${_PERM_TYPE} "${CPACK_RPM_DEFAULT_${_PERM_TYPE}}") + else() + set(TMP_DEFAULT_${_PERM_TYPE} "root") + endif() + endforeach() + + # set default file and dir permissions + foreach(_PERM_TYPE "FILE" "DIR") + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEFAULT_${_PERM_TYPE}_PERMISSIONS) + get_unix_permissions_octal_notation("CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEFAULT_${_PERM_TYPE}_PERMISSIONS" "TMP_DEFAULT_${_PERM_TYPE}_PERMISSIONS") + set(_PERMISSIONS_VAR "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEFAULT_${_PERM_TYPE}_PERMISSIONS") + elseif(CPACK_RPM_DEFAULT_${_PERM_TYPE}_PERMISSIONS) + get_unix_permissions_octal_notation("CPACK_RPM_DEFAULT_${_PERM_TYPE}_PERMISSIONS" "TMP_DEFAULT_${_PERM_TYPE}_PERMISSIONS") + set(_PERMISSIONS_VAR "CPACK_RPM_DEFAULT_${_PERM_TYPE}_PERMISSIONS") + else() + set(TMP_DEFAULT_${_PERM_TYPE}_PERMISSIONS "-") + endif() + endforeach() + + # 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") + + # Print out some debug information if we were asked for that + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_TOPLEVEL_DIRECTORY = ${CPACK_TOPLEVEL_DIRECTORY}") + message("CPackRPM:Debug: CPACK_TOPLEVEL_TAG = ${CPACK_TOPLEVEL_TAG}") + message("CPackRPM:Debug: CPACK_TEMPORARY_DIRECTORY = ${CPACK_TEMPORARY_DIRECTORY}") + message("CPackRPM:Debug: CPACK_OUTPUT_FILE_NAME = ${CPACK_OUTPUT_FILE_NAME}") + message("CPackRPM:Debug: CPACK_OUTPUT_FILE_PATH = ${CPACK_OUTPUT_FILE_PATH}") + message("CPackRPM:Debug: CPACK_PACKAGE_FILE_NAME = ${CPACK_PACKAGE_FILE_NAME}") + message("CPackRPM:Debug: CPACK_RPM_BINARY_SPECFILE = ${CPACK_RPM_BINARY_SPECFILE}") + message("CPackRPM:Debug: CPACK_PACKAGE_INSTALL_DIRECTORY = ${CPACK_PACKAGE_INSTALL_DIRECTORY}") + message("CPackRPM:Debug: CPACK_TEMPORARY_PACKAGE_FILE_NAME = ${CPACK_TEMPORARY_PACKAGE_FILE_NAME}") + endif() + + # + # USER generated/provided spec file handling. + # + + # We can have a component specific spec file. + if(CPACK_RPM_PACKAGE_COMPONENT) + cpack_rpm_variable_fallback("CPACK_RPM_USER_BINARY_SPECFILE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_USER_BINARY_SPECFILE") + endif() + + cpack_rpm_variable_fallback("CPACK_RPM_FILE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_FILE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_FILE_NAME" + "CPACK_RPM_FILE_NAME") + if(NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT") + if(CPACK_RPM_FILE_NAME) + if(NOT CPACK_RPM_FILE_NAME MATCHES ".*\\.rpm") + message(FATAL_ERROR "'${CPACK_RPM_FILE_NAME}' is not a valid RPM package file name as it must end with '.rpm'!") + endif() + else() + # old file name format for back compatibility + string(TOUPPER "${CPACK_RPM_MAIN_COMPONENT}" + CPACK_RPM_MAIN_COMPONENT_UPPER) + + if(CPACK_RPM_MAIN_COMPONENT_UPPER STREQUAL CPACK_RPM_PACKAGE_COMPONENT_UPPER) + # this is the main component so ignore the component filename part + set(CPACK_RPM_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.rpm") + else() + set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}") + endif() + endif() + # else example: + #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm") + + if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE AND GENERATE_SPEC_PARTS) + string(TOLOWER "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm" expected_filename_) + + file(WRITE "${CPACK_RPM_ROOTDIR}/SPECS/${CPACK_RPM_PACKAGE_COMPONENT}.rpm_name" + "${expected_filename_};${CPACK_RPM_FILE_NAME}") + elseif(NOT CPACK_RPM_DEBUGINFO_PACKAGE) + set(FILE_NAME_DEFINE "%define _rpmfilename ${CPACK_RPM_FILE_NAME}") + endif() + endif() + + if(CPACK_RPM_PACKAGE_SOURCES) # source rpm + set(archive_name_ "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}") + + execute_process( + COMMAND ${CMAKE_COMMAND} -E tar "cfvz" "${CPACK_RPM_DIRECTORY}/SOURCES/${archive_name_}.tar.gz" "${CPACK_PACKAGE_FILE_NAME}" + WORKING_DIRECTORY ${CPACK_RPM_DIRECTORY} + ) + set(TMP_RPM_SOURCE "Source: ${archive_name_}.tar.gz") + + if(CPACK_RPM_BUILDREQUIRES) + set(TMP_RPM_BUILD_REQUIRES "BuildRequires: ${CPACK_RPM_BUILDREQUIRES}") + endif() + + # Disable debuginfo packages - srpm generates invalid packages due to + # releasing control to cpack to generate binary packages. + # Note however that this doesn't prevent cpack to generate debuginfo + # packages when run from srpm with --rebuild. + set(TMP_RPM_DISABLE_DEBUGINFO "%define debug_package %{nil}") + + if(NOT CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX) + set(CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX "/") + endif() + + set(TMP_RPM_BUILD + " +%build +mkdir cpack_rpm_build_dir +cd cpack_rpm_build_dir +'${CMAKE_COMMAND}' ${CPACK_RPM_SOURCE_PKG_BUILD_PARAMS} -DCPACK_PACKAGING_INSTALL_PREFIX=${CPACK_RPM_SOURCE_PKG_PACKAGING_INSTALL_PREFIX} ../${CPACK_PACKAGE_FILE_NAME} +make %{?_smp_mflags}" # %{?_smp_mflags} -> -j option + ) + set(TMP_RPM_INSTALL + " +cd cpack_rpm_build_dir +cpack -G RPM +mv *.rpm %_rpmdir" + ) + set(TMP_RPM_PREP "%setup -c") + + set(RPMBUILD_FLAGS "-bs") + + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in + "# Restore old style debuginfo creation for rpm >= 4.14. +%undefine _debugsource_packages +%undefine _debuginfo_subpackages + +# -*- rpm-spec -*- +BuildRoot: %_topdir/\@CPACK_PACKAGE_FILE_NAME\@ +Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@ +Name: \@CPACK_RPM_PACKAGE_NAME\@ +Version: \@CPACK_RPM_PACKAGE_VERSION\@ +Release: \@CPACK_RPM_PACKAGE_RELEASE\@ +License: \@CPACK_RPM_PACKAGE_LICENSE\@ +Group: \@CPACK_RPM_PACKAGE_GROUP\@ +Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ + +\@TMP_RPM_SOURCE\@ +\@TMP_RPM_BUILD_REQUIRES\@ +\@TMP_RPM_BUILDARCH\@ +\@TMP_RPM_PREFIXES\@ + +\@TMP_RPM_DISABLE_DEBUGINFO\@ + +%define _rpmdir %_topdir/RPMS +%define _srcrpmdir %_topdir/SRPMS +\@FILE_NAME_DEFINE\@ +%define _unpackaged_files_terminate_build 0 +\@TMP_RPM_SPEC_INSTALL_POST\@ +\@CPACK_RPM_SPEC_MORE_DEFINE\@ +\@CPACK_RPM_COMPRESSION_TYPE_TMP\@ + +%description +\@CPACK_RPM_PACKAGE_DESCRIPTION\@ + +# This is a shortcutted spec file generated by CMake RPM generator +# we skip _install step because CPack does that for us. +# We do only save CPack installed tree in _prepr +# and then restore it in build. +%prep +\@TMP_RPM_PREP\@ + +\@TMP_RPM_BUILD\@ + +#p build + +%install +\@TMP_RPM_INSTALL\@ + +%clean + +%changelog +\@CPACK_RPM_SPEC_CHANGELOG\@ +" + ) + + elseif(GENERATE_SPEC_PARTS) # binary rpm with single debuginfo package + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in + "# -*- rpm-spec -*- +%package -n \@CPACK_RPM_PACKAGE_NAME\@ +Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@ +Version: \@CPACK_RPM_PACKAGE_VERSION\@ +Release: \@CPACK_RPM_PACKAGE_RELEASE\@ +License: \@CPACK_RPM_PACKAGE_LICENSE\@ +Group: \@CPACK_RPM_PACKAGE_GROUP\@ +Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ + +\@TMP_RPM_URL\@ +\@TMP_RPM_REQUIRES\@ +\@TMP_RPM_REQUIRES_PRE\@ +\@TMP_RPM_REQUIRES_POST\@ +\@TMP_RPM_REQUIRES_PREUN\@ +\@TMP_RPM_REQUIRES_POSTUN\@ +\@TMP_RPM_PROVIDES\@ +\@TMP_RPM_OBSOLETES\@ +\@TMP_RPM_CONFLICTS\@ +\@TMP_RPM_SUGGESTS\@ +\@TMP_RPM_AUTOPROV\@ +\@TMP_RPM_AUTOREQ\@ +\@TMP_RPM_AUTOREQPROV\@ +\@TMP_RPM_BUILDARCH\@ +\@TMP_RPM_PREFIXES\@ +\@TMP_RPM_EPOCH\@ + +%description -n \@CPACK_RPM_PACKAGE_NAME\@ +\@CPACK_RPM_PACKAGE_DESCRIPTION\@ + +%files -n \@CPACK_RPM_PACKAGE_NAME\@ +%defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@) +\@CPACK_RPM_INSTALL_FILES\@ +\@CPACK_RPM_ABSOLUTE_INSTALL_FILES\@ +\@CPACK_RPM_USER_INSTALL_FILES\@ +" + ) + + else() # binary rpm + if(CPACK_RPM_DEBUGINFO_SINGLE_PACKAGE) + # find generated spec file and take its name + file(GLOB spec_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.spec") + + foreach(f_ IN LISTS spec_files_) + file(READ "${f_}" tmp_) + string(APPEND TMP_OTHER_COMPONENTS "\n${tmp_}\n") + endforeach() + endif() + + # We should generate a USER spec file template: + # - either because the user asked for it : CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE + # - or the user did not provide one : NOT CPACK_RPM_USER_BINARY_SPECFILE + set(RPMBUILD_FLAGS "-bb") + if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) + + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in + "# Restore old style debuginfo creation for rpm >= 4.14. +%undefine _debugsource_packages +%undefine _debuginfo_subpackages + +# -*- rpm-spec -*- +BuildRoot: %_topdir/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@ +Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@ +Name: \@CPACK_RPM_PACKAGE_NAME\@ +Version: \@CPACK_RPM_PACKAGE_VERSION\@ +Release: \@CPACK_RPM_PACKAGE_RELEASE\@ +License: \@CPACK_RPM_PACKAGE_LICENSE\@ +Group: \@CPACK_RPM_PACKAGE_GROUP\@ +Vendor: \@CPACK_RPM_PACKAGE_VENDOR\@ + +\@TMP_RPM_URL\@ +\@TMP_RPM_REQUIRES\@ +\@TMP_RPM_REQUIRES_PRE\@ +\@TMP_RPM_REQUIRES_POST\@ +\@TMP_RPM_REQUIRES_PREUN\@ +\@TMP_RPM_REQUIRES_POSTUN\@ +\@TMP_RPM_PROVIDES\@ +\@TMP_RPM_OBSOLETES\@ +\@TMP_RPM_CONFLICTS\@ +\@TMP_RPM_SUGGESTS\@ +\@TMP_RPM_AUTOPROV\@ +\@TMP_RPM_AUTOREQ\@ +\@TMP_RPM_AUTOREQPROV\@ +\@TMP_RPM_BUILDARCH\@ +\@TMP_RPM_PREFIXES\@ +\@TMP_RPM_EPOCH\@ + +\@TMP_RPM_DEBUGINFO\@ + +%define _rpmdir %_topdir/RPMS +%define _srcrpmdir %_topdir/SRPMS +\@FILE_NAME_DEFINE\@ +%define _unpackaged_files_terminate_build 0 +\@TMP_RPM_SPEC_INSTALL_POST\@ +\@CPACK_RPM_SPEC_MORE_DEFINE\@ +\@CPACK_RPM_COMPRESSION_TYPE_TMP\@ + +%description +\@CPACK_RPM_PACKAGE_DESCRIPTION\@ + +# This is a shortcutted spec file generated by CMake RPM generator +# we skip _install step because CPack does that for us. +# We do only save CPack installed tree in _prepr +# and then restore it in build. +%prep +mv $RPM_BUILD_ROOT %_topdir/tmpBBroot + +%install +if [ -e $RPM_BUILD_ROOT ]; +then + rm -rf $RPM_BUILD_ROOT +fi +mv %_topdir/tmpBBroot $RPM_BUILD_ROOT + +\@TMP_RPM_DEBUGINFO_INSTALL\@ + +%clean + +%post +\@RPM_SYMLINK_POSTINSTALL\@ +\@CPACK_RPM_SPEC_POSTINSTALL\@ + +%postun +\@CPACK_RPM_SPEC_POSTUNINSTALL\@ + +%pre +\@CPACK_RPM_SPEC_PREINSTALL\@ + +%preun +\@CPACK_RPM_SPEC_PREUNINSTALL\@ + +%files +%defattr(\@TMP_DEFAULT_FILE_PERMISSIONS\@,\@TMP_DEFAULT_USER\@,\@TMP_DEFAULT_GROUP\@,\@TMP_DEFAULT_DIR_PERMISSIONS\@) +\@CPACK_RPM_INSTALL_FILES\@ +\@CPACK_RPM_ABSOLUTE_INSTALL_FILES\@ +\@CPACK_RPM_USER_INSTALL_FILES\@ + +%changelog +\@CPACK_RPM_SPEC_CHANGELOG\@ + +\@TMP_OTHER_COMPONENTS\@ +" + ) + endif() + + # Stop here if we were asked to only generate a template USER spec file + # The generated file may then be used as a template by user who wants + # to customize their own spec file. + if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE) + message(FATAL_ERROR "CPackRPM: STOP here Generated USER binary spec file template is: ${CPACK_RPM_BINARY_SPECFILE}.in") + endif() + endif() + + # After that we may either use a user provided spec file + # or generate one using appropriate variables value. + if(CPACK_RPM_USER_BINARY_SPECFILE) + # User may have specified SPECFILE just use it + message("CPackRPM: Will use USER specified spec file: ${CPACK_RPM_USER_BINARY_SPECFILE}") + # The user provided file is processed for @var replacement + configure_file(${CPACK_RPM_USER_BINARY_SPECFILE} ${CPACK_RPM_BINARY_SPECFILE} @ONLY) + else() + # No User specified spec file, will use the generated spec file + message("CPackRPM: Will use GENERATED spec file: ${CPACK_RPM_BINARY_SPECFILE}") + # Note the just created file is processed for @var replacement + configure_file(${CPACK_RPM_BINARY_SPECFILE}.in ${CPACK_RPM_BINARY_SPECFILE} @ONLY) + endif() + + if(NOT GENERATE_SPEC_PARTS) # generate package + if(RPMBUILD_EXECUTABLE) + # Now call rpmbuild using the SPECFILE + execute_process( + COMMAND "${RPMBUILD_EXECUTABLE}" ${RPMBUILD_FLAGS} + --define "_topdir ${CPACK_RPM_DIRECTORY}" + --buildroot "%_topdir/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" + --target "${CPACK_RPM_PACKAGE_ARCHITECTURE}" + "${CPACK_RPM_BINARY_SPECFILE}" + WORKING_DIRECTORY "${CPACK_TOPLEVEL_DIRECTORY}/${CPACK_PACKAGE_FILE_NAME}${CPACK_RPM_PACKAGE_COMPONENT_PART_PATH}" + RESULT_VARIABLE CPACK_RPMBUILD_EXEC_RESULT + ERROR_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err" + OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out") + if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err RPMBUILDERR) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out RPMBUILDOUT) + message("CPackRPM:Debug: You may consult rpmbuild logs in: ") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.err") + message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_NAME}.out") + message("CPackRPM:Debug: *** ${RPMBUILDOUT} ***") + endif() + else() + if(ALIEN_EXECUTABLE) + message(FATAL_ERROR "RPM packaging through alien not done (yet)") + endif() + endif() + + # find generated rpm files and take their names + file(GLOB_RECURSE GENERATED_FILES "${CPACK_RPM_DIRECTORY}/RPMS/*.rpm" + "${CPACK_RPM_DIRECTORY}/SRPMS/*.rpm") + + if(NOT GENERATED_FILES) + message(FATAL_ERROR "RPM package was not generated! ${CPACK_RPM_DIRECTORY}") + endif() + + unset(expected_filenames_) + unset(filenames_) + if(CPACK_RPM_DEBUGINFO_PACKAGE AND NOT CPACK_RPM_FILE_NAME STREQUAL "RPM-DEFAULT") + list(APPEND expected_filenames_ + "${CPACK_RPM_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.*\\.rpm") + list(APPEND filenames_ "${CPACK_RPM_FILE_NAME}") + endif() + + if(CPACK_RPM_DEBUGINFO_PACKAGE) + cpack_rpm_variable_fallback("CPACK_RPM_DEBUGINFO_FILE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_DEBUGINFO_FILE_NAME" + "CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DEBUGINFO_FILE_NAME" + "CPACK_RPM_DEBUGINFO_FILE_NAME") + + if(CPACK_RPM_DEBUGINFO_FILE_NAME AND + NOT CPACK_RPM_DEBUGINFO_FILE_NAME STREQUAL "RPM-DEFAULT") + list(APPEND expected_filenames_ + "${CPACK_RPM_PACKAGE_NAME}-debuginfo-${CPACK_PACKAGE_VERSION}.*\\.rpm") + string(REPLACE "@cpack_component@" "${CPACK_RPM_PACKAGE_COMPONENT}" + CPACK_RPM_DEBUGINFO_FILE_NAME "${CPACK_RPM_DEBUGINFO_FILE_NAME}") + list(APPEND filenames_ "${CPACK_RPM_DEBUGINFO_FILE_NAME}") + endif() + endif() + + # check if other files have to be renamed + file(GLOB rename_files_ "${CPACK_RPM_DIRECTORY}/SPECS/*.rpm_name") + if(rename_files_) + foreach(f_ IN LISTS rename_files_) + file(READ "${f_}" tmp_) + list(GET tmp_ 0 efn_) + list(APPEND expected_filenames_ "${efn_}") + list(GET tmp_ 1 fn_) + list(APPEND filenames_ "${fn_}") + endforeach() + endif() + + if(expected_filenames_) + foreach(F IN LISTS GENERATED_FILES) + unset(matched_) + foreach(expected_ IN LISTS expected_filenames_) + if(F MATCHES ".*/${expected_}") + list(FIND expected_filenames_ "${expected_}" idx_) + list(GET filenames_ ${idx_} filename_) + get_filename_component(FILE_PATH "${F}" DIRECTORY) + file(RENAME "${F}" "${FILE_PATH}/${filename_}") + list(APPEND new_files_list_ "${FILE_PATH}/${filename_}") + set(matched_ "YES") + + break() + endif() + endforeach() + + if(NOT matched_) + list(APPEND new_files_list_ "${F}") + endif() + endforeach() + + set(GENERATED_FILES "${new_files_list_}") + endif() + endif() + + set(GEN_CPACK_OUTPUT_FILES "${GENERATED_FILES}" PARENT_SCOPE) + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: GEN_CPACK_OUTPUT_FILES = ${GENERATED_FILES}") + endif() +endfunction() + +cpack_rpm_generate_package() diff --git a/Modules/Internal/CPack/CPackWIX.cmake b/Modules/Internal/CPack/CPackWIX.cmake new file mode 100644 index 0000000..d1875f2 --- /dev/null +++ b/Modules/Internal/CPack/CPackWIX.cmake @@ -0,0 +1,20 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +if(NOT CPACK_WIX_ROOT) + string(REPLACE "\\" "/" CPACK_WIX_ROOT "$ENV{WIX}") +endif() + +find_program(CPACK_WIX_CANDLE_EXECUTABLE candle + PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin") + +if(NOT CPACK_WIX_CANDLE_EXECUTABLE) + message(FATAL_ERROR "Could not find the WiX candle executable.") +endif() + +find_program(CPACK_WIX_LIGHT_EXECUTABLE light + PATHS "${CPACK_WIX_ROOT}" PATH_SUFFIXES "bin") + +if(NOT CPACK_WIX_LIGHT_EXECUTABLE) + message(FATAL_ERROR "Could not find the WiX light executable.") +endif() diff --git a/Modules/Internal/CPack/CPackZIP.cmake b/Modules/Internal/CPack/CPackZIP.cmake new file mode 100644 index 0000000..f619de4 --- /dev/null +++ b/Modules/Internal/CPack/CPackZIP.cmake @@ -0,0 +1,30 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + + +if(CMAKE_BINARY_DIR) + message(FATAL_ERROR "CPackZIP.cmake may only be used by CPack internally.") +endif() + +find_program(ZIP_EXECUTABLE wzzip PATHS "$ENV{ProgramFiles}/WinZip") +if(ZIP_EXECUTABLE) + set(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" -P \"<ARCHIVE>\" @<FILELIST>") + set(CPACK_ZIP_NEED_QUOTES TRUE) +endif() + +if(NOT ZIP_EXECUTABLE) + find_program(ZIP_EXECUTABLE 7z PATHS "$ENV{ProgramFiles}/7-Zip") + if(ZIP_EXECUTABLE) + set(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" a -tzip \"<ARCHIVE>\" @<FILELIST>") + set(CPACK_ZIP_NEED_QUOTES TRUE) + endif() +endif() + +if(NOT ZIP_EXECUTABLE) + find_package(Cygwin) + find_program(ZIP_EXECUTABLE zip PATHS "${CYGWIN_INSTALL_PATH}/bin") + if(ZIP_EXECUTABLE) + set(CPACK_ZIP_COMMAND "\"${ZIP_EXECUTABLE}\" -r \"<ARCHIVE>\" . -i@<FILELIST>") + set(CPACK_ZIP_NEED_QUOTES FALSE) + endif() +endif() |