diff options
52 files changed, 1061 insertions, 291 deletions
diff --git a/Help/manual/cmake-generator-expressions.7.rst b/Help/manual/cmake-generator-expressions.7.rst index 0e73bd2..8fd07d7 100644 --- a/Help/manual/cmake-generator-expressions.7.rst +++ b/Help/manual/cmake-generator-expressions.7.rst @@ -305,3 +305,42 @@ Available output expressions are: Content of ``...`` converted to shell path style. For example, slashes are converted to backslashes in Windows shells and drive letters are converted to posix paths in MSYS shells. The ``...`` must be an absolute path. +``$<GENEX_EVAL:...>`` + Content of ``...`` evaluated as a generator expression in the current + context. This enables consumption of generator expressions + whose evaluation results itself in generator expressions. +``$<TARGET_GENEX_EVAL:tgt,...>`` + Content of ``...`` evaluated as a generator expression in the context of + ``tgt`` target. This enables consumption of custom target properties that + themselves contain generator expressions. + + Having the capability to evaluate generator expressions is very useful when + you want to manage custom properties supporting generator expressions. + For example: + + .. code-block:: cmake + + add_library(foo ...) + + set_property(TARGET foo PROPERTY + CUSTOM_KEYS $<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS> + ) + + add_custom_target(printFooKeys + COMMAND ${CMAKE_COMMAND} -E echo $<TARGET_PROPERTY:foo,CUSTOM_KEYS> + ) + + This naive implementation of the ``printFooKeys`` custom command is wrong + because ``CUSTOM_KEYS`` target property is not evaluated and the content + is passed as is (i.e. ``$<$<CONFIG:DEBUG>:FOO_EXTRA_THINGS>``). + + To have the expected result (i.e. ``FOO_EXTRA_THINGS`` if config is + ``Debug``), it is required to evaluate the output of + ``$<TARGET_PROPERTY:foo,CUSTOM_KEYS>``: + + .. code-block:: cmake + + add_custom_target(printFooKeys + COMMAND ${CMAKE_COMMAND} -E + echo $<TARGET_GENEX_EVAL:foo,$<TARGET_PROPERTY:foo,CUSTOM_KEYS>> + ) diff --git a/Help/release/dev/genex-GENEX_EVAL.rst b/Help/release/dev/genex-GENEX_EVAL.rst new file mode 100644 index 0000000..0869c93 --- /dev/null +++ b/Help/release/dev/genex-GENEX_EVAL.rst @@ -0,0 +1,7 @@ +genex-GENEX_EVAL +---------------- + +* New ``$<GENEX_EVAL:...>`` and ``$<TARGET_GENEX_EVAL:target,...>`` + :manual:`generator expression <cmake-generator-expressions(7)>` + had been added to enable consumption of generator expressions whose + evaluation results itself in generator expressions. diff --git a/Help/release/dev/reorder-sys-includes.rst b/Help/release/dev/reorder-sys-includes.rst new file mode 100644 index 0000000..14d520f --- /dev/null +++ b/Help/release/dev/reorder-sys-includes.rst @@ -0,0 +1,7 @@ +reorder-sys-includes +-------------------- + +* Include directories marked as ``SYSTEM`` are now moved after non-system + directories. The ``-isystem`` flag does this automatically, so moving + them explicitly to the end makes the behavior consistent on compilers + that do not have any ``-isystem`` flag. diff --git a/Modules/CMakeDetermineCompilerId.cmake b/Modules/CMakeDetermineCompilerId.cmake index 15c304c..ea5465a 100644 --- a/Modules/CMakeDetermineCompilerId.cmake +++ b/Modules/CMakeDetermineCompilerId.cmake @@ -52,6 +52,22 @@ function(CMAKE_DETERMINE_COMPILER_ID lang flagvar src) endforeach() endif() + # CUDA < 7.5 is missing version macros + if(lang STREQUAL "CUDA" + AND CMAKE_${lang}_COMPILER_ID STREQUAL "NVIDIA" + AND NOT CMAKE_${lang}_COMPILER_VERSION) + execute_process( + COMMAND "${CMAKE_${lang}_COMPILER}" + --version + OUTPUT_VARIABLE output ERROR_VARIABLE output + RESULT_VARIABLE result + TIMEOUT 10 + ) + if(output MATCHES [=[ V([0-9]+)\.([0-9]+)\.([0-9]+)]=]) + set(CMAKE_${lang}_COMPILER_VERSION "${CMAKE_MATCH_1}.${CMAKE_MATCH_2}.${CMAKE_MATCH_3}") + endif() + endif() + if (COMPILER_QNXNTO AND CMAKE_${lang}_COMPILER_ID STREQUAL "GNU") execute_process( COMMAND "${CMAKE_${lang}_COMPILER}" diff --git a/Modules/CPack.cmake b/Modules/CPack.cmake index 9216fc9..3ff8be6 100644 --- a/Modules/CPack.cmake +++ b/Modules/CPack.cmake @@ -100,11 +100,19 @@ # # Short description of the project (only a few words). Default value is:: # -# ${PROJECT_DESCRIPTION} +# ${CMAKE_PROJECT_DESCRIPTION} # # if DESCRIPTION has given to the project() call or # CMake generated string with PROJECT_NAME otherwise. # +# .. variable:: CPACK_PACKAGE_HOMEPAGE_URL +# +# Project homepage URL. Default value is:: +# +# ${CMAKE_PROJECT_HOMEPAGE_URL} +# +# if HOMEPAGE_URL has given to the project(). +# # .. variable:: CPACK_PACKAGE_FILE_NAME # # The name of the package file to generate, not including the @@ -373,6 +381,10 @@ else() _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${CMAKE_PROJECT_NAME} built using CMake") endif() +if(CMAKE_PROJECT_HOMEPAGE_URL) + _cpack_set_default(CPACK_PACKAGE_HOMEPAGE_URL + "${CMAKE_PROJECT_HOMEPAGE_URL}") +endif() _cpack_set_default(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_ROOT}/Templates/CPack.GenericDescription.txt") diff --git a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake index cb0beaf..bf9111a 100644 --- a/Modules/Compiler/NVIDIA-DetermineCompiler.cmake +++ b/Modules/Compiler/NVIDIA-DetermineCompiler.cmake @@ -2,9 +2,11 @@ set(_compiler_id_pp_test "defined(__NVCC__)") set(_compiler_id_version_compute " -# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__CUDACC_VER_MAJOR__) -# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__CUDACC_VER_MINOR__) -# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__) +# if defined(__CUDACC_VER_MAJOR__) +# define @PREFIX@COMPILER_VERSION_MAJOR @MACRO_DEC@(__CUDACC_VER_MAJOR__) +# define @PREFIX@COMPILER_VERSION_MINOR @MACRO_DEC@(__CUDACC_VER_MINOR__) +# define @PREFIX@COMPILER_VERSION_PATCH @MACRO_DEC@(__CUDACC_VER_BUILD__) +# endif # if defined(_MSC_VER) /* _MSC_VER = VVRR */ # define @PREFIX@SIMULATE_VERSION_MAJOR @MACRO_DEC@(_MSC_VER / 100) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 33b755a..b03f793 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -5,22 +5,25 @@ # FindMatlab # ---------- # -# Finds Matlab installations and provides Matlab tools and libraries to cmake. +# Finds Matlab or Matlab Compiler Runtime (MCR) and provides Matlab tools, +# libraries and compilers to CMake. # -# 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: +# This package primary purpose is to find the libraries associated with Matlab +# or the MCR 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 +# * to run specific commands in Matlab in case Matlab is available +# * for declaring Matlab unit test +# * to retrieve various information from Matlab (mex extensions, versions and # release queries, ...) # # The module supports the following components: # -# * ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the MX, -# ENG and MAT libraries of Matlab -# * ``MAIN_PROGRAM`` the Matlab binary program. +# * ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``MX``, +# ``ENG`` and ``MAT`` libraries of Matlab +# * ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not +# available on the MCR version, and will yield an error if the MCR is found +# instead of the regular Matlab installation. # * ``MEX_COMPILER`` the MEX compiler. # * ``SIMULINK`` the Simulink environment. # @@ -30,24 +33,26 @@ # **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. +# :command:`matlab_get_release_name_from_version` provide a mapping +# between the release name and 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: The installed versions of Matlab/MCR 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. +# * OS X: The installed versions of Matlab/MCR are given by the MATLAB +# default installation 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``. This does +# not work for MCR installation and :variable:`Matlab_ROOT_DIR` should be +# specified on this platform. # # 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. +# When a Matlab/MCR installation is found automatically and the ``MATLAB_VERSION`` +# is not given, the version is queried from Matlab directly (on Windows this +# may pop up a Matlab window) or from the MCR installation. # # The mapping of the release names and the version of Matlab is performed by # defining pairs (name, version). The variable @@ -135,15 +140,15 @@ # 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 +# returns all the possible Matlab or MCR 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 dependent) # :command:`matlab_get_version_from_matlab_run` -# returns the version of Matlab, given the full directory of the Matlab -# program. +# returns the version of Matlab/MCR, given the full directory of the Matlab/MCR +# installation path. # # # Known issues @@ -256,7 +261,7 @@ endif() # .. 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) +macro(matlab_get_version_from_release_name release_name version_name) string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) @@ -264,7 +269,7 @@ macro (matlab_get_version_from_release_name release_name version_name) if(NOT _matched STREQUAL "") set(${version_name} ${CMAKE_MATCH_1}) else() - message(WARNING "The release name ${release_name} is not registered") + message(WARNING "[MATLAB] The release name ${release_name} is not registered") endif() unset(_matched) @@ -278,7 +283,7 @@ endmacro() # .. 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) +macro(matlab_get_release_name_from_version version release_name) set(${release_name} "") foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) @@ -292,7 +297,7 @@ macro (matlab_get_release_name_from_version version release_name) unset(_var) unset(_matched) if(${release_name} STREQUAL "") - message(WARNING "The version ${version} is not registered") + message(WARNING "[MATLAB] The version ${version} is not registered") endif() endmacro() @@ -341,8 +346,9 @@ endmacro() # 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). +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB`` and +# ``HKLM\\SOFTWARE\\Mathworks\\MATLAB Runtime`` or an empty list in case an +# error occurred (or nothing found). # # .. note:: # @@ -352,51 +358,54 @@ endmacro() 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") + message(FATAL_ERROR "[MATLAB] 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) + foreach(_installation_type IN ITEMS "MATLAB" "MATLAB Runtime") - set(matlabs_from_registry) - if(${resultMatlab} EQUAL 0) + # /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\\${_installation_type} /f * /k ${APPEND_REG} + RESULT_VARIABLE resultMatlab + OUTPUT_VARIABLE varMatlab + ERROR_VARIABLE errMatlab + INPUT_FILE NUL + ) - 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}) + if(${resultMatlab} EQUAL 0) - 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() + 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) + list(APPEND matlabs_from_registry ${_matlab_current_version}) + unset(_matlab_current_version) + endforeach() - endif() + endif() + endforeach() if(matlabs_from_registry) list(REMOVE_DUPLICATES matlabs_from_registry) @@ -441,7 +450,6 @@ macro(extract_matlab_versions_from_registry_brute_force matlab_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) @@ -449,10 +457,7 @@ macro(extract_matlab_versions_from_registry_brute_force matlab_versions) list(REVERSE matlab_supported_versions) endif() - set(${matlab_versions} ${matlab_supported_versions}) - - endmacro() @@ -461,9 +466,11 @@ 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)``. +# Populates the Matlab root with valid versions of Matlab or +# Matlab Runtime (MCR). +# The returned matlab_roots is organized in triplets +# ``(type,version_number,matlab_root_path)``, where ``type`` +# indicates either ``MATLAB`` or ``MCR``. # # :: # @@ -472,17 +479,17 @@ endmacro() # matlab_roots) # # ``matlab_versions`` -# the versions of each of the Matlab installations +# the versions of each of the Matlab or MCR installations # ``matlab_roots`` -# the location of each of the Matlab installations +# the location of each of the Matlab or MCR 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 ) + # check for Matlab installations foreach(_matlab_current_version ${matlab_versions}) get_filename_component( current_MATLAB_ROOT @@ -490,13 +497,27 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_ ABSOLUTE) if(EXISTS ${current_MATLAB_ROOT}) - list(APPEND _matlab_roots_list ${_matlab_current_version} ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list "MATLAB" ${_matlab_current_version} ${current_MATLAB_ROOT}) + endif() + + endforeach() + + # Check for MCR installations + foreach(_matlab_current_version ${matlab_versions}) + get_filename_component( + current_MATLAB_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB Runtime\\${_matlab_current_version};MATLABROOT]" + ABSOLUTE) + + # remove the dot + string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") + + if(EXISTS ${current_MATLAB_ROOT}) + list(APPEND _matlab_roots_list "MCR" ${_matlab_current_version} "${current_MATLAB_ROOT}/v${_matlab_current_version_without_dot}") endif() - endforeach(_matlab_current_version) - unset(_matlab_current_version) + endforeach() set(${matlab_roots} ${_matlab_roots_list} PARENT_SCOPE) - unset(_matlab_roots_list) endfunction() #.rst: @@ -513,7 +534,7 @@ endfunction() # mex_suffix) # # ``matlab_root`` -# the root of the Matlab installation +# the root of the Matlab/MCR installation # ``mex_suffix`` # the variable name in which the suffix will be returned. function(matlab_get_mex_suffix matlab_root mex_suffix) @@ -548,7 +569,9 @@ function(matlab_get_mex_suffix matlab_root mex_suffix) ) endif() endforeach(current_mexext_suffix) - + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Determining mex files extensions from '${matlab_root}/bin' with program '${Matlab_MEXEXTENSIONS_PROG}'") + endif() # the program has been found? if((NOT Matlab_MEXEXTENSIONS_PROG) OR (NOT EXISTS ${Matlab_MEXEXTENSIONS_PROG})) @@ -568,12 +591,29 @@ function(matlab_get_mex_suffix matlab_root mex_suffix) set(devnull INPUT_FILE NUL) endif() + # this is the prefered way. If this does not work properly (eg. MCR on Windows), then we use our own knowledge execute_process( COMMAND ${Matlab_MEXEXTENSIONS_PROG} OUTPUT_VARIABLE _matlab_mex_extension + #RESULT_VARIABLE _matlab_mex_extension_call ERROR_VARIABLE _matlab_mex_extension_error ${devnull}) - string(STRIP ${_matlab_mex_extension} _matlab_mex_extension) + + if(NOT "${_matlab_mex_extension_error}" STREQUAL "") + if(WIN32) + # this is only for intel architecture + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_matlab_mex_extension "mexw64") + else() + set(_matlab_mex_extension "mexw32") + endif() + endif() + endif() + + string(STRIP "${_matlab_mex_extension}" _matlab_mex_extension) + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] '${Matlab_MEXEXTENSIONS_PROG}' : returned '${_matlab_mex_extension_call}', determined extension '${_matlab_mex_extension}' and error string is '${_matlab_mex_extension_error}'") + endif() unset(Matlab_MEXEXTENSIONS_PROG CACHE) set(${mex_suffix} ${_matlab_mex_extension} PARENT_SCOPE) @@ -586,7 +626,8 @@ endfunction() # .. command:: matlab_get_version_from_matlab_run # # This function runs Matlab program specified on arguments and extracts its -# version. +# version. If the path provided for the Matlab installation points to an MCR +# installation, the version is extracted from the installed files. # # :: # @@ -602,7 +643,6 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve set(${matlab_list_versions} "" PARENT_SCOPE) - if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] Determining the version of Matlab from ${matlab_binary_program}") endif() @@ -704,7 +744,9 @@ endfunction() # .. command:: matlab_add_unit_test # # Adds a Matlab unit test to the test set of cmake/ctest. -# This command requires the component ``MAIN_PROGRAM``. +# This command requires the component ``MAIN_PROGRAM`` and hence is not +# available for an MCR installation. +# # The unit test uses the Matlab unittest framework (default, available # starting Matlab 2013b+) except if the option ``NO_UNITTEST_FRAMEWORK`` # is given. @@ -929,7 +971,7 @@ function(matlab_add_mex) 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" + COMMENT "[MATLAB] Copy ${${prefix}_NAME} documentation file into the output folder" ) endif() # documentation @@ -1005,10 +1047,10 @@ 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) +# This can possibly run Matlab for extracting the version. +function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_version matlab_final_version) - # if the version is not trivial, we query matlab for that + # if the version is not trivial, we query matlab (if not MCR) 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") @@ -1021,189 +1063,231 @@ function(_Matlab_get_version_from_root matlab_root matlab_known_version matlab_f 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) + if("${matlab_or_mcr}" STREQUAL "UNKNOWN") + if(MATLAB_FIND_DEBUG) + message(WARNING "[MATLAB] Determining Matlab or MCR") endif() - find_program( - _matlab_current_program - matlab - ${_find_matlab_options} - DOC "Matlab main program" - ) - endif() + if(EXISTS "${matlab_root}/appdata/version.xml") + # we inspect the application version.xml file that contains the product information + file(STRINGS "${matlab_root}/appdata/version.xml" productinfo_string NEWLINE_CONSUME) + string(REGEX MATCH "<installedProductData.*displayedString=\"([a-zA-Z ]+)\".*/>" + product_reg_match + ${productinfo_string} + ) + + # default fallback to Matlab + set(matlab_or_mcr "MATLAB") + if(NOT "${CMAKE_MATCH_1}" STREQUAL "") + string(TOLOWER "${CMAKE_MATCH_1}" product_reg_match) + + if("${product_reg_match}" STREQUAL "matlab runtime") + set(matlab_or_mcr "MCR") + endif() + endif() + 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}") + message(WARNING "[MATLAB] '${matlab_root}' contains the '${matlab_or_mcr}'") 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) + # UNKNOWN is the default behaviour in case we + # - have an erroneous matlab_root + # - have an initial 'UNKNOWN' + if("${matlab_or_mcr}" STREQUAL "MATLAB" OR "${matlab_or_mcr}" STREQUAL "UNKNOWN") + # MATLAB versions + set(_matlab_current_program ${Matlab_MAIN_PROGRAM}) - # 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() + # do we already have a matlab program? + if(NOT _matlab_current_program) - # 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(_find_matlab_options) + if(matlab_root AND EXISTS ${matlab_root}) + set(_find_matlab_options PATHS ${matlab_root} ${matlab_root}/bin NO_DEFAULT_PATH) + endif() - set(matlab_list_of_all_versions) - matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + find_program( + _matlab_current_program + matlab + ${_find_matlab_options} + DOC "Matlab main program" + ) + endif() - list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) - if(${list_of_all_versions_length} GREATER 0) - list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) - else() - set(_matlab_version_tmp "unknown") - 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() - # set the version into the cache - set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + # 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) - # warning, just in case several versions found (should not happen) - 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() + # 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() - # return the updated value - set(${matlab_final_version} ${Matlab_VERSION_STRING_INTERNAL} PARENT_SCOPE) + # 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) -endfunction() + set(matlab_list_of_all_versions) + matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) + list(LENGTH matlab_list_of_all_versions list_of_all_versions_length) + if(${list_of_all_versions_length} GREATER 0) + list(GET matlab_list_of_all_versions 0 _matlab_version_tmp) + else() + set(_matlab_version_tmp "unknown") + endif() + # 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) + 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) + else() + # MCR + # we cannot run anything in order to extract the version. We assume that the file + # VersionInfo.xml exists under the MatlabRoot, we look for it and extract the version from there + set(_matlab_version_tmp "unknown") + file(STRINGS "${matlab_root}/VersionInfo.xml" versioninfo_string NEWLINE_CONSUME) + # parses "<version>9.2.0.538062</version>" + string(REGEX MATCH "<version>(.*)</version>" + version_reg_match + ${versioninfo_string} + ) + + if(NOT "${version_reg_match}" STREQUAL "") + if("${CMAKE_MATCH_1}" MATCHES "(([0-9])\\.([0-9]))[\\.0-9]*") + set(_matlab_version_tmp "${CMAKE_MATCH_1}") + endif() + endif() + set(${matlab_final_version} "${_matlab_version_tmp}" PARENT_SCOPE) + set(Matlab_VERSION_STRING_INTERNAL + "${_matlab_version_tmp}" + CACHE INTERNAL "Matlab (MCR) version (automatically determined)" + FORCE) + endif() # Matlab or MCR +endfunction() -# ################################### -# Exploring the possible Matlab_ROOTS -# this variable will get all Matlab installations found in the current system. -set(_matlab_possible_roots) +# Utility function for finding Matlab or MCR on Win32 +function(_Matlab_find_instances_win32 matlab_roots) + # 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) + if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(_matlab_win64 ON) + else() + set(_matlab_win64 OFF) + endif() -if(Matlab_ROOT_DIR) - # if the user specifies a possible root, we keep this one + matlab_extract_all_installed_versions_from_registry(_matlab_win64 _matlab_versions_from_registry) - if(NOT EXISTS ${Matlab_ROOT_DIR}) - # if Matlab_ROOT_DIR specified but erroneous + # the returned list is empty, doing the search on all known versions + if(NOT _matlab_versions_from_registry) if(MATLAB_FIND_DEBUG) - message(WARNING "[MATLAB] the specified path for Matlab_ROOT_DIR does not exist (${Matlab_ROOT_DIR})") - endif() - else() - # NOTFOUND indicates the code below to search for the version automatically - if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "") - 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 + 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) -else() - - # if the user does not specify the possible installation root, we look for - # one installation using the appropriate heuristics + set(_matlab_versions_from_registry) + matlab_extract_all_installed_versions_from_registry(CMAKE_CL_64 _matlab_versions_from_registry) - if(WIN32) + # 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() - # On WIN32, we look for Matlab installation in the registry - # if unsuccessful, we look for all known revision and filter the existing - # ones. + # filtering the results with the registry keys + matlab_get_all_valid_matlab_roots_from_registry("${_matlab_versions_from_registry}" _matlab_possible_roots) + set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) - # testing if we are able to extract the needed information from the registry - set(_matlab_versions_from_registry) +endfunction() - if(CMAKE_SIZEOF_VOID_P EQUAL 8) - set(_matlab_win64 ON) - else() - set(_matlab_win64 OFF) - endif() +# Utility function for finding Matlab or MCR on OSX +function(_Matlab_find_instances_osx matlab_roots) - matlab_extract_all_installed_versions_from_registry(_matlab_win64 _matlab_versions_from_registry) + set(_matlab_possible_roots) + # 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() - # the returned list is empty, doing the search on all known versions - if(NOT _matlab_versions_from_registry) + foreach(_matlab_current_release IN LISTS _matlab_releases) + matlab_get_version_from_release_name("${_matlab_current_release}" _matlab_current_version) + string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") + set(_matlab_base_path "/Applications/MATLAB_${_matlab_current_release}.app") + # Check Matlab, has precedence over MCR + if(EXISTS ${_matlab_base_path}) if(MATLAB_FIND_DEBUG) - message(STATUS "[MATLAB] Search for Matlab from the registry unsuccessful, testing all supported versions") + message(STATUS "[MATLAB] Found version ${_matlab_current_release} (${_matlab_current_version}) in ${_matlab_base_path}") endif() - - extract_matlab_versions_from_registry_brute_force(_matlab_versions_from_registry) + list(APPEND _matlab_possible_roots "MATLAB" ${_matlab_current_version} ${_matlab_base_path}) 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) + # Checks MCR + set(_mcr_path "/Applications/MATLAB/MATLAB_Runtime/v${_matlab_current_version_without_dot}") + if(EXISTS "${_mcr_path}") + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] Found MCR version ${_matlab_current_release} (${_matlab_current_version}) in ${_mcr_path}") endif() + list(APPEND _matlab_possible_roots "MCR" ${_matlab_current_version} ${_mcr_path}) + endif() - unset(_matlab_full_string) - endforeach(_matlab_current_release) - - unset(_matlab_current_release) - unset(_matlab_releases) - - endif() - -endif() - + endforeach() + set(${matlab_roots} ${_matlab_possible_roots} PARENT_SCOPE) +endfunction() -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 +# Utility function for finding Matlab or MCR from the PATH +function(_Matlab_find_instances_from_path matlab_roots) + set(_matlab_possible_roots) # At this point, we have no other choice than trying to find it from PATH. - # If set by the user, this won't change + # 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) @@ -1218,17 +1302,88 @@ if(_numbers_of_matlab_roots EQUAL 0) 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}) + # We found the Matlab program + list(APPEND _matlab_possible_roots "MATLAB" "NOTFOUND" ${_matlab_current_location}) + + # we remove this from the CACHE + unset(_matlab_main_tmp CACHE) + else() + find_program( + _matlab_mex_tmp + NAMES mex) + if(_matlab_mex_tmp) + # we then populate the list of roots, with empty version + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] mex compiler found from PATH: ${_matlab_mex_tmp}") + endif() + + # resolve symlinks + get_filename_component(_mex_current_location "${_matlab_mex_tmp}" REALPATH) + + # get the directory (the command below has to be run twice) + # this will be the matlab root + get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) + get_filename_component(_mex_current_location "${_mex_current_location}" DIRECTORY) # Matlab Runtime mex compiler should be in bin + + # We found the Matlab program + list(APPEND _matlab_possible_roots "MCR" "NOTFOUND" ${_mex_current_location}) + + unset(_matlab_mex_tmp CACHE) + else() + if(MATLAB_FIND_DEBUG) + message(STATUS "[MATLAB] mex compiler not found") + endif() + endif() - unset(_matlab_current_location) endif() - unset(_matlab_main_tmp CACHE) -endif() + set(${matlab_roots} ${_matlab_possible_roots} 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() + # NOTFOUND indicates the code below to search for the version automatically + if("${Matlab_VERSION_STRING_INTERNAL}" STREQUAL "") + list(APPEND _matlab_possible_roots "UNKNOWN" "NOTFOUND" ${Matlab_ROOT_DIR}) # empty version, empty MCR/Matlab indication + else() + list(APPEND _matlab_possible_roots "UNKNOWN" ${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. + # There is apparently no standard way on Linux. + if(WIN32) + _Matlab_find_instances_win32(_matlab_possible_roots_win32) + list(APPEND _matlab_possible_roots ${_matlab_possible_roots_win32}) + elseif(APPLE) + _Matlab_find_instances_osx(_matlab_possible_roots_osx) + list(APPEND _matlab_possible_roots ${_matlab_possible_roots_osx}) + endif() +endif() + + +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 + _Matlab_find_instances_from_path(_matlab_possible_roots) +endif() if(MATLAB_FIND_DEBUG) @@ -1242,12 +1397,14 @@ endif() # take the first possible Matlab root list(LENGTH _matlab_possible_roots _numbers_of_matlab_roots) set(Matlab_VERSION_STRING "NOTFOUND") +set(Matlab_Or_MCR "UNKNOWN") 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) + list(GET _matlab_possible_roots 0 Matlab_Or_MCR) + list(GET _matlab_possible_roots 1 Matlab_VERSION_STRING) + list(GET _matlab_possible_roots 2 Matlab_ROOT_DIR) # adding a warning in case of ambiguity - if(_numbers_of_matlab_roots GREATER 2 AND MATLAB_FIND_DEBUG) + if(_numbers_of_matlab_roots GREATER 3 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() @@ -1290,13 +1447,11 @@ set(Matlab_ROOT_DIR ${Matlab_ROOT_DIR} CACHE PATH "Matlab installation root path # Fix the version, in case this one is NOTFOUND _Matlab_get_version_from_root( "${Matlab_ROOT_DIR}" + "${Matlab_Or_MCR}" ${Matlab_VERSION_STRING} Matlab_VERSION_STRING ) - - - if(MATLAB_FIND_DEBUG) message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}") endif() diff --git a/Modules/FindPython/Support.cmake b/Modules/FindPython/Support.cmake index 67bda7a..9903a6d 100644 --- a/Modules/FindPython/Support.cmake +++ b/Modules/FindPython/Support.cmake @@ -54,6 +54,45 @@ function (_PYTHON_GET_FRAMEWORKS _PYTHON_PGF_FRAMEWORK_PATHS _PYTHON_VERSION) endfunction() +function (_PYTHON_VALIDATE_INTERPRETER) + if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + return() + endif() + + if (${_PYTHON_PREFIX}_EXECUTABLE MATCHES "python${CMAKE_EXECUTABLE_SUFFIX}$") + # executable found do not have version in name + # ensure major version is OK + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys; sys.stdout.write(str(sys.version_info[0]))" + RESULT_VARIABLE result + OUTPUT_VARIABLE version + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT version EQUAL _${_PYTHON_PREFIX}_REQUIRED_VERSION_MAJOR) + # interpreter not usable or has wrong major version + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() + + if (CMAKE_SIZEOF_VOID_P AND "Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS + AND NOT CMAKE_CROSSCOMPILING) + # In this case, interpreter must have same architecture as environment + execute_process (COMMAND "${${_PYTHON_PREFIX}_EXECUTABLE}" -c + "import sys, struct; sys.stdout.write(str(struct.calcsize(\"P\")))" + RESULT_VARIABLE result + OUTPUT_VARIABLE size + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + if (result OR NOT size EQUAL CMAKE_SIZEOF_VOID_P) + # interpreter not usable or has wrong architecture + set (${_PYTHON_PREFIX}_EXECUTABLE ${_PYTHON_PREFIX}_EXECUTABLE-NOTFOUND CACHE INTERNAL "" FORCE) + return() + endif() + endif() +endfunction() + + function (_PYTHON_FIND_RUNTIME_LIBRARY _PYTHON_LIB) string (REPLACE "_RUNTIME" "" _PYTHON_LIB "${_PYTHON_LIB}") # look at runtime part on systems supporting it @@ -211,17 +250,22 @@ if ("Interpreter" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS) find_program (${_PYTHON_PREFIX}_EXECUTABLE NAMES python${_${_PYTHON_PREFIX}_VERSION}) + _python_validate_interpreter () if (${_PYTHON_PREFIX}_EXECUTABLE) break() endif() endforeach() # try more generic names - find_program (${_PYTHON_PREFIX}_EXECUTABLE - NAMES python${${_PYTHON_PREFIX}_VERSION_MAJOR} python - ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} - HINTS ${_${_PYTHON_PREFIX}_HINTS} - PATH_SUFFIXES bin) + if (NOT ${_PYTHON_PREFIX}_EXECUTABLE) + find_program (${_PYTHON_PREFIX}_EXECUTABLE + NAMES python${${_PYTHON_PREFIX}_VERSION_MAJOR} python + ${_${_PYTHON_PREFIX}_IRON_PYTHON_NAMES} + HINTS ${_${_PYTHON_PREFIX}_HINTS} + PATH_SUFFIXES bin) + + _python_validate_interpreter () + endif() # retrieve exact version of executable found if (${_PYTHON_PREFIX}_EXECUTABLE) @@ -531,6 +575,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS _python_get_frameworks (_${_PYTHON_PREFIX}_FRAMEWORK_PATHS ${_${_PYTHON_PREFIX}_VERSION}) + # search first in known locations find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} python${_${_PYTHON_PREFIX}_VERSION}mu @@ -549,6 +594,22 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} + lib/python${_${_PYTHON_PREFIX}_VERSION}/config + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # search in all default paths + find_library (${_PYTHON_PREFIX}_LIBRARY_RELEASE + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS} + python${_${_PYTHON_PREFIX}_VERSION}mu + python${_${_PYTHON_PREFIX}_VERSION}m + python${_${_PYTHON_PREFIX}_VERSION}u + python${_${_PYTHON_PREFIX}_VERSION} + NAMES_PER_DIR + PATH_SUFFIXES lib/${CMAKE_LIBRARY_ARCHITECTURE} lib libs + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}mu + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}m + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION}u + lib/python${_${_PYTHON_PREFIX}_VERSION}/config-${_${_PYTHON_PREFIX}_VERSION} lib/python${_${_PYTHON_PREFIX}_VERSION}/config) # retrieve runtime library if (${_PYTHON_PREFIX}_LIBRARY_RELEASE) @@ -580,6 +641,7 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS HINTS "${_${_PYTHON_PREFIX}_PATH}" ${_${_PYTHON_PREFIX}_HINTS} NO_DEFAULT_PATH) else() + # search first in known locations find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d NAMES_PER_DIR @@ -588,6 +650,13 @@ if ("Development" IN_LIST ${_PYTHON_PREFIX}_FIND_COMPONENTS [HKEY_CURRENT_USER\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\${_${_PYTHON_PREFIX}_VERSION}\\InstallPath] [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\ContinuumAnalytics\\Anaconda${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}-${_${_PYTHON_PREFIX}_ARCH}\\InstallPath] + PATH_SUFFIXES lib libs + NO_SYSTEM_ENVIRONMENT_PATH + NO_CMAKE_SYSTEM_PATH) + # search in all default paths + find_library (${_PYTHON_PREFIX}_LIBRARY_DEBUG + NAMES python${_${_PYTHON_PREFIX}_VERSION_NO_DOTS}_d + NAMES_PER_DIR PATH_SUFFIXES lib libs) endif() if (${_PYTHON_PREFIX}_LIBRARY_DEBUG) diff --git a/Source/cmGeneratorExpressionDAGChecker.cxx b/Source/cmGeneratorExpressionDAGChecker.cxx index f0eafb4..face282 100644 --- a/Source/cmGeneratorExpressionDAGChecker.cxx +++ b/Source/cmGeneratorExpressionDAGChecker.cxx @@ -154,6 +154,18 @@ bool cmGeneratorExpressionDAGChecker::GetTransitivePropertiesOnly() return top->TransitivePropertiesOnly; } +bool cmGeneratorExpressionDAGChecker::EvaluatingGenexExpression() +{ + const cmGeneratorExpressionDAGChecker* top = this; + const cmGeneratorExpressionDAGChecker* parent = this->Parent; + while (parent) { + top = parent; + parent = parent->Parent; + } + + return top->Property == "TARGET_GENEX_EVAL" || top->Property == "GENEX_EVAL"; +} + bool cmGeneratorExpressionDAGChecker::EvaluatingLinkLibraries(const char* tgt) { const cmGeneratorExpressionDAGChecker* top = this; diff --git a/Source/cmGeneratorExpressionDAGChecker.h b/Source/cmGeneratorExpressionDAGChecker.h index 3f73fca..a3a8f69 100644 --- a/Source/cmGeneratorExpressionDAGChecker.h +++ b/Source/cmGeneratorExpressionDAGChecker.h @@ -61,6 +61,7 @@ struct cmGeneratorExpressionDAGChecker void ReportError(cmGeneratorExpressionContext* context, const std::string& expr); + bool EvaluatingGenexExpression(); bool EvaluatingLinkLibraries(const char* tgt = nullptr); #define DECLARE_TRANSITIVE_PROPERTY_METHOD(METHOD) bool METHOD() const; diff --git a/Source/cmGeneratorExpressionNode.cxx b/Source/cmGeneratorExpressionNode.cxx index 89ed4f0..399e894 100644 --- a/Source/cmGeneratorExpressionNode.cxx +++ b/Source/cmGeneratorExpressionNode.cxx @@ -365,6 +365,113 @@ static const struct TargetNameIfExistsNode : public cmGeneratorExpressionNode } } targetNameIfExistsNode; +struct GenexEvaluator : public cmGeneratorExpressionNode +{ + GenexEvaluator() {} + +protected: + std::string EvaluateExpression( + const std::string& genexOperator, const std::string& expression, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* dagCheckerParent) const + { + if (context->HeadTarget) { + cmGeneratorExpressionDAGChecker dagChecker( + context->Backtrace, context->HeadTarget->GetName(), genexOperator, + content, dagCheckerParent); + switch (dagChecker.Check()) { + case cmGeneratorExpressionDAGChecker::SELF_REFERENCE: + case cmGeneratorExpressionDAGChecker::CYCLIC_REFERENCE: { + dagChecker.ReportError(context, content->GetOriginalExpression()); + return std::string(); + } + case cmGeneratorExpressionDAGChecker::ALREADY_SEEN: + case cmGeneratorExpressionDAGChecker::DAG: + break; + } + + return this->EvaluateDependentExpression( + expression, context->LG, context, context->HeadTarget, + context->CurrentTarget, &dagChecker); + } + + return this->EvaluateDependentExpression( + expression, context->LG, context, context->HeadTarget, + context->CurrentTarget, dagCheckerParent); + } +}; + +static const struct TargetGenexEvalNode : public GenexEvaluator +{ + TargetGenexEvalNode() {} + + int NumExpectedParameters() const override { return 2; } + + bool AcceptsArbitraryContentParameter() const override { return true; } + + std::string Evaluate( + const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* dagCheckerParent) const override + { + const std::string& targetName = parameters.front(); + if (targetName.empty() || + !cmGeneratorExpression::IsValidTargetName(targetName)) { + reportError(context, content->GetOriginalExpression(), + "$<TARGET_GENEX_EVAL:tgt, ...> expression requires a " + "non-empty valid target name."); + return std::string(); + } + + const auto* target = context->LG->FindGeneratorTargetToUse(targetName); + if (!target) { + std::ostringstream e; + e << "$<TARGET_GENEX_EVAL:tgt, ...> target \"" << targetName + << "\" not found."; + reportError(context, content->GetOriginalExpression(), e.str()); + return std::string(); + } + + const std::string& expression = parameters[1]; + if (expression.empty()) { + return expression; + } + + cmGeneratorExpressionContext targetContext( + context->LG, context->Config, context->Quiet, target, target, + context->EvaluateForBuildsystem, context->Backtrace, context->Language); + + return this->EvaluateExpression("TARGET_GENEX_EVAL", expression, + &targetContext, content, dagCheckerParent); + } +} targetGenexEvalNode; + +static const struct GenexEvalNode : public GenexEvaluator +{ + GenexEvalNode() {} + + int NumExpectedParameters() const override { return 1; } + + bool AcceptsArbitraryContentParameter() const override { return true; } + + std::string Evaluate( + const std::vector<std::string>& parameters, + cmGeneratorExpressionContext* context, + const GeneratorExpressionContent* content, + cmGeneratorExpressionDAGChecker* dagCheckerParent) const override + { + const std::string& expression = parameters[0]; + if (expression.empty()) { + return expression; + } + + return this->EvaluateExpression("GENEX_EVAL", expression, context, content, + dagCheckerParent); + } +} genexEvalNode; + static const struct LowerCaseNode : public cmGeneratorExpressionNode { LowerCaseNode() {} @@ -1124,7 +1231,9 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode const char* prop = target->GetProperty(propertyName); if (dagCheckerParent) { - if (dagCheckerParent->EvaluatingLinkLibraries()) { + if (dagCheckerParent->EvaluatingGenexExpression()) { + // No check required. + } else if (dagCheckerParent->EvaluatingLinkLibraries()) { #define TRANSITIVE_PROPERTY_COMPARE(PROPERTY) \ (#PROPERTY == propertyName || "INTERFACE_" #PROPERTY == propertyName) || if (CM_FOR_EACH_TRANSITIVE_PROPERTY_NAME( @@ -1933,6 +2042,8 @@ const cmGeneratorExpressionNode* cmGeneratorExpressionNode::GetNode( nodeMap["TARGET_POLICY"] = &targetPolicyNode; nodeMap["TARGET_EXISTS"] = &targetExistsNode; nodeMap["TARGET_NAME_IF_EXISTS"] = &targetNameIfExistsNode; + nodeMap["TARGET_GENEX_EVAL"] = &targetGenexEvalNode; + nodeMap["GENEX_EVAL"] = &genexEvalNode; nodeMap["BUILD_INTERFACE"] = &buildInterfaceNode; nodeMap["INSTALL_INTERFACE"] = &installInterfaceNode; nodeMap["INSTALL_PREFIX"] = &installPrefixNode; diff --git a/Source/cmLocalGenerator.cxx b/Source/cmLocalGenerator.cxx index 629d54a..c5370e4 100644 --- a/Source/cmLocalGenerator.cxx +++ b/Source/cmLocalGenerator.cxx @@ -202,6 +202,22 @@ void cmLocalGenerator::ComputeObjectMaxPath() this->ObjectMaxPathViolations.clear(); } +void cmLocalGenerator::MoveSystemIncludesToEnd( + std::vector<std::string>& includeDirs, const std::string& config, + const std::string& lang, const cmGeneratorTarget* target) const +{ + if (!target) { + return; + } + + std::stable_sort( + includeDirs.begin(), includeDirs.end(), + [&target, &config, &lang](std::string const& a, std::string const& b) { + return !target->IsSystemIncludeDirectory(a, config, lang) && + target->IsSystemIncludeDirectory(b, config, lang); + }); +} + void cmLocalGenerator::TraceDependencies() { std::vector<std::string> configs; @@ -651,7 +667,7 @@ std::string cmLocalGenerator::ConvertToIncludeReference( } std::string cmLocalGenerator::GetIncludeFlags( - const std::vector<std::string>& includes, cmGeneratorTarget* target, + const std::vector<std::string>& includeDirs, cmGeneratorTarget* target, const std::string& lang, bool forceFullPaths, bool forResponseFile, const std::string& config) { @@ -659,6 +675,9 @@ std::string cmLocalGenerator::GetIncludeFlags( return ""; } + std::vector<std::string> includes = includeDirs; + this->MoveSystemIncludesToEnd(includes, config, lang, target); + OutputFormat shellFormat = forResponseFile ? RESPONSE : SHELL; std::ostringstream includeFlags; @@ -924,6 +943,8 @@ void cmLocalGenerator::GetIncludeDirectories(std::vector<std::string>& dirs, } } + this->MoveSystemIncludesToEnd(dirs, config, lang, target); + // Add standard include directories for this language. // We do not filter out implicit directories here. std::string const standardIncludesVar = diff --git a/Source/cmLocalGenerator.h b/Source/cmLocalGenerator.h index 533ac56..9ba62cc 100644 --- a/Source/cmLocalGenerator.h +++ b/Source/cmLocalGenerator.h @@ -411,6 +411,10 @@ private: int targetType); void ComputeObjectMaxPath(); + void MoveSystemIncludesToEnd(std::vector<std::string>& includeDirs, + const std::string& config, + const std::string& lang, + cmGeneratorTarget const* target) const; }; #if defined(CMAKE_BUILD_WITH_CMAKE) diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index ed090ec..b11cf03 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1442,10 +1442,24 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release add_subdirectory(FindThreads) # Matlab module - if(CMake_TEST_FindMatlab) + # CMake_TEST_FindMatlab: indicates to look for Matlab (from PATH for Linux) + # CMake_TEST_FindMatlab_MCR: indicates the MCR is installed + # CMake_TEST_FindMatlab_MCR_ROOT_DIR: indicates an optional root directory for the MCR, required on Linux + if(CMake_TEST_FindMatlab OR CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")) + set(FindMatlab_additional_test_options ) + if(CMake_TEST_FindMatlab_MCR OR NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "") + set(FindMatlab_additional_test_options -DIS_MCR=TRUE) + endif() + if(NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "") + set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMCR_ROOT:FILEPATH=${CMake_TEST_FindMatlab_MCR_ROOT_DIR}") + endif() + set(FindMatlab.basic_checks_BUILD_OPTIONS ${FindMatlab_additional_test_options}) ADD_TEST_MACRO(FindMatlab.basic_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>) + set(FindMatlab.versions_checks_BUILD_OPTIONS ${FindMatlab_additional_test_options}) ADD_TEST_MACRO(FindMatlab.versions_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>) + set(FindMatlab.components_checks_BUILD_OPTIONS ${FindMatlab_additional_test_options}) ADD_TEST_MACRO(FindMatlab.components_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>) + set(FindMatlab.failure_reports_BUILD_OPTIONS ${FindMatlab_additional_test_options}) ADD_TEST_MACRO(FindMatlab.failure_reports ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>) endif() diff --git a/Tests/FindMatlab/basic_checks/CMakeLists.txt b/Tests/FindMatlab/basic_checks/CMakeLists.txt index 951fcf2..4a74d93 100644 --- a/Tests/FindMatlab/basic_checks/CMakeLists.txt +++ b/Tests/FindMatlab/basic_checks/CMakeLists.txt @@ -8,8 +8,23 @@ set(MATLAB_FIND_DEBUG TRUE) # the success of the following command is dependent on the current configuration: # - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab # - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab -find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY MAIN_PROGRAM) +if(IS_MCR) + set(components MX_LIBRARY) + set(RUN_UNIT_TESTS FALSE) +else() + set(RUN_UNIT_TESTS TRUE) + set(components MX_LIBRARY MAIN_PROGRAM) +endif() + +if(NOT "${MCR_ROOT}" STREQUAL "") + set(Matlab_ROOT_DIR "${MCR_ROOT}") + if(NOT EXISTS "${MCR_ROOT}") + message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}") + endif() +endif() + +find_package(Matlab REQUIRED COMPONENTS ${components}) matlab_add_mex( @@ -21,38 +36,39 @@ matlab_add_mex( DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt ) +if(RUN_UNIT_TESTS) + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-1 + TIMEOUT 300 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests1.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + + # timeout tests, TIMEOUT set to very short on purpose + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-2 + TIMEOUT 15 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests_timeout.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE) + + + # testing the test without the unittest framework of Matlab + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-3 + TIMEOUT 300 + NO_UNITTEST_FRAMEWORK + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests2.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-1 - TIMEOUT 300 - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests1.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) - -# timeout tests, TIMEOUT set to very short on purpose -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-2 - TIMEOUT 15 - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests_timeout.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) -set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE) - - -# testing the test without the unittest framework of Matlab -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-3 - TIMEOUT 300 - NO_UNITTEST_FRAMEWORK - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests2.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) - -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-4 - TIMEOUT 300 - NO_UNITTEST_FRAMEWORK - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests3.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) -set_tests_properties(${PROJECT_NAME}_matlabtest-4 PROPERTIES WILL_FAIL TRUE) + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-4 + TIMEOUT 300 + NO_UNITTEST_FRAMEWORK + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests3.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + set_tests_properties(${PROJECT_NAME}_matlabtest-4 PROPERTIES WILL_FAIL TRUE) +endif() diff --git a/Tests/FindMatlab/components_checks/CMakeLists.txt b/Tests/FindMatlab/components_checks/CMakeLists.txt index 3dec093..da6a2b0 100644 --- a/Tests/FindMatlab/components_checks/CMakeLists.txt +++ b/Tests/FindMatlab/components_checks/CMakeLists.txt @@ -5,10 +5,18 @@ project(component_checks) set(MATLAB_FIND_DEBUG TRUE) +if(NOT "${MCR_ROOT}" STREQUAL "") + set(Matlab_ROOT_DIR "${MCR_ROOT}") + if(NOT EXISTS "${MCR_ROOT}") + message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}") + endif() +endif() + # the success of the following command is dependent on the current configuration: # - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab # - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab -find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY ENG_LIBRARY MAT_LIBRARY MAIN_PROGRAM) +find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY ENG_LIBRARY MAT_LIBRARY + OPTIONAL_COMPONENTS MAIN_PROGRAM) message(STATUS "FindMatlab libraries: ${Matlab_LIBRARIES}") diff --git a/Tests/FindMatlab/failure_reports/CMakeLists.txt b/Tests/FindMatlab/failure_reports/CMakeLists.txt index 1cf9613..e597a4a 100644 --- a/Tests/FindMatlab/failure_reports/CMakeLists.txt +++ b/Tests/FindMatlab/failure_reports/CMakeLists.txt @@ -7,7 +7,22 @@ project(failure_reports) set(MATLAB_FIND_DEBUG TRUE) -find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY MAIN_PROGRAM) +if(IS_MCR) + set(components MX_LIBRARY) + set(RUN_UNIT_TESTS FALSE) +else() + set(RUN_UNIT_TESTS TRUE) + set(components MX_LIBRARY MAIN_PROGRAM) +endif() + +if(NOT "${MCR_ROOT}" STREQUAL "") + set(Matlab_ROOT_DIR "${MCR_ROOT}") + if(NOT EXISTS "${MCR_ROOT}") + message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}") + endif() +endif() + +find_package(Matlab REQUIRED COMPONENTS ${components}) # main extensions for testing, same as other tests matlab_add_mex( @@ -19,21 +34,23 @@ matlab_add_mex( DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt ) -# the unit test file does not exist: the failure should be properly reported -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-1 - TIMEOUT 300 - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) -set_tests_properties(${PROJECT_NAME}_matlabtest-1 PROPERTIES WILL_FAIL TRUE) - -# without the unit test framework -matlab_add_unit_test( - NAME ${PROJECT_NAME}_matlabtest-2 - TIMEOUT 300 - NO_UNITTEST_FRAMEWORK - UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile2.m - ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> - ) -set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE) +if(RUN_UNIT_TESTS) + # the unit test file does not exist: the failure should be properly reported + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-1 + TIMEOUT 300 + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + set_tests_properties(${PROJECT_NAME}_matlabtest-1 PROPERTIES WILL_FAIL TRUE) + + # without the unit test framework + matlab_add_unit_test( + NAME ${PROJECT_NAME}_matlabtest-2 + TIMEOUT 300 + NO_UNITTEST_FRAMEWORK + UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../nonexistantfile2.m + ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper1> + ) + set_tests_properties(${PROJECT_NAME}_matlabtest-2 PROPERTIES WILL_FAIL TRUE) +endif() diff --git a/Tests/FindMatlab/versions_checks/CMakeLists.txt b/Tests/FindMatlab/versions_checks/CMakeLists.txt index 5d20685..d015730 100644 --- a/Tests/FindMatlab/versions_checks/CMakeLists.txt +++ b/Tests/FindMatlab/versions_checks/CMakeLists.txt @@ -7,6 +7,13 @@ set(MATLAB_FIND_DEBUG TRUE) set(MATLAB_ADDITIONAL_VERSIONS "dummy=14.9") +if(NOT "${MCR_ROOT}" STREQUAL "") + set(Matlab_ROOT_DIR "${MCR_ROOT}") + if(NOT EXISTS "${MCR_ROOT}") + message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}") + endif() +endif() + # the success of the following command is dependent on the current configuration # in this case, we are only interested in the version macros find_package(Matlab) diff --git a/Tests/IncludeDirectories/CMakeLists.txt b/Tests/IncludeDirectories/CMakeLists.txt index db18462..b7b8320 100644 --- a/Tests/IncludeDirectories/CMakeLists.txt +++ b/Tests/IncludeDirectories/CMakeLists.txt @@ -65,6 +65,10 @@ else() PROPERTIES COMPILE_FLAGS "-ITarProp") endif() +add_library(ordertest ordertest.cpp) +target_include_directories(ordertest SYSTEM PUBLIC SystemIncludeDirectories/systemlib) +target_include_directories(ordertest PUBLIC SystemIncludeDirectories/userlib) + add_subdirectory(StandardIncludeDirectories) add_subdirectory(TargetIncludeDirectories) diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/ordertest.h b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/ordertest.h new file mode 100644 index 0000000..28915e6 --- /dev/null +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/systemlib/ordertest.h @@ -0,0 +1 @@ +#error ordertest.h includes from systemlib diff --git a/Tests/IncludeDirectories/SystemIncludeDirectories/userlib/ordertest.h b/Tests/IncludeDirectories/SystemIncludeDirectories/userlib/ordertest.h new file mode 100644 index 0000000..fa882cb --- /dev/null +++ b/Tests/IncludeDirectories/SystemIncludeDirectories/userlib/ordertest.h @@ -0,0 +1 @@ +/* empty file */ diff --git a/Tests/IncludeDirectories/ordertest.cpp b/Tests/IncludeDirectories/ordertest.cpp new file mode 100644 index 0000000..7e24f77 --- /dev/null +++ b/Tests/IncludeDirectories/ordertest.cpp @@ -0,0 +1 @@ +#include "ordertest.h" diff --git a/Tests/RunCMake/CMakeLists.txt b/Tests/RunCMake/CMakeLists.txt index 44a8c45..f5dd528 100644 --- a/Tests/RunCMake/CMakeLists.txt +++ b/Tests/RunCMake/CMakeLists.txt @@ -362,8 +362,16 @@ set(IfacePaths_SOURCES_ARGS -DTEST_PROP=SOURCES) add_RunCMake_test(IfacePaths_SOURCES TEST_DIR IfacePaths) # Matlab module related tests -if(CMake_TEST_FindMatlab) - add_RunCMake_test(FindMatlab) +if(CMake_TEST_FindMatlab OR CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")) + set(FindMatlab_additional_test_options ) + if(CMake_TEST_FindMatlab_MCR OR NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "") + set(FindMatlab_additional_test_options -DIS_MCR=TRUE) + endif() + if(NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "") + set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMCR_ROOT:FILEPATH=${CMake_TEST_FindMatlab_MCR_ROOT_DIR}") + endif() + + add_RunCMake_test(FindMatlab ${FindMatlab_additional_test_options}) endif() add_executable(pseudo_emulator pseudo_emulator.c) diff --git a/Tests/RunCMake/FindMatlab/MatlabTest1.cmake b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake index 1cbc1c2..b4cc741 100644 --- a/Tests/RunCMake/FindMatlab/MatlabTest1.cmake +++ b/Tests/RunCMake/FindMatlab/MatlabTest1.cmake @@ -3,6 +3,9 @@ cmake_minimum_required (VERSION 2.8.12) enable_testing() project(test_should_fail) +if(NOT "${matlab_root}" STREQUAL "") + set(Matlab_ROOT_DIR ${matlab_root}) +endif() find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY) matlab_add_mex( diff --git a/Tests/RunCMake/FindMatlab/MatlabTest2.cmake b/Tests/RunCMake/FindMatlab/MatlabTest2.cmake index d5b0e6d..4295d3c 100644 --- a/Tests/RunCMake/FindMatlab/MatlabTest2.cmake +++ b/Tests/RunCMake/FindMatlab/MatlabTest2.cmake @@ -6,4 +6,8 @@ if(NOT DEFINED matlab_required) set(matlab_required REQUIRED) endif() +if(NOT DEFINED Matlab_ROOT_DIR AND NOT "${matlab_root}" STREQUAL "") + set(Matlab_ROOT_DIR ${matlab_root}) +endif() + find_package(Matlab ${matlab_required} COMPONENTS MX_LIBRARY) diff --git a/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake index f0eb6b4..deebf89 100644 --- a/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake +++ b/Tests/RunCMake/FindMatlab/RunCMakeTest.cmake @@ -1,5 +1,13 @@ include(RunCMake) + + +if(NOT "${MCR_ROOT}" STREQUAL "") + if(NOT EXISTS "${MCR_ROOT}") + message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}") + endif() + set(RunCMake_TEST_OPTIONS "-Dmatlab_root=${MCR_ROOT}") +endif() run_cmake(MatlabTest1) if(RunCMake_GENERATOR MATCHES "Make" AND UNIX) @@ -11,6 +19,9 @@ if(RunCMake_GENERATOR MATCHES "Make" AND UNIX) message(STATUS "RerunFindMatlab: first configuration to extract real Matlab_ROOT_DIR") set(RunCMake_TEST_OPTIONS "-Dmatlab_required=REQUIRED") + if(NOT "${MCR_ROOT}" STREQUAL "") + set(RunCMake_TEST_OPTIONS ${RunCMake_TEST_OPTIONS} "-Dmatlab_root=${MCR_ROOT}") + endif() run_cmake(MatlabTest2) message(STATUS "RerunFindMatlab: flushing the variables") diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-check.cmake b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-check.cmake new file mode 100644 index 0000000..df76740 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-check.cmake @@ -0,0 +1,6 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/GENEX_EVAL-generated.txt" content) + +set(expected "BEFORE_PROPERTY1_AFTER") +if(NOT content STREQUAL expected) + set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]") +endif() diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-stderr.txt b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-stderr.txt new file mode 100644 index 0000000..012dff6 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1-stderr.txt @@ -0,0 +1,26 @@ +^CMake Error at GENEX_EVAL-recursion1.cmake:7 \(add_custom_target\): + Error evaluating generator expression: + + \$<GENEX_EVAL:\$<TARGET_PROPERTY:CUSTOM_PROPERTY>> + + Dependency loop found. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at GENEX_EVAL-recursion1.cmake:7 \(add_custom_target\): + Loop step 1 + + \$<GENEX_EVAL:\$<TARGET_PROPERTY:CUSTOM_PROPERTY>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at GENEX_EVAL-recursion1.cmake:7 \(add_custom_target\): + Loop step 2 + + \$<TARGET_GENEX_EVAL:recursion,\$<TARGET_PROPERTY:recursion,CUSTOM_PROPERTY>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1.cmake b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1.cmake new file mode 100644 index 0000000..6596a81 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion1.cmake @@ -0,0 +1,9 @@ + +enable_language(C) + +add_library (recursion SHARED empty.c) +set_property (TARGET recursion PROPERTY CUSTOM_PROPERTY "$<GENEX_EVAL:$<TARGET_PROPERTY:CUSTOM_PROPERTY>>") + +add_custom_target (drive + COMMAND echo "$<TARGET_GENEX_EVAL:recursion,$<TARGET_PROPERTY:recursion,CUSTOM_PROPERTY>>" + DEPENDS recursion) diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-stderr.txt b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-stderr.txt new file mode 100644 index 0000000..fd954e6 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2-stderr.txt @@ -0,0 +1,26 @@ +^CMake Error at GENEX_EVAL-recursion2.cmake:8 \(add_custom_target\): + Error evaluating generator expression: + + \$<GENEX_EVAL:\$<TARGET_PROPERTY:CUSTOM_PROPERTY1>> + + Dependency loop found. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at GENEX_EVAL-recursion2.cmake:8 \(add_custom_target\): + Loop step 1 + + \$<GENEX_EVAL:\$<TARGET_PROPERTY:CUSTOM_PROPERTY2>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at GENEX_EVAL-recursion2.cmake:8 \(add_custom_target\): + Loop step 2 + + \$<TARGET_GENEX_EVAL:recursion,\$<TARGET_PROPERTY:recursion,CUSTOM_PROPERTY1>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2.cmake b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2.cmake new file mode 100644 index 0000000..773749f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL-recursion2.cmake @@ -0,0 +1,10 @@ + +enable_language(C) + +add_library(recursion SHARED empty.c) +set_property (TARGET recursion PROPERTY CUSTOM_PROPERTY1 "$<GENEX_EVAL:$<TARGET_PROPERTY:CUSTOM_PROPERTY2>>") +set_property (TARGET recursion PROPERTY CUSTOM_PROPERTY2 "$<GENEX_EVAL:$<TARGET_PROPERTY:CUSTOM_PROPERTY1>>") + +add_custom_target (drive + COMMAND echo "$<TARGET_GENEX_EVAL:recursion,$<TARGET_PROPERTY:recursion,CUSTOM_PROPERTY1>>" + DEPENDS recursion) diff --git a/Tests/RunCMake/GeneratorExpression/GENEX_EVAL.cmake b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL.cmake new file mode 100644 index 0000000..ab8988b --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/GENEX_EVAL.cmake @@ -0,0 +1,11 @@ + +cmake_policy(VERSION 3.11) + +enable_language(C) + +add_library (example SHARED empty.c) +set_property (TARGET example PROPERTY CUSTOM_PROPERTY1 "PROPERTY1") +set_property (TARGET example PROPERTY CUSTOM_PROPERTY2 "$<TARGET_PROPERTY:CUSTOM_PROPERTY1>") +set_property (TARGET example PROPERTY CUSTOM_PROPERTY3 "$<GENEX_EVAL:BEFORE_$<TARGET_PROPERTY:CUSTOM_PROPERTY2>_AFTER>") + +file(GENERATE OUTPUT "GENEX_EVAL-generated.txt" CONTENT "$<TARGET_GENEX_EVAL:example,$<TARGET_PROPERTY:example,CUSTOM_PROPERTY3>>") diff --git a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake index 5636d00..3905c5f 100644 --- a/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake +++ b/Tests/RunCMake/GeneratorExpression/RunCMakeTest.cmake @@ -42,6 +42,15 @@ run_cmake(TARGET_NAME_IF_EXISTS-no-arg) run_cmake(TARGET_NAME_IF_EXISTS-empty-arg) run_cmake(TARGET_NAME_IF_EXISTS) run_cmake(TARGET_NAME_IF_EXISTS-not-a-target) +run_cmake(TARGET_GENEX_EVAL-no-arg) +run_cmake(TARGET_GENEX_EVAL-no-target) +run_cmake(TARGET_GENEX_EVAL-non-valid-target) +run_cmake(TARGET_GENEX_EVAL-recursion1) +run_cmake(TARGET_GENEX_EVAL-recursion2) +run_cmake(TARGET_GENEX_EVAL) +run_cmake(GENEX_EVAL-recursion1) +run_cmake(GENEX_EVAL-recursion2) +run_cmake(GENEX_EVAL) run_cmake(ImportedTarget-TARGET_BUNDLE_DIR) run_cmake(ImportedTarget-TARGET_BUNDLE_CONTENT_DIR) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-check.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-check.cmake new file mode 100644 index 0000000..124a583 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-check.cmake @@ -0,0 +1,6 @@ +file(READ "${RunCMake_TEST_BINARY_DIR}/TARGET_GENEX_EVAL-generated.txt" content) + +set(expected "BEFORE_PROPERTY1_AFTER") +if(NOT content STREQUAL expected) + set(RunCMake_TEST_FAILED "actual content:\n [[${content}]]\nbut expected:\n [[${expected}]]") +endif() diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-stderr.txt new file mode 100644 index 0000000..9b0844f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at TARGET_GENEX_EVAL-no-arg.cmake:4 \(add_custom_command\): + Error evaluating generator expression: + + \$<TARGET_GENEX_EVAL:> + + \$<TARGET_GENEX_EVAL> expression requires 2 comma separated parameters, but + got 1 instead. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg.cmake new file mode 100644 index 0000000..2dc13ea --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-arg.cmake @@ -0,0 +1,7 @@ + +cmake_policy(VERSION 3.11) + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c" + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.c" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<TARGET_GENEX_EVAL:>.c" +) +add_custom_target(drive DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-stderr.txt new file mode 100644 index 0000000..647fd85 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at TARGET_GENEX_EVAL-no-target.cmake:2 \(add_custom_command\): + Error evaluating generator expression: + + \$<TARGET_GENEX_EVAL:,> + + \$<TARGET_GENEX_EVAL:tgt, ...> expression requires a non-empty valid target + name. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target.cmake new file mode 100644 index 0000000..df4f0ea --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-no-target.cmake @@ -0,0 +1,5 @@ + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c" + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.c" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<TARGET_GENEX_EVAL:,>.c" +) +add_custom_target(drive DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-stderr.txt new file mode 100644 index 0000000..cc44d4b --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target-stderr.txt @@ -0,0 +1,8 @@ +^CMake Error at TARGET_GENEX_EVAL-non-valid-target.cmake:2 \(add_custom_command\): + Error evaluating generator expression: + + \$<TARGET_GENEX_EVAL:bad-target,> + + \$<TARGET_GENEX_EVAL:tgt, ...> target "bad-target" not found. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target.cmake new file mode 100644 index 0000000..8db7375 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-non-valid-target.cmake @@ -0,0 +1,5 @@ + +add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c" + COMMAND "${CMAKE_COMMAND}" -E copy "${CMAKE_CURRENT_SOURCE_DIR}/empty.c" "${CMAKE_CURRENT_BINARY_DIR}/copied_file$<TARGET_GENEX_EVAL:bad-target,>.c" +) +add_custom_target(drive DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/copied_file.c") diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-stderr.txt new file mode 100644 index 0000000..bba2234 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1-stderr.txt @@ -0,0 +1,9 @@ +^CMake Error at TARGET_GENEX_EVAL-recursion1.cmake:7 \(add_custom_target\): + Error evaluating generator expression: + + \$<TARGET_GENEX_EVAL:recursion,\$<TARGET_PROPERTY:CUSTOM_PROPERTY>> + + Self reference on target "recursion". + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1.cmake new file mode 100644 index 0000000..b75d211 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion1.cmake @@ -0,0 +1,9 @@ + +enable_language(C) + +add_library (recursion SHARED empty.c) +set_property (TARGET recursion PROPERTY CUSTOM_PROPERTY "$<TARGET_GENEX_EVAL:recursion,$<TARGET_PROPERTY:CUSTOM_PROPERTY>>") + +add_custom_target (drive + COMMAND echo "$<TARGET_GENEX_EVAL:recursion,$<TARGET_PROPERTY:recursion,CUSTOM_PROPERTY>>" + DEPENDS recursion) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-result.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-result.txt new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-result.txt @@ -0,0 +1 @@ +1 diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-stderr.txt b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-stderr.txt new file mode 100644 index 0000000..73f6b77 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2-stderr.txt @@ -0,0 +1,26 @@ +^CMake Error at TARGET_GENEX_EVAL-recursion2.cmake:10 \(add_custom_target\): + Error evaluating generator expression: + + \$<TARGET_GENEX_EVAL:recursion1,\$<TARGET_PROPERTY:recursion1,CUSTOM_PROPERTY1>> + + Dependency loop found. +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at TARGET_GENEX_EVAL-recursion2.cmake:10 \(add_custom_target\): + Loop step 1 + + \$<TARGET_GENEX_EVAL:recursion2,\$<TARGET_PROPERTY:recursion2,CUSTOM_PROPERTY2>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) + + +CMake Error at TARGET_GENEX_EVAL-recursion2.cmake:10 \(add_custom_target\): + Loop step 2 + + \$<TARGET_GENEX_EVAL:recursion1,\$<TARGET_PROPERTY:recursion1,CUSTOM_PROPERTY1>> + +Call Stack \(most recent call first\): + CMakeLists.txt:3 \(include\) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2.cmake new file mode 100644 index 0000000..a28dfc3 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL-recursion2.cmake @@ -0,0 +1,12 @@ + +enable_language(C) + +add_library (recursion1 SHARED empty.c) +set_property (TARGET recursion1 PROPERTY CUSTOM_PROPERTY1 "$<TARGET_GENEX_EVAL:recursion2,$<TARGET_PROPERTY:recursion2,CUSTOM_PROPERTY2>>") + +add_library (recursion2 SHARED empty.c) +set_property (TARGET recursion2 PROPERTY CUSTOM_PROPERTY2 "$<TARGET_GENEX_EVAL:recursion1,$<TARGET_PROPERTY:recursion1,CUSTOM_PROPERTY1>>") + +add_custom_target (drive + COMMAND echo "$<TARGET_GENEX_EVAL:recursion1,$<TARGET_PROPERTY:recursion1,CUSTOM_PROPERTY1>>" + DEPENDS recursion) diff --git a/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL.cmake b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL.cmake new file mode 100644 index 0000000..68b3712 --- /dev/null +++ b/Tests/RunCMake/GeneratorExpression/TARGET_GENEX_EVAL.cmake @@ -0,0 +1,10 @@ + +cmake_policy(VERSION 3.11) + +enable_language(C) + +add_library (example SHARED empty.c) +set_property (TARGET example PROPERTY CUSTOM_PROPERTY1 "PROPERTY1") +set_property (TARGET example PROPERTY CUSTOM_PROPERTY2 "BEFORE_$<TARGET_PROPERTY:CUSTOM_PROPERTY1>_AFTER") + +file(GENERATE OUTPUT "TARGET_GENEX_EVAL-generated.txt" CONTENT "$<TARGET_GENEX_EVAL:example,$<TARGET_PROPERTY:example,CUSTOM_PROPERTY2>>") |