diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/CPackRPM.cmake | 1273 | ||||
-rw-r--r-- | Modules/Compiler/GNU-CXX.cmake | 4 | ||||
-rw-r--r-- | Modules/FindMatlab.cmake | 1508 | ||||
-rw-r--r-- | Modules/MatlabTestsRedirect.cmake | 92 | ||||
-rw-r--r-- | Modules/WriteCompilerDetectionHeader.cmake | 2 |
5 files changed, 2137 insertions, 742 deletions
diff --git a/Modules/CPackRPM.cmake b/Modules/CPackRPM.cmake index fce8236..539a0aa 100644 --- a/Modules/CPackRPM.cmake +++ b/Modules/CPackRPM.cmake @@ -494,709 +494,687 @@ if(NOT UNIX) message(FATAL_ERROR "CPackRPM.cmake may only be used under UNIX.") endif() -# 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 +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 "\n" ", " - LSB_RELEASE_OUTPUT - ${_TMP_LSB_RELEASE_OUTPUT}) - else () - set(LSB_RELEASE_OUTPUT "lsb_release not installed/found!") + string(REGEX REPLACE "^.* " "" + RPMBUILD_EXECUTABLE_VERSION + ${_TMP_VERSION}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: rpmbuild version is <${RPMBUILD_EXECUTABLE_VERSION}>") + endif() 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) - set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") - string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) -else() - set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "") -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: -# + if(NOT RPMBUILD_EXECUTABLE) + message(FATAL_ERROR "RPM package requires rpmbuild executable") + endif() -# CPACK_RPM_PACKAGE_SUMMARY (mandatory) + # 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() -# CPACK_RPM_PACKAGE_SUMMARY_ is used only locally so that it can be unset each time before use otherwise -# component packaging could leak variable content between components -unset(CPACK_RPM_PACKAGE_SUMMARY_) -if(CPACK_RPM_PACKAGE_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY_ ${CPACK_RPM_PACKAGE_SUMMARY}) - unset(CPACK_RPM_PACKAGE_SUMMARY) -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() -#Check for component summary first. -#If not set, it will use regular package summary logic. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY}) + # 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() -endif() -if(NOT CPACK_RPM_PACKAGE_SUMMARY) - if(CPACK_RPM_PACKAGE_SUMMARY_) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) - elseif(CPACK_PACKAGE_DESCRIPTION_SUMMARY) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_PACKAGE_DESCRIPTION_SUMMARY}) + # Are we packaging components ? + if(CPACK_RPM_PACKAGE_COMPONENT) + set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "-${CPACK_RPM_PACKAGE_COMPONENT}") + string(TOUPPER ${CPACK_RPM_PACKAGE_COMPONENT} CPACK_RPM_PACKAGE_COMPONENT_UPPER) else() - # if neither var is defined lets use the name as summary - string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_SUMMARY) + set(CPACK_RPM_PACKAGE_COMPONENT_PART_NAME "") endif() -endif() -# CPACK_RPM_PACKAGE_NAME (mandatory) -if(NOT CPACK_RPM_PACKAGE_NAME) - string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) -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_VERSION (mandatory) -if(NOT CPACK_RPM_PACKAGE_VERSION) - if(NOT CPACK_PACKAGE_VERSION) - message(FATAL_ERROR "RPM package requires a package version") + # CPACK_RPM_PACKAGE_SUMMARY (mandatory) + + #Check for component summary first. + #If not set, it will use regular package summary logic. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY) + set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_SUMMARY}) + endif() 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}") + + 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() -endif() -set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE}) + # CPACK_RPM_PACKAGE_NAME (mandatory) + if(NOT CPACK_RPM_PACKAGE_NAME) + string(TOLOWER "${CPACK_PACKAGE_NAME}" CPACK_RPM_PACKAGE_NAME) + endif() -#prefer component architecture -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE) - set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE}) + # 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 component build arch = ${_CPACK_RPM_PACKAGE_ARCHITECTURE}") + message("CPackRPM:Debug: using user-specified build arch = ${CPACK_RPM_PACKAGE_ARCHITECTURE}") endif() 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() -# CPACK_RPM_PACKAGE_LICENSE -if(NOT CPACK_RPM_PACKAGE_LICENSE) - set(CPACK_RPM_PACKAGE_LICENSE "unknown") -endif() + set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_PACKAGE_ARCHITECTURE}) -# CPACK_RPM_PACKAGE_GROUP -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}") + #prefer component architecture + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE) + set(_CPACK_RPM_PACKAGE_ARCHITECTURE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_ARCHITECTURE}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using component build arch = ${_CPACK_RPM_PACKAGE_ARCHITECTURE}") + endif() + endif() + endif() + if(${_CPACK_RPM_PACKAGE_ARCHITECTURE} STREQUAL "noarch") + set(TMP_RPM_BUILDARCH "Buildarch: ${_CPACK_RPM_PACKAGE_ARCHITECTURE}") else() - set(CPACK_RPM_PACKAGE_VENDOR "unknown") + set(TMP_RPM_BUILDARCH "") 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 -# + # 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() -# CPACK_RPM_PACKAGE_DESCRIPTION_ is used only locally so that it can be unset each time before use otherwise -# component packaging could leak variable content between components -unset(CPACK_RPM_PACKAGE_DESCRIPTION_) -if(CPACK_RPM_PACKAGE_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION_ ${CPACK_RPM_PACKAGE_DESCRIPTION}) - unset(CPACK_RPM_PACKAGE_DESCRIPTION) -endif() + # CPACK_RPM_PACKAGE_LICENSE + if(NOT CPACK_RPM_PACKAGE_LICENSE) + set(CPACK_RPM_PACKAGE_LICENSE "unknown") + endif() -#Check for a component description first. -#If not set, it will use regular package description logic. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION}) - elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION}) + # CPACK_RPM_PACKAGE_GROUP + if(NOT CPACK_RPM_PACKAGE_GROUP) + set(CPACK_RPM_PACKAGE_GROUP "unknown") endif() -endif() -if(NOT CPACK_RPM_PACKAGE_DESCRIPTION) - if(CPACK_RPM_PACKAGE_DESCRIPTION_) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) - elseif(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_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_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() + # 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 + # + + #Check for a component description first. + #If not set, it will use regular package description logic. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_DESCRIPTION}) + elseif(CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION) + set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_COMPONENT_${CPACK_RPM_PACKAGE_COMPONENT_UPPER}_DESCRIPTION}) + endif() + endif() -if(CPACK_PACKAGE_RELOCATABLE) - set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) -endif() -if(CPACK_RPM_PACKAGE_RELOCATABLE) - unset(TMP_RPM_PREFIXES) + 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 () - 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.") + # 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_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files) - cpack_rpm_prepare_relocation_paths() + set(CPACK_RPM_COMPRESSION_TYPE_TMP "") endif() -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_PACKAGE_RELOCATABLE) + set(CPACK_RPM_PACKAGE_RELOCATABLE TRUE) + endif() + if(CPACK_RPM_PACKAGE_RELOCATABLE) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: processing ${_RPM_SPEC_HEADER}") + message("CPackRPM:Debug: Trying to build a relocatable package") endif() - if(CPACK_RPM_PACKAGE_COMPONENT) - if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}") - endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}}) - else() - if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_SET_DESTDIR AND (NOT CPACK_SET_DESTDIR STREQUAL "I_ON")) + message("CPackRPM:Warning: CPACK_SET_DESTDIR is set (=${CPACK_SET_DESTDIR}) while requesting a relocatable package (CPACK_RPM_PACKAGE_RELOCATABLE is set): this is not supported, the package won't be relocatable.") + else() + set(CPACK_RPM_PACKAGE_PREFIX ${CPACK_PACKAGING_INSTALL_PREFIX}) # kept for back compatibility (provided external RPM spec files) + cpack_rpm_prepare_relocation_paths() + endif() + 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) + if(DEFINED CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}) if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined") - message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + message("CPackRPM:Debug: using CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}") endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER}}) + else() + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PACKAGE_${_RPM_SPEC_HEADER} not defined") + 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() + endif() + else() + if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") endif() - endif() - else() - if(DEFINED CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}) - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: using CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}") + set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) endif() - set(CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}}) - endif() - endif() + endif() - # Do not forget to unset previously set header (from previous component) - unset(TMP_RPM_${_RPM_SPEC_HEADER}) - # 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) - set(_PACKAGE_HEADER_NAME "${_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}") - set(_PACKAGE_HEADER_NAME "${_PACKAGE_HEADER_NAME})") + # 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) + set(_PACKAGE_HEADER_NAME "${_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}") + set(_PACKAGE_HEADER_NAME "${_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 ${_PACKAGE_HEADER_NAME}:\n ${CPACK_RPM_PACKAGE_${_RPM_SPEC_HEADER}_TMP}") + message("CPackRPM:Debug: User defined CPACK_RPM_SPEC_INSTALL_POST = ${CPACK_RPM_SPEC_INSTALL_POST}") 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) + set(TMP_RPM_SPEC_INSTALL_POST "%define __spec_install_post ${CPACK_RPM_SPEC_INSTALL_POST}") 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 refered script file(s) will be read and directly -# put after the %post or %postun section -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE) - set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE}) + # 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 refered script file(s) will be read and directly + # put after the %post or %postun section + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE) + set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_INSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) + endif() + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE) + set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) + endif() else() set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) - endif() - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE) - set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_POST_UNINSTALL_SCRIPT_FILE}) - else() set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) endif() -else() - set(CPACK_RPM_POST_INSTALL_READ_FILE ${CPACK_RPM_POST_INSTALL_SCRIPT_FILE}) - set(CPACK_RPM_POST_UNINSTALL_READ_FILE ${CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE}) -endif() -# Handle post-install file if it has been specified -if(CPACK_RPM_POST_INSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE}) - file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL) + # Handle post-install file if it has been specified + if(CPACK_RPM_POST_INSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_POST_INSTALL_READ_FILE}) + file(READ ${CPACK_RPM_POST_INSTALL_READ_FILE} CPACK_RPM_SPEC_POSTINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_POST_INSTALL_SCRIPT_FILE <${CPACK_RPM_POST_INSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no post install file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_POSTINSTALL "") endif() -else() - # reset SPEC var value if no post install file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_POSTINSTALL "") -endif() -# Handle post-uninstall file if it has been specified -if(CPACK_RPM_POST_UNINSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE}) - file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL) + # Handle post-uninstall file if it has been specified + if(CPACK_RPM_POST_UNINSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_POST_UNINSTALL_READ_FILE}) + file(READ ${CPACK_RPM_POST_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_POSTUNINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_POST_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_POST_UNINSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no post uninstall file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_POSTUNINSTALL "") endif() -else() - # reset SPEC var value if no post uninstall file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_POSTUNINSTALL "") -endif() -# 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 refered script file(s) will be read and directly -# put after the %pre or %preun section -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE) - set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE}) + # 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 refered script file(s) will be read and directly + # put after the %pre or %preun section + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE) + set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_INSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) + endif() + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE) + set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE}) + else() + set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) + endif() else() set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) - endif() - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE) - set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_PRE_UNINSTALL_SCRIPT_FILE}) - else() set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) endif() -else() - set(CPACK_RPM_PRE_INSTALL_READ_FILE ${CPACK_RPM_PRE_INSTALL_SCRIPT_FILE}) - set(CPACK_RPM_PRE_UNINSTALL_READ_FILE ${CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE}) -endif() -# Handle pre-install file if it has been specified -if(CPACK_RPM_PRE_INSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE}) - file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL) + # Handle pre-install file if it has been specified + if(CPACK_RPM_PRE_INSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_PRE_INSTALL_READ_FILE}) + file(READ ${CPACK_RPM_PRE_INSTALL_READ_FILE} CPACK_RPM_SPEC_PREINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_PRE_INSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_INSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no pre-install file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_PREINSTALL "") endif() -else() - # reset SPEC var value if no pre-install file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_PREINSTALL "") -endif() -# Handle pre-uninstall file if it has been specified -if(CPACK_RPM_PRE_UNINSTALL_READ_FILE) - if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE}) - file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL) + # Handle pre-uninstall file if it has been specified + if(CPACK_RPM_PRE_UNINSTALL_READ_FILE) + if(EXISTS ${CPACK_RPM_PRE_UNINSTALL_READ_FILE}) + file(READ ${CPACK_RPM_PRE_UNINSTALL_READ_FILE} CPACK_RPM_SPEC_PREUNINSTALL) + else() + message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring") + endif() else() - message("CPackRPM:Warning: CPACK_RPM_PRE_UNINSTALL_SCRIPT_FILE <${CPACK_RPM_PRE_UNINSTALL_READ_FILE}> does not exists - ignoring") + # reset SPEC var value if no pre-uninstall file has been specified + # (either globally or component-wise) + set(CPACK_RPM_SPEC_PREUNINSTALL "") endif() -else() - # reset SPEC var value if no pre-uninstall file has been specified - # (either globally or component-wise) - set(CPACK_RPM_SPEC_PREUNINSTALL "") -endif() -# CPACK_RPM_CHANGELOG_FILE -# May be used to embed a changelog in the spec file. -# The refered 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) + # CPACK_RPM_CHANGELOG_FILE + # May be used to embed a changelog in the spec file. + # The refered 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() - message(SEND_ERROR "CPackRPM:Warning: CPACK_RPM_CHANGELOG_FILE <${CPACK_RPM_CHANGELOG_FILE}> does not exists - ignoring") + 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() -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}") + # 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() -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) - -#set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${_CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm") -set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}") -# 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}") - -# 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}") - list(FIND _RPM_DIRS_TO_OMIT "${_OMIT_DIR}" _DUPLICATE_FOUND) - if(_DUPLICATE_FOUND EQUAL -1) - set(_OMIT_DIR "-o -path ${_OMIT_DIR}") - separate_arguments(_OMIT_DIR) - list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR}) - endif() - endforeach() - endif() - endforeach() -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) + + #set(CPACK_RPM_FILE_NAME "${CPACK_RPM_PACKAGE_NAME}-${CPACK_RPM_PACKAGE_VERSION}-${CPACK_RPM_PACKAGE_RELEASE}-${_CPACK_RPM_PACKAGE_ARCHITECTURE}.rpm") + set(CPACK_RPM_FILE_NAME "${CPACK_OUTPUT_FILE_NAME}") + # 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}") + + # 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}") + list(FIND _RPM_DIRS_TO_OMIT "${_OMIT_DIR}" _DUPLICATE_FOUND) + if(_DUPLICATE_FOUND EQUAL -1) + set(_OMIT_DIR "-o -path ${_OMIT_DIR}") + separate_arguments(_OMIT_DIR) + list(APPEND _RPM_DIRS_TO_OMIT ${_OMIT_DIR}) + endif() + 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 (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/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include) - if (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION) - message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.") - list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}") + if (NOT DEFINED CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST /etc /etc/init.d /usr /usr/share /usr/share/doc /usr/bin /usr/lib /usr/lib64 /usr/include) + if (CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION) + message("CPackRPM:Debug: Adding ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION} to builtin omit list.") + list(APPEND CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST "${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION}") + endif() endif() -endif() -if(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST) + 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() + foreach(_DIR ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}) + list(APPEND _RPM_DIRS_TO_OMIT "-o;-path;.${_DIR}") + endforeach() + endif() if (CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST= ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}") - endif() - foreach(_DIR ${CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST}) - list(APPEND _RPM_DIRS_TO_OMIT "-o;-path;.${_DIR}") - endforeach() -endif() -if (CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") -endif() + message("CPackRPM:Debug: Final list of path to OMIT in RPM: ${_RPM_DIRS_TO_OMIT}") + endif() -# Use files tree to construct files command (spec file) -# We should not forget to include symlinks (thus -o -type l) -# We should include directory as well (thus -type d) -# but not the main local dir "." (thus -a -not -name ".") -# We must remove the './' due to the local search and escape the -# file name by enclosing it between double quotes (thus the sed) -# Then we must authorize any man pages extension (adding * at the end) -# because rpmbuild may automatically compress those files -execute_process(COMMAND find . -type f -o -type l -o (-type d -a -not ( -name "." ${_RPM_DIRS_TO_OMIT} ) ) - COMMAND sed s:.*/man.*/.*:&*: - COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/ - WORKING_DIRECTORY "${WDIR}" - OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES) - -# 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) - set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}") - 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() + # Use files tree to construct files command (spec file) + # We should not forget to include symlinks (thus -o -type l) + # We should include directory as well (thus -type d) + # but not the main local dir "." (thus -a -not -name ".") + # We must remove the './' due to the local search and escape the + # file name by enclosing it between double quotes (thus the sed) + # Then we must authorize any man pages extension (adding * at the end) + # because rpmbuild may automatically compress those files + execute_process(COMMAND find . -type f -o -type l -o (-type d -a -not ( -name "." ${_RPM_DIRS_TO_OMIT} ) ) + COMMAND sed s:.*/man.*/.*:&*: + COMMAND sed s/\\.\\\(.*\\\)/\"\\1\"/ + WORKING_DIRECTORY "${WDIR}" + OUTPUT_VARIABLE CPACK_RPM_INSTALL_FILES) + + # 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) + set(COMPONENT_FILES_TAG "CPACK_ABSOLUTE_DESTINATION_FILES_${CPACK_RPM_PACKAGE_COMPONENT}") + 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() -else() - if(CPACK_ABSOLUTE_DESTINATION_FILES) - set(CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL "${CPACK_ABSOLUTE_DESTINATION_FILES}") + + # In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST. + if(CPACK_RPM_PACKAGE_COMPONENT) + if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST) + set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST}) + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: Handling User Filelist: <${CPACK_RPM_USER_FILELIST_INTERNAL}>") + message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") + endif() + else() + set(CPACK_RPM_USER_FILELIST_INTERNAL "") + endif() + else() + if(CPACK_RPM_USER_FILELIST) + set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}") + else() + set(CPACK_RPM_USER_FILELIST_INTERNAL "") + endif() endif() -endif() -# In component case, set CPACK_RPM_USER_FILELIST_INTERNAL with CPACK_RPM_<COMPONENT>_USER_FILELIST. -if(CPACK_RPM_PACKAGE_COMPONENT) - if(CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST) - set(CPACK_RPM_USER_FILELIST_INTERNAL ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_FILELIST}) + # 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}>") - message("CPackRPM:Debug: in component = ${CPACK_RPM_PACKAGE_COMPONENT}") 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-z0-9\(\),-]* " "" F_PATH ${F}) + string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F}) + + if(CPACK_RPM_PACKAGE_DEBUG) + message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>") + endif() + if(F_PREFIX) + set(F_PREFIX "${F_PREFIX} ") + endif() + # Rebuild the user list file + set(CPACK_RPM_USER_INSTALL_FILES "${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) + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endforeach() else() - set(CPACK_RPM_USER_FILELIST_INTERNAL "") + set(CPACK_RPM_USER_INSTALL_FILES "") endif() -else() - if(CPACK_RPM_USER_FILELIST) - set(CPACK_RPM_USER_FILELIST_INTERNAL "${CPACK_RPM_USER_FILELIST}") + + 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 unecessary quotes + string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") + # Remove ABSOLUTE install file from INSTALL FILE LIST + list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}) + # Rebuild INSTALL_FILES + set(CPACK_RPM_INSTALL_FILES "") + foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endforeach() + # Build ABSOLUTE_INSTALL_FILES + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") + foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${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() - set(CPACK_RPM_USER_FILELIST_INTERNAL "") + # reset vars in order to avoid leakage of value(s) from one component to another + set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") endif() -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 + # Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir + # This is necessary to avoid duplicate files since rpmbuild do + # recursion on its own when encountering a pathname which is a directory + # which is not flagged as %dir 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-z0-9\(\),-]* " "" F_PATH ${F}) - string(REGEX MATCH "%[A-Za-z0-9\(\),-]*" F_PREFIX ${F}) - - if(CPACK_RPM_PACKAGE_DEBUG) - message("CPackRPM:Debug: F_PREFIX=<${F_PREFIX}>, F_PATH=<${F_PATH}>") - endif() - if(F_PREFIX) - set(F_PREFIX "${F_PREFIX} ") - endif() - # Rebuild the user list file - set(CPACK_RPM_USER_INSTALL_FILES "${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) - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + if(IS_DIRECTORY "${WDIR}/${F}") + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}%dir \"${F}\"\n") + else() + set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + endif() endforeach() -else() - set(CPACK_RPM_USER_INSTALL_FILES "") -endif() + set(CPACK_RPM_INSTALL_FILES_LIST "") -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 unecessary quotes - string(REPLACE "\"" "" CPACK_RPM_INSTALL_FILES_LIST "${CPACK_RPM_INSTALL_FILES_LIST}") - # Remove ABSOLUTE install file from INSTALL FILE LIST - list(REMOVE_ITEM CPACK_RPM_INSTALL_FILES_LIST ${CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL}) - # Rebuild INSTALL_FILES - set(CPACK_RPM_INSTALL_FILES "") - foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") - endforeach() - # Build ABSOLUTE_INSTALL_FILES - set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "") - foreach(F IN LISTS CPACK_ABSOLUTE_DESTINATION_FILES_INTERNAL) - set(CPACK_RPM_ABSOLUTE_INSTALL_FILES "${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() + # 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}${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.spec") -# Prepend directories in ${CPACK_RPM_INSTALL_FILES} with %dir -# This is necessary to avoid duplicate files since rpmbuild do -# recursion on its own when encountering a pathname which is a directory -# which is not flagged as %dir -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_INSTALL_FILES "") -foreach(F IN LISTS CPACK_RPM_INSTALL_FILES_LIST) - if(IS_DIRECTORY "${WDIR}/${F}") - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}%dir \"${F}\"\n") - else() - set(CPACK_RPM_INSTALL_FILES "${CPACK_RPM_INSTALL_FILES}\"${F}\"\n") + # 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() -endforeach() -set(CPACK_RPM_INSTALL_FILES_LIST "") - -# 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}${CPACK_RPM_PACKAGE_COMPONENT_PART_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. -# + # + # USER generated/provided spec file handling. + # -# We can have a component specific spec file. -if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE) - set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE}) -endif() + # We can have a component specific spec file. + if(CPACK_RPM_PACKAGE_COMPONENT AND CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE) + set(CPACK_RPM_USER_BINARY_SPECFILE ${CPACK_RPM_${CPACK_RPM_PACKAGE_COMPONENT}_USER_BINARY_SPECFILE}) + 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 -if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) - file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in + # 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 + if(CPACK_RPM_GENERATE_USER_BINARY_SPECFILE_TEMPLATE OR NOT CPACK_RPM_USER_BINARY_SPECFILE) + file(WRITE ${CPACK_RPM_BINARY_SPECFILE}.in "# -*- rpm-spec -*- BuildRoot: \@CPACK_RPM_DIRECTORY\@/\@CPACK_PACKAGE_FILE_NAME\@\@CPACK_RPM_PACKAGE_COMPONENT_PART_PATH\@ Summary: \@CPACK_RPM_PACKAGE_SUMMARY\@ @@ -1271,63 +1249,54 @@ mv \"\@CPACK_TOPLEVEL_DIRECTORY\@/tmpBBroot\" $RPM_BUILD_ROOT %changelog \@CPACK_RPM_SPEC_CHANGELOG\@ ") - # 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 templare is: ${CPACK_RPM_BINARY_SPECFILE}.in") + # 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 templare is: ${CPACK_RPM_BINARY_SPECFILE}.in") + endif() 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(RPMBUILD_EXECUTABLE) - # Now call rpmbuild using the SPECFILE - execute_process( - COMMAND "${RPMBUILD_EXECUTABLE}" -bb - --define "_topdir ${CPACK_RPM_DIRECTORY}" - --buildroot "${CPACK_RPM_DIRECTORY}/${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_COMPONENT_PART_NAME}.err" - OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") - if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT) - file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err RPMBUILDERR) - file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out RPMBUILDOUT) - message("CPackRPM:Debug: You may consult rpmbuild logs in: ") - message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err") - message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") - message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") - message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + # 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() -else() - if(ALIEN_EXECUTABLE) - message(FATAL_ERROR "RPM packaging through alien not done (yet)") + + if(RPMBUILD_EXECUTABLE) + # Now call rpmbuild using the SPECFILE + execute_process( + COMMAND "${RPMBUILD_EXECUTABLE}" -bb + --define "_topdir ${CPACK_RPM_DIRECTORY}" + --buildroot "${CPACK_RPM_DIRECTORY}/${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_COMPONENT_PART_NAME}.err" + OUTPUT_FILE "${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") + if(CPACK_RPM_PACKAGE_DEBUG OR CPACK_RPMBUILD_EXEC_RESULT) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err RPMBUILDERR) + file(READ ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out RPMBUILDOUT) + message("CPackRPM:Debug: You may consult rpmbuild logs in: ") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.err") + message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + message("CPackRPM:Debug: - ${CPACK_TOPLEVEL_DIRECTORY}/rpmbuild${CPACK_RPM_PACKAGE_COMPONENT_PART_NAME}.out") + message("CPackRPM:Debug: *** ${RPMBUILDERR} ***") + endif() + else() + if(ALIEN_EXECUTABLE) + message(FATAL_ERROR "RPM packaging through alien not done (yet)") + endif() endif() -endif() +endfunction() -# reset variables from temporary variables -if(CPACK_RPM_PACKAGE_SUMMARY_) - set(CPACK_RPM_PACKAGE_SUMMARY ${CPACK_RPM_PACKAGE_SUMMARY_}) -else() - unset(CPACK_RPM_PACKAGE_SUMMARY) -endif() -if(CPACK_RPM_PACKAGE_DESCRIPTION_) - set(CPACK_RPM_PACKAGE_DESCRIPTION ${CPACK_RPM_PACKAGE_DESCRIPTION_}) -else() - unset(CPACK_RPM_PACKAGE_DESCRIPTION) -endif() +cpack_rpm_generate_package() diff --git a/Modules/Compiler/GNU-CXX.cmake b/Modules/Compiler/GNU-CXX.cmake index 86a31e4..2dc02f0 100644 --- a/Modules/Compiler/GNU-CXX.cmake +++ b/Modules/Compiler/GNU-CXX.cmake @@ -44,10 +44,10 @@ macro(cmake_record_cxx_compile_features) endmacro() set(_result 0) - if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) _get_gcc_features(${CMAKE_CXX14_STANDARD_COMPILE_OPTION} CMAKE_CXX14_COMPILE_FEATURES) endif() - if (UNIX AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) + if (NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.4) if (_result EQUAL 0) _get_gcc_features(${CMAKE_CXX11_STANDARD_COMPILE_OPTION} CMAKE_CXX11_COMPILE_FEATURES) endif() diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 73b3a5b..d08423b 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -2,20 +2,208 @@ # FindMatlab # ---------- # -# this module looks for Matlab +# Finds Matlab installations and provides Matlab tools and libraries to cmake. # -# Defines: +# This package first intention is to find the libraries associated with Matlab +# in order to be able to build Matlab extensions (mex files). It can also be +# used: # -# :: +# * run specific commands in Matlab +# * declare Matlab unit test +# * retrieve various information from Matlab (mex extensions, versions and +# release queries, ...) # -# MATLAB_INCLUDE_DIR: include path for mex.h, engine.h -# MATLAB_LIBRARIES: required libraries: libmex, etc -# MATLAB_MEX_LIBRARY: path to libmex.lib -# MATLAB_MX_LIBRARY: path to libmx.lib -# MATLAB_ENG_LIBRARY: path to libeng.lib +# The module supports the following components: +# +# * ``MX_LIBRARY`` and ``ENG_LIBRARY`` respectively the MX and ENG libraries of +# Matlab +# * ``MAIN_PROGRAM`` the Matlab binary program. +# +# .. note:: +# +# The version given to the :command:`find_package` directive is the Matlab +# **version**, which should not be confused with the Matlab *release* name +# (eg. `R2014`). +# The :command:`matlab_get_version_from_release_name` and +# :command:`matlab_get_release_name_from_version` allow a mapping +# from the release name to the version. +# +# The variable :variable:`Matlab_ROOT_DIR` may be specified in order to give +# the path of the desired Matlab version. Otherwise, the behaviour is platform +# specific: +# +# * Windows: The installed versions of Matlab are retrieved from the +# Windows registry +# * OS X: The installed versions of Matlab are given by the MATLAB +# paths in ``/Application``. If no such application is found, it falls back +# to the one that might be accessible from the PATH. +# * Unix: The desired Matlab should be accessible from the PATH. +# +# Additional information is provided when :variable:`MATLAB_FIND_DEBUG` is set. +# When a Matlab binary is found automatically and the ``MATLAB_VERSION`` +# is not given, the version is queried from Matlab directly. +# On Windows, it can make a window running Matlab appear. +# +# The mapping of the release names and the version of Matlab is performed by +# defining pairs (name, version). The variable +# :variable:`MATLAB_ADDITIONAL_VERSIONS` may be provided before the call to +# the :command:`find_package` in order to handle additional versions. +# +# A Matlab scripts can be added to the set of tests using the +# :command:`matlab_add_unit_test`. By default, the Matlab unit test framework +# will be used (>= 2013a) to run this script, but regular ``.m`` files +# returning an exit code can be used as well (0 indicating a success). +# +# Module Input Variables +# ---------------------- +# +# Users or projects may set the following variables to configure the module +# behaviour: +# +# :variable:`Matlab_ROOT_DIR` +# the root of the Matlab installation. +# :variable:`MATLAB_FIND_DEBUG` +# outputs debug information +# :variable:`MATLAB_ADDITIONAL_VERSIONS` +# additional versions of Matlab for the automatic retrieval of the installed +# versions. +# +# Variables defined by the module +# ------------------------------- +# +# Result variables +# ^^^^^^^^^^^^^^^^ +# +# ``Matlab_FOUND`` +# ``TRUE`` if the Matlab installation is found, ``FALSE`` +# otherwise. All variable below are defined if Matlab is found. +# ``Matlab_ROOT_DIR`` +# the final root of the Matlab installation determined by the FindMatlab +# module. +# ``Matlab_MAIN_PROGRAM`` +# the Matlab binary program. Available only if the component ``MAIN_PROGRAM`` +# is given in the :command:`find_package` directive. +# ``Matlab_INCLUDE_DIRS`` +# the path of the Matlab libraries headers +# ``Matlab_MEX_LIBRARY`` +# library for mex, always available. +# ``Matlab_MX_LIBRARY`` +# mx library of Matlab (arrays). Available only if the component +# ``MX_LIBRARY`` has been requested. +# ``Matlab_ENG_LIBRARY`` +# Matlab engine library. Available only if the component ``ENG_LIBRARY`` +# is requested. +# ``Matlab_LIBRARIES`` +# the whole set of libraries of Matlab +# ``Matlab_MEX_COMPILER`` +# the mex compiler of Matlab. Currently not used. +# Available only if the component ``MEX_COMPILER`` is asked +# +# Cached variables +# ^^^^^^^^^^^^^^^^ +# +# ``Matlab_MEX_EXTENSION`` +# the extension of the mex files for the current platform (given by Matlab). +# ``Matlab_ROOT_DIR`` +# the location of the root of the Matlab installation found. If this value +# is changed by the user, the result variables are recomputed. +# +# Provided macros +# --------------- +# +# :command:`matlab_get_version_from_release_name` +# returns the version from the release name +# :command:`matlab_get_release_name_from_version` +# returns the release name from the Matlab version +# +# Provided functions +# ------------------ +# +# :command:`matlab_add_mex` +# adds a target compiling a MEX file. +# :command:`matlab_add_unit_test` +# adds a Matlab unit test file as a test to the project. +# :command:`matlab_extract_all_installed_versions_from_registry` +# parses the registry for all Matlab versions. Available on Windows only. +# The part of the registry parsed is dependent on the host processor +# :command:`matlab_get_all_valid_matlab_roots_from_registry` +# returns all the possible Matlab paths, according to a previously +# given list. Only the existing/accessible paths are kept. This is mainly +# useful for the searching all possible Matlab installation. +# :command:`matlab_get_mex_suffix` +# returns the suffix to be used for the mex files +# (platform/architecture dependant) +# :command:`matlab_get_version_from_matlab_run` +# returns the version of Matlab, given the full directory of the Matlab program. +# +# +# Known issues +# ------------ +# +# **Symbol clash in a MEX target** +# By default, every symbols inside a MEX +# file defined with the command :command:`matlab_add_mex` have hidden +# visibility, except for the entry point. This is the default behaviour of +# the MEX compiler, which lowers the risk of symbol collision between the +# libraries shipped with Matlab, and the libraries to which the MEX file is +# linking to. This is also the default on Windows platforms. +# +# However, this is not sufficient in certain case, where for instance your +# MEX file is linking against libraries that are already loaded by Matlab, +# even if those libraries have different SONAMES. +# A possible solution is to hide the symbols of the libraries to which the +# MEX target is linking to. This can be achieved in GNU GCC compilers with +# the linker option ``-Wl,--exclude-libs,ALL``. +# +# **Tests using GPU resources** +# in case your MEX file is using the GPU and +# in order to be able to run unit tests on this MEX file, the GPU resources +# should be properly released by Matlab. A possible solution is to make +# Matlab aware of the use of the GPU resources in the session, which can be +# performed by a command such as ``D = gpuDevice()`` at the beginning of +# the test script (or via a fixture). +# +# +# Reference +# -------------- +# +# .. variable:: Matlab_ROOT_DIR +# +# The root folder of the Matlab installation. If set before the call to +# :command:`find_package`, the module will look for the components in that +# path. If not set, then an automatic search of Matlab +# will be performed. If set, it should point to a valid version of Matlab. +# +# .. variable:: MATLAB_FIND_DEBUG +# +# If set, the lookup of Matlab and the intermediate configuration steps are +# outputted to the console. +# +# .. variable:: MATLAB_ADDITIONAL_VERSIONS +# +# If set, specifies additional versions of Matlab that may be looked for. +# The variable should be a list of strings, organised by pairs of release +# name and versions, such as follows:: +# +# set(MATLAB_ADDITIONAL_VERSIONS +# "release_name1=corresponding_version1" +# "release_name2=corresponding_version2" +# ... +# ) +# +# Example:: +# +# set(MATLAB_ADDITIONAL_VERSIONS +# "R2013b=8.2" +# "R2013a=8.1" +# "R2012b=8.0") +# +# The order of entries in this list matters when several versions of +# Matlab are installed. The priority is set according to the ordering in +# this list. #============================================================================= -# Copyright 2005-2009 Kitware, Inc. +# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. @@ -27,101 +215,1247 @@ # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) -set(MATLAB_FOUND 0) -if(WIN32) - if(${CMAKE_GENERATOR} MATCHES "Visual Studio 6") - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc60") +set(_FindMatlab_SELF_DIR "${CMAKE_CURRENT_LIST_DIR}") + +include(FindPackageHandleStandardArgs) +include(CheckCXXCompilerFlag) + + +# The currently supported versions. Other version can be added by the user by +# providing MATLAB_ADDITIONAL_VERSIONS +if(NOT MATLAB_ADDITIONAL_VERSIONS) + set(MATLAB_ADDITIONAL_VERSIONS) +endif() + +set(MATLAB_VERSIONS_MAPPING + "R2014a=8.3" + "R2013b=8.2" + "R2013a=8.1" + "R2012b=8.0" + "R2012a=7.14" + + "R2011b=7.13" + "R2011a=7.12" + "R2010b=7.11" + + ${MATLAB_ADDITIONAL_VERSIONS} + ) + + +# temporary folder for all Matlab runs +set(_matlab_temporary_folder ${CMAKE_BINARY_DIR}/Matlab) + +if(NOT EXISTS "${_matlab_temporary_folder}") + file(MAKE_DIRECTORY "${_matlab_temporary_folder}") +endif() + +#.rst: +# .. command:: matlab_get_version_from_release_name +# +# Returns the version of Matlab (17.58) from a release name (R2017k) +macro (matlab_get_version_from_release_name release_name version_name) + + string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) + + set(${version_name} "") + if(NOT _matched STREQUAL "") + set(${version_name} ${CMAKE_MATCH_1}) else() - if(${CMAKE_GENERATOR} MATCHES "Visual Studio 7") - # Assume people are generally using 7.1, - # if using 7.0 need to link to: ../extern/lib/win32/microsoft/msvc70 - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/msvc71") - else() - if(${CMAKE_GENERATOR} MATCHES "Borland") - # Same here, there are also: bcc50 and bcc51 directories - set(MATLAB_ROOT "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/lib/win32/microsoft/bcc54") - else() - if(MATLAB_FIND_REQUIRED) - message(FATAL_ERROR "Generator not compatible: ${CMAKE_GENERATOR}") - endif() + message(WARNING "The release name ${release_name} is not registered") + endif() + unset(_matched) + +endmacro() + + + + + +#.rst: +# .. command:: matlab_get_release_name_from_version +# +# Returns the release name (R2017k) from the version of Matlab (17.58) +macro (matlab_get_release_name_from_version version release_name) + + set(${release_name} "") + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=${version}" _matched ${_var}) + if(NOT _matched STREQUAL "") + set(${release_name} ${CMAKE_MATCH_1}) + break() + endif() + endforeach(_var) + + unset(_var) + unset(_matched) + if(${release_name} STREQUAL "") + message(WARNING "The version ${version} is not registered") + endif() + +endmacro() + + + + + +# extracts all the supported release names (R2017k...) of Matlab +# internal use +macro(matlab_get_supported_releases list_releases) + set(${list_releases}) + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) + if(NOT _matched STREQUAL "") + list(APPEND ${list_releases} ${CMAKE_MATCH_1}) + endif() + unset(_matched) + unset(CMAKE_MATCH_1) + endforeach(_var) + unset(_var) +endmacro() + + + +# extracts all the supported versions of Matlab +# internal use +macro(matlab_get_supported_versions list_versions) + set(${list_versions}) + foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) + string(REGEX MATCHALL "(.+)=([0-9]+\\.?[0-9]*)" _matched ${_var}) + if(NOT _matched STREQUAL "") + list(APPEND ${list_versions} ${CMAKE_MATCH_2}) + endif() + unset(_matched) + unset(CMAKE_MATCH_1) + endforeach(_var) + unset(_var) +endmacro() + + +#.rst: +# .. command:: matlab_extract_all_installed_versions_from_registry +# +# This function parses the registry and founds the Matlab versions that are +# installed. The found versions are returned in `matlab_versions`. +# Set `win64` to `TRUE` if the 64 bit version of Matlab should be looked for +# The returned list contains all versions under +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` or an empty list in case an error +# occurred (or nothing found). +# +# .. note:: +# +# Only the versions are provided. No check is made over the existence of the +# installation referenced in the registry, +# +function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions) + + if(NOT CMAKE_HOST_WIN32) + message(FATAL_ERROR "This macro can only be called by a windows host (call to reg.exe") + endif() + + + if(${win64} AND ${CMAKE_HOST_SYSTEM_PROCESSOR} MATCHES "64") + set(APPEND_REG "/reg:64") + else() + set(APPEND_REG "/reg:32") + endif() + + # /reg:64 should be added on 64 bits capable OSs in order to enable the + # redirection of 64 bits applications + execute_process( + COMMAND reg query HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\MATLAB /f * /k ${APPEND_REG} + RESULT_VARIABLE resultMatlab + OUTPUT_VARIABLE varMatlab + ERROR_VARIABLE errMatlab + INPUT_FILE NUL + ) + + + set(matlabs_from_registry) + if(${resultMatlab} EQUAL 0) + + string( + REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" + matlab_versions_regex ${varMatlab}) + + foreach(match IN LISTS matlab_versions_regex) + string( + REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" + current_match ${match}) + + set(_matlab_current_version ${CMAKE_MATCH_1}) + set(current_matlab_version_major ${CMAKE_MATCH_2}) + set(current_matlab_version_minor ${CMAKE_MATCH_4}) + if(NOT current_matlab_version_minor) + set(current_matlab_version_minor "0") endif() + + list(APPEND matlabs_from_registry ${_matlab_current_version}) + unset(_matlab_current_version) + endforeach(match) + + endif() + + if(matlabs_from_registry) + list(REMOVE_DUPLICATES matlabs_from_registry) + list(SORT matlabs_from_registry) + list(REVERSE matlabs_from_registry) + endif() + + set(${matlab_versions} ${matlabs_from_registry} PARENT_SCOPE) + +endfunction() + + + +# (internal) +macro(extract_matlab_versions_from_registry_brute_force matlab_versions) + # get the supported versions + set(matlab_supported_versions) + matlab_get_supported_versions(matlab_supported_versions) + + + # this is a manual population of the versions we want to look for + # this can be done as is, but preferably with the call to + # matlab_get_supported_versions and variable + + # populating the versions we want to look for + # set(matlab_supported_versions) + + # # Matlab 7 + # set(matlab_major 7) + # foreach(current_matlab_minor RANGE 4 20) + # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") + # endforeach(current_matlab_minor) + + # # Matlab 8 + # set(matlab_major 8) + # foreach(current_matlab_minor RANGE 0 5) + # list(APPEND matlab_supported_versions "${matlab_major}.${current_matlab_minor}") + # endforeach(current_matlab_minor) + + # # taking into account the possible additional versions provided by the user + # if(DEFINED MATLAB_ADDITIONAL_VERSIONS) + # list(APPEND matlab_supported_versions MATLAB_ADDITIONAL_VERSIONS) + # endif() + + + # we order from more recent to older + if(matlab_supported_versions) + list(REMOVE_DUPLICATES matlab_supported_versions) + list(SORT matlab_supported_versions) + list(REVERSE matlab_supported_versions) + endif() + + + set(${matlab_versions} ${matlab_supported_versions}) + + +endmacro() + + + + +#.rst: +# .. command:: matlab_get_all_valid_matlab_roots_from_registry +# +# Populates the Matlab root with valid versions of Matlab. +# The returned matlab_roots is organized in pairs +# ``(version_number,matlab_root_path)``. +# +# :: +# +# matlab_get_all_valid_matlab_roots_from_registry( +# matlab_versions +# matlab_roots) +# +# ``matlab_versions`` +# the versions of each of the Matlab installations +# ``matlab_roots`` +# the location of each of the Matlab installations +function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_roots) + + # The matlab_versions comes either from + # extract_matlab_versions_from_registry_brute_force or + # matlab_extract_all_installed_versions_from_registry. + + + set(_matlab_roots_list ) + foreach(_matlab_current_version ${matlab_versions}) + get_filename_component( + current_MATLAB_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]" + ABSOLUTE) + + if(EXISTS ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list ${_matlab_current_version} ${current_MATLAB_ROOT}) + endif() + + endforeach(_matlab_current_version) + unset(_matlab_current_version) + set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE) + unset(_matlab_roots_list) +endfunction() + +#.rst: +# .. command:: matlab_get_mex_suffix +# +# Returns the extension of the mex files (the suffixes). +# This function should not be called before the appropriate Matlab root has +# been found. +# +# :: +# +# matlab_get_mex_suffix( +# matlab_root +# mex_suffix) +# +# ``matlab_root`` +# the root of the Matlab installation +# ``mex_suffix`` +# the variable name in which the suffix will be returned. +function(matlab_get_mex_suffix matlab_root mex_suffix) + + # todo setup the extension properly. Currently I do not know if this is + # sufficient for all win32 distributions. + # there is also CMAKE_EXECUTABLE_SUFFIX that could be tweaked + set(mexext_suffix "") + if(WIN32) + list(APPEND mexext_suffix ".bat") + endif() + + # we first try without suffix, since cmake does not understand a list with + # one empty string element + find_program( + Matlab_MEXEXTENSIONS_PROG + NAMES mexext + PATHS ${matlab_root}/bin + DOC "Matlab MEX extension provider" + NO_DEFAULT_PATH + ) + + foreach(current_mexext_suffix IN LISTS mexext_suffix) + if(NOT DEFINED Matlab_MEXEXTENSIONS_PROG OR NOT Matlab_MEXEXTENSIONS_PROG) + # this call should populate the cache automatically + find_program( + Matlab_MEXEXTENSIONS_PROG + "mexext${current_mexext_suffix}" + PATHS ${matlab_root}/bin + DOC "Matlab MEX extension provider" + NO_DEFAULT_PATH + ) + endif() + endforeach(current_mexext_suffix) + + + # the program has been found? + if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG})) + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot found mexext program. Matlab root is ${matlab_root}") + endif() + unset(Matlab_MEXEXTENSIONS_PROG CACHE) + return() + endif() + + set(_matlab_mex_extension) + + set(devnull) + if(UNIX) + set(devnull INPUT_FILE /dev/null) + elseif(WIN32) + set(devnull INPUT_FILE NUL) + endif() + + execute_process( + COMMAND ${Matlab_MEXEXTENSIONS_PROG} + OUTPUT_VARIABLE _matlab_mex_extension + ERROR_VARIABLE _matlab_mex_extension_error + ${devnull}) + string(STRIP ${_matlab_mex_extension} _matlab_mex_extension) + + unset(Matlab_MEXEXTENSIONS_PROG CACHE) + set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE) +endfunction() + + + + +#.rst: +# .. command:: matlab_get_version_from_matlab_run +# +# This function runs Matlab program specified on arguments and extracts its +# version. +# +# :: +# +# matlab_get_version_from_matlab_run( +# matlab_binary_path +# matlab_list_versions) +# +# ``matlab_binary_path`` +# the location of the `matlab` binary executable +# ``matlab_list_versions`` +# the version extracted from Matlab +function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_versions) + + set(${matlab_list_versions} "" PARENT_SCOPE) + + + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}") + endif() + + if(EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Removing previous ${_matlab_temporary_folder}/matlabVersionLog.cmaketmp file") endif() + file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + endif() + + + # the log file is needed since on windows the command executes in a new + # window and it is not possible to get back the answer of Matlab + # the -wait command is needed on windows, otherwise the call returns + # immediately after the program launches itself. + if(WIN32) + set(_matlab_additional_commands "-wait") endif() - find_library(MATLAB_MEX_LIBRARY - libmex - ${MATLAB_ROOT} + + set(devnull) + if(UNIX) + set(devnull INPUT_FILE /dev/null) + elseif(WIN32) + set(devnull INPUT_FILE NUL) + endif() + + # timeout set to 30 seconds, in case it does not start + # note as said before OUTPUT_VARIABLE cannot be used in a platform + # independent manner however, not setting it would flush the output of Matlab + # in the current console (unix variant) + execute_process( + COMMAND "${matlab_binary_program}" -nosplash -nojvm ${_matlab_additional_commands} -logfile "matlabVersionLog.cmaketmp" -nodesktop -nodisplay -r "version, exit" + OUTPUT_VARIABLE _matlab_version_from_cmd_dummy + RESULT_VARIABLE _matlab_result_version_call + ERROR_VARIABLE _matlab_result_version_call_error + TIMEOUT 30 + WORKING_DIRECTORY "${_matlab_temporary_folder}" + ${devnull} ) - find_library(MATLAB_MX_LIBRARY - libmx - ${MATLAB_ROOT} + + + if(${_matlab_result_version_call}) + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. Matlab call returned with error ${_matlab_result_version_call}.") + endif() + return() + elseif(NOT EXISTS "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Unable to determine the version of Matlab. The log file does not exist.") + endif() + return() + endif() + + # if successful, read back the log + file(READ "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp" _matlab_version_from_cmd) + file(REMOVE "${_matlab_temporary_folder}/matlabVersionLog.cmaketmp") + + set(index -1) + string(FIND ${_matlab_version_from_cmd} "ans" index) + if(index EQUAL -1) + + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot find the version of Matlab returned by the run.") + endif() + + else() + set(matlab_list_of_all_versions_tmp) + + string(SUBSTRING ${_matlab_version_from_cmd} ${index} -1 substring_ans) + string( + REGEX MATCHALL "ans[\r\n\t ]*=[\r\n\t ]*([0-9]+(\\.[0-9]+)?)" + matlab_versions_regex + ${substring_ans}) + foreach(match IN LISTS matlab_versions_regex) + string( + REGEX MATCH "ans[\r\n\t ]*=[\r\n\t ]*(([0-9]+)(\\.([0-9]+))?)" + current_match ${match}) + + list(APPEND matlab_list_of_all_versions_tmp ${CMAKE_MATCH_1}) + endforeach() + if(matlab_list_of_all_versions_tmp) + list(REMOVE_DUPLICATES matlab_list_of_all_versions_tmp) + endif() + set(${matlab_list_versions} ${matlab_list_of_all_versions_tmp} PARENT_SCOPE) + + endif() + +endfunction() + + +#.rst: +# .. command:: matlab_add_unit_test +# +# Adds a Matlab unit test to the test set of cmake/ctest. +# This command requires the component ``MAIN_PROGRAM``. +# The unit test uses the Matlab unittest framework (default, available +# starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK`` +# is given. +# +# The function expects one Matlab test script file to be given. +# In the case ``NO_UNITTEST_FRAMEWORK`` is given, the unittest script file +# should contain the script to be run, plus an exit command with the exit +# value. This exit value will be passed to the ctest framework (0 success, +# non 0 failure). Additional arguments accepted by :command:`add_test` can be +# passed through ``TEST_ARGS`` (eg. ``CONFIGURATION <config> ...``). +# +# :: +# +# matlab_add_unit_test( +# NAME <name> +# UNITTEST_FILE matlab_file_containing_unittest.m +# [UNITTEST_PRECOMMAND matlab_command_to_run] +# [TIMEOUT timeout] +# [ADDITIONAL_PATH path1 [path2 ...]] +# [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]] +# [TEST_ARGS arg1 [arg2 ...]] +# [NO_UNITTEST_FRAMEWORK] +# ) +# +# The function arguments are: +# +# ``NAME`` +# name of the unittest in ctest. +# ``UNITTEST_FILE`` +# the matlab unittest file. Its path will be automatically +# added to the Matlab path. +# ``UNITTEST_PRECOMMAND`` +# Matlab script command to be ran before the file +# containing the test (eg. GPU device initialisation based on CMake +# variables). +# ``TIMEOUT`` +# the test timeout in seconds. Defaults to 180 seconds as the +# Matlab unit test may hang. +# ``ADDITIONAL_PATH`` +# a list of paths to add to the Matlab path prior to +# running the unit test. +# ``MATLAB_ADDITIONAL_STARTUP_OPTIONS`` +# a list of additional option in order +# to run Matlab from the command line. +# ``TEST_ARGS`` +# Additional options provided to the add_test command. These +# options are added to the default options (eg. "CONFIGURATIONS Release") +# ``NO_UNITTEST_FRAMEWORK`` +# when set, indicates that the test should not +# use the unittest framework of Matlab (available for versions >= R2013a). +# +function(matlab_add_unit_test) + + if(NOT Matlab_MAIN_PROGRAM) + message(FATAL_ERROR "[MATLAB] This functionality needs the MAIN_PROGRAM component (not default)") + endif() + + set(options NO_UNITTEST_FRAMEWORK) + set(oneValueArgs NAME UNITTEST_PRECOMMAND UNITTEST_FILE TIMEOUT) + set(multiValueArgs ADDITIONAL_PATH MATLAB_ADDITIONAL_STARTUP_OPTIONS TEST_ARGS) + + set(prefix _matlab_unittest_prefix) + cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if(NOT ${prefix}_NAME) + message(FATAL_ERROR "[MATLAB] The Matlab test name cannot be empty") + endif() + + add_test(NAME ${${prefix}_NAME} + COMMAND ${CMAKE_COMMAND} + -Dtest_name=${${prefix}_NAME} + -Dadditional_paths=${${prefix}_ADDITIONAL_PATH} + -Dtest_timeout=${${prefix}_TIMEOUT} + -Doutput_directory=${_matlab_temporary_folder} + -DMatlab_PROGRAM=${Matlab_MAIN_PROGRAM} + -Dno_unittest_framework=${${prefix}_NO_UNITTEST_FRAMEWORK} + -DMatlab_ADDITIONNAL_STARTUP_OPTIONS=${${prefix}_MATLAB_ADDITIONAL_STARTUP_OPTIONS} + -Dunittest_file_to_run=${${prefix}_UNITTEST_FILE} + -Dcmd_to_run_before_test=${${prefix}_UNITTEST_PRECOMMAND} + -P ${_FindMatlab_SELF_DIR}/MatlabTestsRedirect.cmake + ${${prefix}_TEST_ARGS} + ${${prefix}_UNPARSED_ARGUMENTS} + ) +endfunction() + + +#.rst: +# .. command:: matlab_add_mex +# +# Adds a Matlab MEX target. +# This commands compiles the given sources with the current tool-chain in +# order to produce a MEX file. The final name of the produced output may be +# specified, as well as additional link libraries, and a documentation entry +# for the MEX file. Remaining arguments of the call are passed to the +# :command:`add_library` command. +# +# :: +# +# matlab_add_mex( +# NAME <name> +# SRC src1 [src2 ...] +# [OUTPUT_NAME output_name] +# [DOCUMENTATION file.txt] +# [LINK_TO target1 target2 ...] +# [...] +# ) +# +# ``NAME`` +# name of the target. +# ``SRC`` +# list of tje source files. +# ``LINK_TO`` +# a list of additional link dependencies. The target links to ``libmex`` +# by default. If ``Matlab_MX_LIBRARY`` is defined, it also +# links to ``libmx``. +# ``OUTPUT_NAME`` +# if given, overrides the default name. The default name is +# the name of the target without any prefix and +# with ``Matlab_MEX_EXTENSION`` suffix. +# ``DOCUMENTATION`` +# if given, the file ``file.txt`` will be considered as +# being the documentation file for the MEX file. This file is copied into +# the same folder without any processing, with the same name as the final +# mex file, and with extension `.m`. In that case, typing ``help <name>`` +# in Matlab prints the documentation contained in this file. +# +# The documentation file is not processed and should be in the following +# format: +# +# :: +# +# % This is the documentation +# function ret = mex_target_output_name(input1) +# +function(matlab_add_mex ) + + if(NOT WIN32) + # we do not need all this on Windows + # pthread options + check_cxx_compiler_flag(-pthread HAS_MINUS_PTHREAD) + # we should use try_compile instead, the link flags are discarded from + # this compiler_flag function. + #check_cxx_compiler_flag(-Wl,--exclude-libs,ALL HAS_SYMBOL_HIDING_CAPABILITY) + + endif() + + set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME) + set(multiValueArgs LINK_TO SRC) + + set(prefix _matlab_addmex_prefix) + cmake_parse_arguments(${prefix} "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) + + if(NOT ${prefix}_NAME) + message(FATAL_ERROR "[MATLAB] The MEX target name cannot be empty") + endif() + + if(NOT ${prefix}_OUTPUT_NAME) + set(${prefix}_OUTPUT_NAME ${${prefix}_NAME}) + endif() + + add_library(${${prefix}_NAME} + SHARED + ${${prefix}_SRC} + ${${prefix}_DOCUMENTATION} + ${${prefix}_UNPARSED_ARGUMENTS}) + target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS}) + + if(DEFINED Matlab_MX_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_MX_LIBRARY}) + endif() + + target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${${prefix}_LINK_TO}) + set_target_properties(${${prefix}_NAME} + PROPERTIES + PREFIX "" + OUTPUT_NAME ${${prefix}_OUTPUT_NAME} + SUFFIX ".${Matlab_MEX_EXTENSION}") + + + # documentation + if(NOT ${${prefix}_DOCUMENTATION} STREQUAL "") + get_target_property(output_name ${${prefix}_NAME} OUTPUT_NAME) + add_custom_command( + TARGET ${${prefix}_NAME} + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${${prefix}_DOCUMENTATION} $<TARGET_FILE_DIR:${${prefix}_NAME}>/${output_name}.m + COMMENT "Copy ${${prefix}_NAME} documentation file into the output folder" ) - find_library(MATLAB_ENG_LIBRARY - libeng - ${MATLAB_ROOT} + endif() # documentation + + # entry point in the mex file + taking care of visibility and symbol clashes. + if(WIN32) + set_target_properties(${${prefix}_NAME} + PROPERTIES + DEFINE_SYMBOL "DLL_EXPORT_SYM=__declspec(dllexport)") + else() + + if(HAS_MINUS_PTHREAD AND NOT APPLE) + # Apparently, compiling with -pthread generated the proper link flags + # and some defines at compilation + target_compile_options(${${prefix}_NAME} PRIVATE "-pthread") + endif() + + + # if we do not do that, the symbols linked from eg. boost remain weak and + # then clash with the ones defined in the matlab process. So by default + # the symbols are hidden. + # This also means that for shared libraries (like MEX), the entry point + # should be explicitly declared with default visibility, otherwise Matlab + # cannot find the entry point. + # Note that this is particularly meaningful if the MEX wrapper itself + # contains symbols that are clashing with Matlab (that are compiled in the + # MEX file). In order to propagate the visibility options to the libraries + # to which the MEX file is linked against, the -Wl,--exclude-libs,ALL + # option should also be specified. + + set_target_properties(${${prefix}_NAME} + PROPERTIES + CXX_VISIBILITY_PRESET "hidden" + C_VISIBILITY_PRESET "hidden" + VISIBILITY_INLINES_HIDDEN "hidden" ) - find_path(MATLAB_INCLUDE_DIR - "mex.h" - "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\7.0;MATLABROOT]/extern/include" + # get_target_property( + # _previous_link_flags + # ${${prefix}_NAME} + # LINK_FLAGS) + # if(NOT _previous_link_flags) + # set(_previous_link_flags) + # endif() + + # if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") + # set_target_properties(${${prefix}_NAME} + # PROPERTIES + # LINK_FLAGS "${_previous_link_flags} -Wl,--exclude-libs,ALL" + # # -Wl,--version-script=${_FindMatlab_SELF_DIR}/MatlabLinuxVisibility.map" + # ) + # elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") + # # in this case, all other symbols become hidden. + # set_target_properties(${${prefix}_NAME} + # PROPERTIES + # LINK_FLAGS "${_previous_link_flags} -Wl,-exported_symbol,_mexFunction" + # #-Wl,-exported_symbols_list,${_FindMatlab_SELF_DIR}/MatlabOSXVisilibity.map" + # ) + # endif() + + + + set_target_properties(${${prefix}_NAME} + PROPERTIES + DEFINE_SYMBOL "DLL_EXPORT_SYM=__attribute__ ((visibility (\"default\")))" ) -else() - if(CMAKE_SIZEOF_VOID_P EQUAL 4) - # Regular x86 - set(MATLAB_ROOT - /usr/local/matlab-7sp1/bin/glnx86/ - /opt/matlab-7sp1/bin/glnx86/ - $ENV{HOME}/matlab-7sp1/bin/glnx86/ - $ENV{HOME}/redhat-matlab/bin/glnx86/ + + + endif() + +endfunction() + + +# (internal) +# Used to get the version of matlab, using caching. This basically transforms the +# output of the root list, with possible unknown version, to a version +# +function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_final_version) + + # if the version is not trivial, we query matlab for that + # we keep track of the location of matlab that induced this version + #if(NOT DEFINED Matlab_PROG_VERSION_STRING_AUTO_DETECT) + # set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version") + #endif() + + if(NOT ${matlab_known_version} STREQUAL "NOTFOUND") + # the version is known, we just return it + set(${matlab_final_version} ${matlab_known_version} PARENT_SCOPE) + set(Matlab_VERSION_STRING_INTERNAL ${matlab_known_version} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + return() + endif() + + # + set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) + + # do we already have a matlab program? + if(NOT _matlab_current_program) + + set(_find_matlab_options) + if(matlab_root AND EXISTS ${matlab_root}) + set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) + endif() + + find_program( + _matlab_current_program + matlab + ${_find_matlab_options} + DOC "Matlab main program" ) + endif() + + if(NOT _matlab_current_program OR NOT EXISTS ${_matlab_current_program}) + # if not found, clear the dependent variables + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Cannot find the main matlab program under ${matlab_root}") + endif() + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) + return() + endif() + + # full real path for path comparison + get_filename_component(_matlab_main_real_path_tmp "${_matlab_current_program}" REALPATH) + unset(_matlab_current_program) + unset(_matlab_current_program CACHE) + + # is it the same as the previous one? + if(_matlab_main_real_path_tmp STREQUAL Matlab_PROG_VERSION_STRING_AUTO_DETECT) + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + return() + endif() + + # update the location of the program + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT ${_matlab_main_real_path_tmp} CACHE INTERNAL "internal matlab location for the discovered version" FORCE) + + set(matlab_list_of_all_versions) + matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + + list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) + + # set the version into the cache + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + + # warning, just in case several versions found (should not happen) + list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) + if((${list_of_all_versions_length} GREATER 1) AND MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Found several versions, taking the first one (versions found ${matlab_list_of_all_versions})") + endif() + + # return the updated value + set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + +endfunction() + + + + + + + +# ################################### +# Exploring the possible Matlab_ROOTS + +# this variable will get all Matlab installations found in the current system. +set(_matlab_possible_roots) + + + +if(Matlab_ROOT_DIR) + # if the user specifies a possible root, we keep this one + + if(NOT EXISTS ${Matlab_ROOT_DIR}) + # if Matlab_ROOT_DIR specified but erroneous + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") + endif() else() - # AMD64: - set(MATLAB_ROOT - /usr/local/matlab-7sp1/bin/glnxa64/ - /opt/matlab-7sp1/bin/glnxa64/ - $ENV{HOME}/matlab7_64/bin/glnxa64/ - $ENV{HOME}/matlab-7sp1/bin/glnxa64/ - $ENV{HOME}/redhat-matlab/bin/glnxa64/ - ) + # NOTFOUND indicates the code below to search for the version automatically + if(NOT DEFINED Matlab_VERSION_STRING_INTERNAL) + list(APPEND _matlab_possible_roots "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version + else() + list(APPEND _matlab_possible_roots ${Matlab_VERSION_STRING_INTERNAL} ${Matlab_ROOT_DIR}) # cached version + endif() + endif() + + +else() + + # if the user does not specify the possible installation root, we look for + # one installation using the appropriate heuristics + + if(WIN32) + + # On WIN32, we look for Matlab installation in the registry + # if unsuccessful, we look for all known revision and filter the existing + # ones. + + # testing if we are able to extract the needed information from the registry + set(_matlab_versions_from_registry) + matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry) + + # the returned list is empty, doing the search on all known versions + if(NOT _matlab_versions_from_registry) + + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") + endif() + + extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) + endif() + + # filtering the results with the registry keys + matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) + unset(_matlab_versions_from_registry) + + elseif(APPLE) + + # on mac, we look for the /Application paths + # this corresponds to the behaviour on Windows. On Linux, we do not have + # any other guess. + matlab_get_supported_releases(_matlab_releases) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Matlab supported versions ${_matlab_releases}. If more version should be supported " + "the variable MATLAB_ADDITIONAL_VERSIONS can be set according to the documentation") + endif() + + foreach(_matlab_current_release IN LISTS _matlab_releases) + set(_matlab_full_string "/Applications/MATLAB_${_matlab_current_release}.app") + if(EXISTS ${_matlab_full_string}) + set(_matlab_current_version) + matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_full_string}") + endif() + list(APPEND _matlab_possible_roots ${_matlab_current_version} ${_matlab_full_string}) + unset(_matlab_current_version) + endif() + + unset(_matlab_full_string) + endforeach(_matlab_current_release) + + unset(_matlab_current_release) + unset(_matlab_releases) + endif() - find_library(MATLAB_MEX_LIBRARY - mex - ${MATLAB_ROOT} - ) - find_library(MATLAB_MX_LIBRARY - mx - ${MATLAB_ROOT} - ) - find_library(MATLAB_ENG_LIBRARY - eng - ${MATLAB_ROOT} - ) - find_path(MATLAB_INCLUDE_DIR - "mex.h" - "/usr/local/matlab-7sp1/extern/include/" - "/opt/matlab-7sp1/extern/include/" - "$ENV{HOME}/matlab-7sp1/extern/include/" - "$ENV{HOME}/redhat-matlab/extern/include/" - ) endif() -# This is common to UNIX and Win32: -set(MATLAB_LIBRARIES - ${MATLAB_MEX_LIBRARY} - ${MATLAB_MX_LIBRARY} - ${MATLAB_ENG_LIBRARY} + + +list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) +if(_numbers_of_matlab_roots EQUAL 0) + # if we have not found anything, we fall back on the PATH + + + # At this point, we have no other choice than trying to find it from PATH. + # If set by the user, this wont change + find_program( + _matlab_main_tmp + NAMES matlab) + + + if(_matlab_main_tmp) + # we then populate the list of roots, with empty version + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] matlab found from PATH: ${_matlab_main_tmp}") + endif() + + # resolve symlinks + get_filename_component(_matlab_current_location "${_matlab_main_tmp}" REALPATH) + + # get the directory (the command below has to be run twice) + # this will be the matlab root + get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) + get_filename_component(_matlab_current_location "${_matlab_current_location}" DIRECTORY) # Matlab should be in bin + + list(APPEND _matlab_possible_roots "NOTFOUND" ${_matlab_current_location}) + + unset(_matlab_current_location) + + endif() + unset(_matlab_main_tmp CACHE) + +endif() + + + + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Matlab root folders are ${_matlab_possible_roots}") +endif() + + + + + +# take the first possible Matlab root +list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) +set(Matlab_VERSION_STRING "NOTFOUND") +if(_numbers_of_matlab_roots GREATER 0) + list(GET _matlab_possible_roots 0 Matlab_VERSION_STRING) + list(GET _matlab_possible_roots 1 Matlab_ROOT_DIR) + + # adding a warning in case of ambiguity + if(_numbers_of_matlab_roots GREATER 2 AND MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Found several distributions of Matlab. Setting the current version to ${Matlab_VERSION_STRING} (located ${Matlab_ROOT_DIR})." + " If this is not the desired behaviour, provide the -DMatlab_ROOT_DIR=... on the command line") + endif() +endif() + + +# check if the root changed against the previous defined one, if so +# clear all the cached variables +if(DEFINED Matlab_ROOT_DIR_LAST_CACHED) + + if(NOT Matlab_ROOT_DIR_LAST_CACHED STREQUAL Matlab_ROOT_DIR) + set(_Matlab_cached_vars + Matlab_INCLUDE_DIRS + Matlab_MEX_LIBRARY + Matlab_MEX_COMPILER + Matlab_MAIN_PROGRAM + Matlab_MX_LIBRARY + Matlab_ENG_LIBRARY + Matlab_MEX_EXTENSION + + # internal + Matlab_MEXEXTENSIONS_PROG + Matlab_ROOT_DIR_LAST_CACHED + #Matlab_PROG_VERSION_STRING_AUTO_DETECT + Matlab_VERSION_STRING_INTERNAL + ) + foreach(_var IN LISTS _Matlab_cached_vars) + if(DEFINED ${_var}) + unset(${_var} CACHE) + endif() + endforeach() + endif() +endif() + +set(Matlab_ROOT_DIR_LAST_CACHED ${Matlab_ROOT_DIR} CACHE INTERNAL "last Matlab root dir location") +set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path" FORCE) + +# Fix the version, in case this one is NOTFOUND +_Matlab_get_version_from_root( + "${Matlab_ROOT_DIR}" + ${Matlab_VERSION_STRING} + Matlab_VERSION_STRING ) -if(MATLAB_INCLUDE_DIR AND MATLAB_LIBRARIES) - set(MATLAB_FOUND 1) + + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}") endif() -mark_as_advanced( - MATLAB_LIBRARIES - MATLAB_MEX_LIBRARY - MATLAB_MX_LIBRARY - MATLAB_ENG_LIBRARY - MATLAB_INCLUDE_DIR - MATLAB_FOUND - MATLAB_ROOT + + +if(Matlab_ROOT_DIR) + file(TO_CMAKE_PATH ${Matlab_ROOT_DIR} Matlab_ROOT_DIR) +endif() + +if(CMAKE_SIZEOF_VOID_P EQUAL 4) + set(_matlab_64Build FALSE) +else() + set(_matlab_64Build TRUE) +endif() + +if(APPLE) + set(_matlab_bin_prefix "mac") # i should be for intel + set(_matlab_bin_suffix_32bits "i") + set(_matlab_bin_suffix_64bits "i64") +elseif(UNIX) + set(_matlab_bin_prefix "gln") + set(_matlab_bin_suffix_32bits "x86") + set(_matlab_bin_suffix_64bits "xa64") +else() + set(_matlab_bin_prefix "win") + set(_matlab_bin_suffix_32bits "32") + set(_matlab_bin_suffix_64bits "64") +endif() + + + +set(MATLAB_INCLUDE_DIR_TO_LOOK ${Matlab_ROOT_DIR}/extern/include) +if(_matlab_64Build) + set(_matlab_current_suffix ${_matlab_bin_suffix_64bits}) +else() + set(_matlab_current_suffix ${_matlab_bin_suffix_32bits}) +endif() + +set(Matlab_BINARIES_DIR + ${Matlab_ROOT_DIR}/bin/${_matlab_bin_prefix}${_matlab_current_suffix}) +set(Matlab_EXTERN_LIBRARY_DIR + ${Matlab_ROOT_DIR}/extern/lib/${_matlab_bin_prefix}${_matlab_current_suffix}) + +if(WIN32) + set(_matlab_lib_dir_for_search ${Matlab_EXTERN_LIBRARY_DIR}/microsoft) + set(_matlab_lib_prefix_for_search "lib") +else() + set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR}) + set(_matlab_lib_prefix_for_search "lib") +endif() + +unset(_matlab_64Build) + + +if(NOT DEFINED Matlab_MEX_EXTENSION) + set(_matlab_mex_extension "") + matlab_get_mex_suffix("${Matlab_ROOT_DIR}" _matlab_mex_extension) + + # This variable goes to the cache. + set(Matlab_MEX_EXTENSION ${_matlab_mex_extension} CACHE STRING "Extensions for the mex targets (automatically given by Matlab)") + unset(_matlab_mex_extension) +endif() + + +if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] [DEBUG]_matlab_lib_prefix_for_search = ${_matlab_lib_prefix_for_search} | _matlab_lib_dir_for_search = ${_matlab_lib_dir_for_search}") +endif() + + + +# internal +# This small stub around find_library is to prevent any pollution of CMAKE_FIND_LIBRARY_PREFIXES in the global scope. +# This is the function to be used below instead of the find_library directives. +function(_Matlab_find_library _matlab_library_prefix) + set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} ${_matlab_library_prefix}) + find_library(${ARGN}) +endfunction() + + +set(_matlab_required_variables) + + +# the MEX library/header are required +find_path( + Matlab_INCLUDE_DIRS + mex.h + PATHS ${MATLAB_INCLUDE_DIR_TO_LOOK} + NO_DEFAULT_PATH + ) +list(APPEND _matlab_required_variables Matlab_INCLUDE_DIRS) + +_Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MEX_LIBRARY + mex + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH ) + + +list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY) + +# the MEX extension is required +list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION) + +# the matlab root is required +list(APPEND _matlab_required_variables Matlab_ROOT_DIR) + + +# component Mex Compiler +list(FIND Matlab_FIND_COMPONENTS MEX_COMPILER _matlab_find_mex_compiler) +if(_matlab_find_mex_compiler GREATER -1) + find_program( + Matlab_MEX_COMPILER + "mex" + PATHS ${Matlab_BINARIES_DIR} + DOC "Matlab MEX compiler" + NO_DEFAULT_PATH + ) + + if(Matlab_MEX_COMPILER) + set(Matlab_MEX_COMPILER_FOUND TRUE) + endif() +endif() +unset(_matlab_find_mex_compiler) + +# component Matlab program +list(FIND Matlab_FIND_COMPONENTS MAIN_PROGRAM _matlab_find_matlab_program) +if(_matlab_find_matlab_program GREATER -1) + + find_program( + Matlab_MAIN_PROGRAM + matlab + PATHS ${Matlab_ROOT_DIR} ${Matlab_ROOT_DIR}/bin + DOC "Matlab main program" + NO_DEFAULT_PATH + ) + + if(Matlab_MAIN_PROGRAM) + set(Matlab_MAIN_PROGRAM_FOUND TRUE) + endif() + +endif() +unset(_matlab_find_matlab_program) + +# Component MX library +list(FIND Matlab_FIND_COMPONENTS MX_LIBRARY _matlab_find_mx) +if(_matlab_find_mx GREATER -1) + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MX_LIBRARY + mx + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + + if(Matlab_MX_LIBRARY) + set(Matlab_MX_LIBRARY_FOUND TRUE) + endif() +endif() +unset(_matlab_find_mx) + + +# Component ENG library +list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng) +if(_matlab_find_eng GREATER -1) + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_ENG_LIBRARY + eng + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + if(Matlab_ENG_LIBRARY) + set(Matlab_ENG_LIBRARY_FOUND TRUE) + endif() +endif() +unset(_matlab_find_eng) + + + + + +unset(_matlab_lib_dir_for_search) + + +set(Matlab_LIBRARIES ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${Matlab_ENG_LIBRARY}) + + +find_package_handle_standard_args( + Matlab + FOUND_VAR Matlab_FOUND + REQUIRED_VARS ${_matlab_required_variables} + VERSION_VAR Matlab_VERSION_STRING + HANDLE_COMPONENTS) + +unset(_matlab_required_variables) +unset(_matlab_bin_prefix) +unset(_matlab_bin_suffix_32bits) +unset(_matlab_bin_suffix_64bits) +unset(_matlab_current_suffix) +unset(_matlab_lib_dir_for_search) +unset(_matlab_lib_prefix_for_search) + +if(Matlab_INCLUDE_DIRS AND Matlab_LIBRARIES) + mark_as_advanced( + #Matlab_LIBRARIES + Matlab_MEX_LIBRARY + Matlab_MX_LIBRARY + Matlab_ENG_LIBRARY + Matlab_INCLUDE_DIRS + Matlab_FOUND + #Matlab_ROOT_DIR + #Matlab_VERSION_STRING + Matlab_MAIN_PROGRAM + #Matlab_MEX_EXTENSION + Matlab_MEXEXTENSIONS_PROG + Matlab_MEX_EXTENSION + #Matlab_BINARIES_DIR + ) +endif() diff --git a/Modules/MatlabTestsRedirect.cmake b/Modules/MatlabTestsRedirect.cmake new file mode 100644 index 0000000..ebccbf6 --- /dev/null +++ b/Modules/MatlabTestsRedirect.cmake @@ -0,0 +1,92 @@ +# This is an undocumented internal helper for the FindMatlab +# module ``matlab_add_unit_test`` command. + +#============================================================================= +# Copyright 2014-2015 Raffi Enficiaud, Max Planck Society +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +# Usage: cmake +# -Dtest_timeout=180 +# -Dworking_directory="." +# -Doutput_directory= +# -Dadditional_paths="" +# -Dno_unittest_framework="" +# -DMatlab_PROGRAM=matlab_exe_location +# -DMatlab_ADDITIONNAL_STARTUP_OPTIONS="" +# -Dtest_name=name_of_the_test +# -Dcmd_to_run_before_test="" +# -Dunittest_file_to_run +# -P FindMatlab_TestsRedirect.cmake + +set(Matlab_UNIT_TESTS_CMD -nosplash -nojvm -nodesktop -nodisplay ${Matlab_ADDITIONNAL_STARTUP_OPTIONS}) +if(WIN32) + set(Matlab_UNIT_TESTS_CMD ${Matlab_UNIT_TESTS_CMD} -wait) +endif() + +if(NOT test_timeout) + set(test_timeout 180) +endif() + +if(NOT cmd_to_run_before_test) + set(cmd_to_run_before_test) +endif() + +get_filename_component(unittest_file_directory "${unittest_file_to_run}" DIRECTORY) +get_filename_component(unittest_file_to_run_name "${unittest_file_to_run}" NAME_WE) + +set(concat_string '${unittest_file_directory}') +foreach(s IN LISTS additional_paths) + if(NOT "${s}" STREQUAL "") + set(concat_string "${concat_string}, '${s}'") + endif() +endforeach() + +set(unittest_to_run "runtests('${unittest_file_to_run_name}'), exit(max([ans(1,:).Failed]))") +if(no_unittest_framework) + set(unittest_to_run "try, ${unittest_file_to_run_name}, catch err, disp('An exception has been thrown during the execution'), disp(err), disp(err.stack), exit(1), end, exit(0)") +endif() + +set(Matlab_SCRIPT_TO_RUN + "addpath(${concat_string}), path, ${cmd_to_run_before_test}, ${unittest_to_run}" + ) + +set(Matlab_LOG_FILE "${output_directory}/${test_name}.log") + +set(devnull) +if(UNIX) + set(devnull INPUT_FILE /dev/null) +elseif(WIN32) + set(devnull INPUT_FILE NUL) +endif() + +execute_process( + COMMAND "${Matlab_PROGRAM}" ${Matlab_UNIT_TESTS_CMD} -logfile "${test_name}.log" -r "${Matlab_SCRIPT_TO_RUN}" + RESULT_VARIABLE res + TIMEOUT ${test_timeout} + OUTPUT_QUIET # we do not want the output twice + WORKING_DIRECTORY "${output_directory}" + ${devnull} + ) + +if(NOT EXISTS ${Matlab_LOG_FILE}) + message( FATAL_ERROR "[MATLAB] ERROR: cannot find the log file ${Matlab_LOG_FILE}") +endif() + +# print the output in any case. +file(READ ${Matlab_LOG_FILE} matlab_log_content) +message("Matlab test ${name_of_the_test} output:\n${matlab_log_content}") # if we put FATAL_ERROR here, the file is indented. + + +if(NOT (res EQUAL 0)) + message( FATAL_ERROR "[MATLAB] TEST FAILED" ) +endif() diff --git a/Modules/WriteCompilerDetectionHeader.cmake b/Modules/WriteCompilerDetectionHeader.cmake index d18f47c..f4dcb21 100644 --- a/Modules/WriteCompilerDetectionHeader.cmake +++ b/Modules/WriteCompilerDetectionHeader.cmake @@ -586,7 +586,7 @@ function(write_compiler_detection_header # if ${def_name} # define ${def_value} nullptr # else -# define ${def_value} static_cast<void*>(0) +# define ${def_value} 0 # endif \n") endif() |