From fff5c1507e3a555f9195b3d0d36cf8e263d8c02c Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 20:41:18 -0400 Subject: FindMatlab: refactor: use registry query instead of execute_process On Windows, instead of executing "reg query" it's much simpler and more robust to use cmake's built in registry query. Remove unused variables. Significantly reduces amount of code in function. --- Modules/FindMatlab.cmake | 47 +++++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 82350bb..8bdb6db 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -458,50 +458,34 @@ endmacro() function(matlab_extract_all_installed_versions_from_registry win64 matlab_versions) if(NOT CMAKE_HOST_WIN32) - message(FATAL_ERROR "[MATLAB] 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") endif() if(${win64} AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "64") - set(APPEND_REG "/reg:64") + set(_view "64") else() - set(APPEND_REG "/reg:32") + set(_view "32") endif() set(matlabs_from_registry) foreach(_installation_type IN ITEMS "MATLAB" "MATLAB Runtime" "MATLAB Compiler Runtime") - # /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 - ) + cmake_host_system_information(RESULT _reg + QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Mathworks/${_installation_type}" + SUBKEYS VIEW ${_view} + ) + if(_reg) - if(resultMatlab EQUAL 0) + string(REGEX MATCHALL "([0-9]+\\.[0-9]+)" _versions_regex ${_reg}) - string( - REGEX MATCHALL "${_installation_type}\\\\([0-9]+(\\.[0-9]+)?)" - matlab_versions_regex ${varMatlab}) - - foreach(match IN LISTS matlab_versions_regex) - string( - REGEX MATCH "${_installation_type}\\\\(([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() + foreach(match IN LISTS _versions_regex) - list(APPEND matlabs_from_registry ${_matlab_current_version}) - unset(_matlab_current_version) + string(REGEX MATCH "([0-9]+\\.[0-9]+)" current_match ${match}) + if(CMAKE_MATCH_1) + list(APPEND matlabs_from_registry ${CMAKE_MATCH_1}) + endif() endforeach() endif() @@ -509,8 +493,7 @@ function(matlab_extract_all_installed_versions_from_registry win64 matlab_versio if(matlabs_from_registry) list(REMOVE_DUPLICATES matlabs_from_registry) - list(SORT matlabs_from_registry COMPARE NATURAL) - list(REVERSE matlabs_from_registry) + list(SORT matlabs_from_registry COMPARE NATURAL ORDER DESCENDING) endif() set(${matlab_versions} ${matlabs_from_registry} PARENT_SCOPE) -- cgit v0.12 From 8b8135487f50ca34cd3500a968a8ad4c4e126e97 Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 20:55:01 -0400 Subject: FindMatlab: refactor: remove unneeded syntax --- Modules/FindMatlab.cmake | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 8bdb6db..7b15897 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -511,8 +511,7 @@ macro(extract_matlab_versions_from_registry_brute_force matlab_versions) # we order from more recent to older if(matlab_supported_versions) list(REMOVE_DUPLICATES matlab_supported_versions) - list(SORT matlab_supported_versions COMPARE NATURAL) - list(REVERSE matlab_supported_versions) + list(SORT matlab_supported_versions COMPARE NATURAL ORDER DESCENDING) endif() set(${matlab_versions} ${matlab_supported_versions}) @@ -1605,10 +1604,6 @@ 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") @@ -1800,7 +1795,7 @@ endif() # 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}) + list(APPEND CMAKE_FIND_LIBRARY_PREFIXES ${_matlab_library_prefix}) find_library(${ARGN}) endfunction() -- cgit v0.12 From d7b73f14c23bd53051503da460642447bf94b0b6 Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 17:04:10 -0400 Subject: FindMatlab: retrieve full major.minor.patch.tweak --- Modules/FindMatlab.cmake | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 7b15897..a3e966b 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -380,9 +380,17 @@ endmacro() #]=======================================================================] macro(matlab_get_release_name_from_version version release_name) + # only the major.minor version is used + string(REGEX MATCH "([0-9]+\\.[0-9]+)" _match ${version}) + if(CMAKE_MATCH_1) + set(short_version ${CMAKE_MATCH_1}) + else() + set(short_version ${version}) + endif() + set(${release_name} "") foreach(_var IN LISTS MATLAB_VERSIONS_MAPPING) - string(REGEX MATCHALL "(.+)=${version}" _matched ${_var}) + string(REGEX MATCHALL "(.+)=${short_version}" _matched ${_var}) if(NOT _matched STREQUAL "") set(${release_name} ${CMAKE_MATCH_1}) break() @@ -392,7 +400,7 @@ macro(matlab_get_release_name_from_version version release_name) unset(_var) unset(_matched) if(${release_name} STREQUAL "") - message(WARNING "[MATLAB] The version ${version} is not registered") + message(WARNING "[MATLAB] The version ${short_version} is not registered") endif() endmacro() @@ -1396,12 +1404,12 @@ function(_Matlab_VersionInfoXML) if(versioninfo_string) # parses "23.2.0.2365128" - string(REGEX MATCH "(.*)" + string(REGEX MATCH "([0-9]+\\.[0-9]+\\.?[0-9]*\\.?[0-9]*)" version_reg_match ${versioninfo_string} ) - if(CMAKE_MATCH_1 MATCHES "(([0-9]+)\\.([0-9]+))[\\.0-9]*") + if(CMAKE_MATCH_1) set(_matlab_version_tmp "${CMAKE_MATCH_1}") endif() endif() -- cgit v0.12 From ff20d993f326da7c72b99b5b179edf9cf95d9ef8 Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 19:56:08 -0400 Subject: FindMatlab: doc: rename osx=>macOS --- Modules/FindMatlab.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index a3e966b..a2784a2 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -46,7 +46,7 @@ The module supports the following components: 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`). + (e.g. `R2023b`). The :command:`matlab_get_version_from_release_name` and :command:`matlab_get_release_name_from_version` provide a mapping between the release name and the version. @@ -57,7 +57,7 @@ specific: * Windows: The installed versions of Matlab/MCR are retrieved from the Windows registry -* OS X: The installed versions of Matlab/MCR are given by the MATLAB +* macOS: 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 @@ -1452,8 +1452,8 @@ function(_Matlab_find_instances_win32 matlab_roots) endfunction() -# Utility function for finding Matlab or MCR on OSX -function(_Matlab_find_instances_osx matlab_roots) +# Utility function for finding Matlab or MCR on macOS +function(_Matlab_find_instances_macos matlab_roots) set(_matlab_possible_roots) # on mac, we look for the /Application paths @@ -1595,8 +1595,8 @@ else() _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}) + _Matlab_find_instances_macos(_matlab_possible_roots_macos) + list(APPEND _matlab_possible_roots ${_matlab_possible_roots_macos}) endif() endif() -- cgit v0.12 From abbfdd3b3a828696ec4c6a67e593099f4802c7e8 Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 20:04:47 -0400 Subject: FindMatlab: improve version regex the matlab_versions_mapping always has at least major.minor --- Modules/FindMatlab.cmake | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index a2784a2..8383349 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -353,7 +353,7 @@ file(MAKE_DIRECTORY "${_matlab_temporary_folder}") #]=======================================================================] macro(matlab_get_version_from_release_name release_name version_name) - string(REGEX MATCHALL "${release_name}=([0-9]+\\.?[0-9]*)" _matched ${MATLAB_VERSIONS_MAPPING}) + string(REGEX MATCHALL "${release_name}=([0-9]+\\.[0-9]+)" _matched ${MATLAB_VERSIONS_MAPPING}) set(${version_name} "") if(NOT _matched STREQUAL "") @@ -411,7 +411,7 @@ endmacro() 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}) + string(REGEX MATCHALL "(.+)=([0-9]+\\.[0-9]+)" _matched ${_var}) if(NOT _matched STREQUAL "") list(APPEND ${list_releases} ${CMAKE_MATCH_1}) endif() @@ -428,7 +428,7 @@ endmacro() 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}) + string(REGEX MATCHALL "(.+)=([0-9]+\\.[0-9]+)" _matched ${_var}) if(NOT _matched STREQUAL "") list(APPEND ${list_versions} ${CMAKE_MATCH_2}) endif() @@ -831,7 +831,7 @@ function(matlab_get_version_from_matlab_run matlab_binary_program matlab_list_ve string(SUBSTRING "${_matlab_version_from_cmd}" ${index} -1 substring_ans) string( - REGEX MATCHALL "ans[\r\n\t ]*=[\r\n\t ]*'?([0-9]+(\\.[0-9]+)?)" + 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) @@ -1404,7 +1404,7 @@ function(_Matlab_VersionInfoXML) if(versioninfo_string) # parses "23.2.0.2365128" - string(REGEX MATCH "([0-9]+\\.[0-9]+\\.?[0-9]*\\.?[0-9]*)" + string(REGEX MATCH "([0-9]+(\\.[0-9]+)+)" version_reg_match ${versioninfo_string} ) -- cgit v0.12 From dc9d9589e47fc015eedfe13df9723df4585e4e36 Mon Sep 17 00:00:00 2001 From: scivision Date: Thu, 14 Sep 2023 21:24:37 -0400 Subject: FindMatlab:WIN32: return full Matlab version when found via registry rework internal XML reading function for better code reuse and namespace isolation --- Modules/FindMatlab.cmake | 37 ++++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 8383349..d53f512 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -489,10 +489,20 @@ function(matlab_extract_all_installed_versions_from_registry win64 matlab_versio string(REGEX MATCHALL "([0-9]+\\.[0-9]+)" _versions_regex ${_reg}) foreach(match IN LISTS _versions_regex) - string(REGEX MATCH "([0-9]+\\.[0-9]+)" current_match ${match}) - if(CMAKE_MATCH_1) - list(APPEND matlabs_from_registry ${CMAKE_MATCH_1}) + + if(NOT CMAKE_MATCH_1) + continue() + endif() + + cmake_host_system_information(RESULT _reg + QUERY WINDOWS_REGISTRY "HKLM/SOFTWARE/Mathworks/${_installation_type}/${CMAKE_MATCH_1}" + VALUE "MATLABROOT" + ) + + _Matlab_VersionInfoXML(${_reg} _matlab_version_tmp) + if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") + list(APPEND matlabs_from_registry ${_matlab_version_tmp}) endif() endforeach() @@ -1354,10 +1364,10 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve ${_matlab_main_real_path_tmp} CACHE INTERNAL "internal matlab location for the discovered version" FORCE) - _Matlab_VersionInfoXML() - if(Matlab_VERSION_STRING_INTERNAL AND NOT Matlab_VERSION_STRING_INTERNAL STREQUAL "unknown") + _Matlab_VersionInfoXML(${matlab_root} _matlab_version_tmp) + if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") # at least back to R2016 VersionInfo.xml exists - set(matlab_list_of_all_versions ${Matlab_VERSION_STRING_INTERNAL}) + set(matlab_list_of_all_versions ${_matlab_version_tmp}) else() # time consuming, less stable way to find Matlab version by running Matlab matlab_get_version_from_matlab_run("${Matlab_PROG_VERSION_STRING_AUTO_DETECT}" matlab_list_of_all_versions) @@ -1382,7 +1392,10 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve # 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 - _Matlab_VersionInfoXML() + _Matlab_VersionInfoXML(${matlab_root} _matlab_version_tmp) + if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + endif() endif() # Matlab or MCR # return the updated value @@ -1391,9 +1404,9 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve endfunction() -function(_Matlab_VersionInfoXML) +function(_Matlab_VersionInfoXML matlab_root _version) - set(_matlab_version_tmp "unknown") + set(_ver "unknown") set(_XMLfile ${matlab_root}/VersionInfo.xml) if(NOT EXISTS ${_XMLfile}) @@ -1410,13 +1423,11 @@ function(_Matlab_VersionInfoXML) ) if(CMAKE_MATCH_1) - set(_matlab_version_tmp "${CMAKE_MATCH_1}") + set(_ver "${CMAKE_MATCH_1}") endif() endif() - if(_matlab_version_tmp) - set(Matlab_VERSION_STRING_INTERNAL "${_matlab_version_tmp}" CACHE INTERNAL "Matlab version" FORCE) - endif() + set(${_version} ${_ver} PARENT_SCOPE) endfunction() -- cgit v0.12 From 35bcb9116c7ec89320e2f7d092a6581272afa145 Mon Sep 17 00:00:00 2001 From: scivision Date: Mon, 18 Sep 2023 15:13:34 -0400 Subject: FindMatlab:lint: set(... CACHE INTERNAL) implies FORCE --- Modules/FindMatlab.cmake | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index d53f512..8fdccdf 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -1280,7 +1280,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve 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) + set(Matlab_VERSION_STRING_INTERNAL ${matlab_known_version} CACHE INTERNAL "Matlab version (automatically determined)") return() endif() @@ -1341,8 +1341,8 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve 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) + set(Matlab_PROG_VERSION_STRING_AUTO_DETECT "" CACHE INTERNAL "internal matlab location for the discovered version") + set(Matlab_VERSION_STRING_INTERNAL "" CACHE INTERNAL "internal matlab location for the discovered version") unset(_matlab_current_program) unset(_matlab_current_program CACHE) return() @@ -1362,7 +1362,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve # 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) + CACHE INTERNAL "internal matlab location for the discovered version") _Matlab_VersionInfoXML(${matlab_root} _matlab_version_tmp) if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") @@ -1381,7 +1381,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve endif() # set the version into the cache - set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)") # warning, just in case several versions found (should not happen) if((list_of_all_versions_length GREATER 1) AND MATLAB_FIND_DEBUG) @@ -1394,7 +1394,7 @@ function(_Matlab_get_version_from_root matlab_root matlab_or_mcr matlab_known_ve # VersionInfo.xml exists under the MatlabRoot, we look for it and extract the version from there _Matlab_VersionInfoXML(${matlab_root} _matlab_version_tmp) if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") - set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)" FORCE) + set(Matlab_VERSION_STRING_INTERNAL ${_matlab_version_tmp} CACHE INTERNAL "Matlab version (automatically determined)") endif() endif() # Matlab or MCR -- cgit v0.12 From 39881de3f6183f6df7f6406724546a35fd8d8f7e Mon Sep 17 00:00:00 2001 From: scivision Date: Mon, 18 Sep 2023 15:50:10 -0400 Subject: FindMatlab:macOS: return full version when found by path guess --- Modules/FindMatlab.cmake | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Modules/FindMatlab.cmake b/Modules/FindMatlab.cmake index 8fdccdf..639cc5f 100644 --- a/Modules/FindMatlab.cmake +++ b/Modules/FindMatlab.cmake @@ -1481,6 +1481,11 @@ function(_Matlab_find_instances_macos matlab_roots) string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") set(_matlab_base_path "/Applications/MATLAB_${_matlab_current_release}.app") + _Matlab_VersionInfoXML(${_matlab_base_path} _matlab_version_tmp) + if(NOT "${_matlab_version_tmp}" STREQUAL "unknown") + set(_matlab_current_version ${_matlab_version_tmp}) + endif() + # Check Matlab, has precedence over MCR if(IS_DIRECTORY "${_matlab_base_path}") if(MATLAB_FIND_DEBUG) -- cgit v0.12