From 26e5f3d525fd4ce9b5fad29b006e9dc797819979 Mon Sep 17 00:00:00 2001 From: Silvio Traversaro Date: Fri, 12 Mar 2021 11:20:56 +0100 Subject: [PATCH] Avoid to link mex file to too many not used libraries and fix use in MATLAB Online (#62) --- cmake/FindMatlab.cmake | 154 +++++++++++++++++++++++--------- sources/Simulink/CMakeLists.txt | 3 +- 2 files changed, 113 insertions(+), 44 deletions(-) diff --git a/cmake/FindMatlab.cmake b/cmake/FindMatlab.cmake index a9d3bed..adef58d 100644 --- a/cmake/FindMatlab.cmake +++ b/cmake/FindMatlab.cmake @@ -1,5 +1,7 @@ -# Distributed under the OSI-approved BSD 3-Clause License. See accompanying -# file Copyright.txt or https://cmake.org/licensing for details. +# Vendored from https://gitlab.kitware.com/cmake/cmake/-/raw/v3.20.0-rc3/Modules/FindMatlab.cmake +# With local modification to implement https://gitlab.kitware.com/cmake/cmake/-/issues/21912 +# Distributed under the OSI-approved BSD 3-Clause License. See +# https://cmake.org/licensing for details. #[=======================================================================[.rst: FindMatlab @@ -17,6 +19,9 @@ can also be used: * to retrieve various information from Matlab (mex extensions, versions and release queries, ...) +.. versionadded:: 3.12 + Added Matlab Compiler Runtime (MCR) support. + The module supports the following components: * ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``ENG`` and ``MAT`` @@ -28,6 +33,17 @@ The module supports the following components: * ``MCC_COMPILER`` the MCC compiler, included with the Matlab Compiler add-on. * ``SIMULINK`` the Simulink environment. +.. versionadded:: 3.7 + Added the ``MAT_LIBRARY`` component. + +.. versionadded:: 3.13 + Added the ``ENGINE_LIBRARY``, ``DATAARRAY_LIBRARY`` and ``MCC_COMPILER`` + components. + +.. versionchanged:: 3.14 + Removed the ``MX_LIBRARY``, ``ENGINE_LIBRARY`` and ``DATAARRAY_LIBRARY`` + components. These libraries are found unconditionally. + .. note:: The version given to the :command:`find_package` directive is the Matlab @@ -107,8 +123,12 @@ Result variables Matlab matrix library. Available only if the component ``MAT_LIBRARY`` is requested. ``Matlab_ENGINE_LIBRARY`` + .. versionadded:: 3.13 + Matlab C++ engine library, always available for R2018a and newer. ``Matlab_DATAARRAY_LIBRARY`` + .. versionadded:: 3.13 + Matlab C++ data array library, always available for R2018a and newer. ``Matlab_LIBRARIES`` the whole set of libraries of Matlab @@ -116,6 +136,8 @@ Result variables the mex compiler of Matlab. Currently not used. Available only if the component ``MEX_COMPILER`` is requested. ``Matlab_MCC_COMPILER`` + .. versionadded:: 3.13 + the mcc compiler of Matlab. Included with the Matlab Compiler add-on. Available only if the component ``MCC_COMPILER`` is requested. @@ -241,6 +263,8 @@ if(NOT MATLAB_ADDITIONAL_VERSIONS) endif() set(MATLAB_VERSIONS_MAPPING + "R2020b=9.9" + "R2020a=9.8" "R2019b=9.7" "R2019a=9.6" "R2018b=9.5" @@ -387,12 +411,12 @@ function(matlab_extract_all_installed_versions_from_registry win64 matlab_versio set(matlabs_from_registry) - foreach(_installation_type IN ITEMS "MATLAB" "MATLAB Runtime") + 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} + COMMAND reg query "HKEY_LOCAL_MACHINE\\SOFTWARE\\Mathworks\\${_installation_type}" /f * /k ${APPEND_REG} RESULT_VARIABLE resultMatlab OUTPUT_VARIABLE varMatlab ERROR_VARIABLE errMatlab @@ -403,12 +427,12 @@ function(matlab_extract_all_installed_versions_from_registry win64 matlab_versio if(resultMatlab EQUAL 0) string( - REGEX MATCHALL "MATLAB\\\\([0-9]+(\\.[0-9]+)?)" + REGEX MATCHALL "${_installation_type}\\\\([0-9]+(\\.[0-9]+)?)" matlab_versions_regex ${varMatlab}) foreach(match IN LISTS matlab_versions_regex) string( - REGEX MATCH "MATLAB\\\\(([0-9]+)(\\.([0-9]+))?)" + REGEX MATCH "${_installation_type}\\\\(([0-9]+)(\\.([0-9]+))?)" current_match ${match}) set(_matlab_current_version ${CMAKE_MATCH_1}) @@ -515,7 +539,7 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_ "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB\\${_matlab_current_version};MATLABROOT]" ABSOLUTE) - if(EXISTS ${current_MATLAB_ROOT}) + if(EXISTS "${current_MATLAB_ROOT}") list(APPEND _matlab_roots_list "MATLAB" ${_matlab_current_version} ${current_MATLAB_ROOT}) endif() @@ -531,7 +555,23 @@ function(matlab_get_all_valid_matlab_roots_from_registry matlab_versions matlab_ # remove the dot string(REPLACE "." "" _matlab_current_version_without_dot "${_matlab_current_version}") - if(EXISTS ${current_MATLAB_ROOT}) + 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() + + # Check for old MCR installations + foreach(_matlab_current_version ${matlab_versions}) + get_filename_component( + current_MATLAB_ROOT + "[HKEY_LOCAL_MACHINE\\SOFTWARE\\MathWorks\\MATLAB Compiler 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() @@ -901,6 +941,7 @@ endfunction() [LINK_TO target1 target2 ...] [R2017b | R2018a] [EXCLUDE_FROM_ALL] + [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES] [...] ) @@ -910,7 +951,7 @@ endfunction() list of source files. ``LINK_TO`` a list of additional link dependencies. The target links to ``libmex`` - and ``libmx`` by default. + and ``libmx`` by default, unless NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES is passed. ``OUTPUT_NAME`` if given, overrides the default name. The default name is the name of the target without any prefix and @@ -921,19 +962,35 @@ endfunction() the same folder without any processing, with the same name as the final mex file, and with extension `.m`. In that case, typing ``help `` in Matlab prints the documentation contained in this file. - ``R2017b`` or ``R2018a`` may be given to specify the version of the C API + ``R2017b`` or ``R2018a`` + .. versionadded:: 3.14 + + May be given to specify the version of the C API to use: ``R2017b`` specifies the traditional (separate complex) C API, and corresponds to the ``-R2017b`` flag for the `mex` command. ``R2018a`` specifies the new interleaved complex C API, and corresponds to the ``-R2018a`` flag for the `mex` command. Ignored if MATLAB version prior to R2018a. Defaults to ``R2017b``. - ``MODULE`` or ``SHARED`` may be given to specify the type of library to be - created. ``EXECUTABLE`` may be given to create an executable instead of + + ``MODULE`` or ``SHARED`` + .. versionadded:: 3.7 + + May be given to specify the type of library to be + created. + + ``EXECUTABLE`` + .. versionadded:: 3.7 + + May be given to create an executable instead of a library. If no type is given explicitly, the type is ``SHARED``. ``EXCLUDE_FROM_ALL`` This option has the same meaning as for :prop_tgt:`EXCLUDE_FROM_ALL` and is forwarded to :command:`add_library` or :command:`add_executable` commands. + ``NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES`` + This option permits to disable the automatic linking of MATLAB libraries, + so that only the libraries that are actually required can be linked via the + ``LINK_TO`` option. The documentation file is not processed and should be in the following format: @@ -960,7 +1017,7 @@ function(matlab_add_mex) endif() - set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL) + set(options EXECUTABLE MODULE SHARED R2017b R2018a EXCLUDE_FROM_ALL NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES) set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME) set(multiValueArgs LINK_TO SRC) @@ -991,7 +1048,10 @@ function(matlab_add_mex) endif() endif() - if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4") # For 9.4 (R2018a) and newer, add API macro + # For 9.4 (R2018a) and newer, add API macro. + # Add it for unknown versions too, just in case. + if(NOT Matlab_VERSION_STRING VERSION_LESS "9.4" + OR Matlab_VERSION_STRING STREQUAL "unknown") if(${${prefix}_R2018a}) set(MEX_API_MACRO "MATLAB_DEFAULT_RELEASE=R2018a") else() @@ -1029,11 +1089,19 @@ function(matlab_add_mex) target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS}) - if(Matlab_HAS_CPP_API) - target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY} ${Matlab_DATAARRAY_LIBRARY}) + if(NOT ${prefix}_NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES) + if(Matlab_HAS_CPP_API) + if(Matlab_ENGINE_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY}) + endif() + if(Matlab_DATAARRAY_LIBRARY) + target_link_libraries(${${prefix}_NAME} ${Matlab_DATAARRAY_LIBRARY}) + endif() + endif() + + target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY}) endif() - - target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${${prefix}_LINK_TO}) + target_link_libraries(${${prefix}_NAME} ${${prefix}_LINK_TO}) set_target_properties(${${prefix}_NAME} PROPERTIES PREFIX "" @@ -1650,32 +1718,34 @@ find_path( ) list(APPEND _matlab_required_variables Matlab_INCLUDE_DIRS) -_Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_MEX_LIBRARY - mex - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH -) -list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY) +if(Matlab_Or_MCR STREQUAL "MATLAB" OR Matlab_Or_MCR STREQUAL "UNKNOWN") + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MEX_LIBRARY + mex + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY) -# the MEX extension is required -list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION) + # the MEX extension is required + list(APPEND _matlab_required_variables Matlab_MEX_EXTENSION) -# the matlab root is required -list(APPEND _matlab_required_variables Matlab_ROOT_DIR) + # the matlab root is required + list(APPEND _matlab_required_variables Matlab_ROOT_DIR) -# The MX library is required -_Matlab_find_library( - ${_matlab_lib_prefix_for_search} - Matlab_MX_LIBRARY - mx - PATHS ${_matlab_lib_dir_for_search} - NO_DEFAULT_PATH -) -list(APPEND _matlab_required_variables Matlab_MX_LIBRARY) -if(Matlab_MX_LIBRARY) - set(Matlab_MX_LIBRARY_FOUND TRUE) + # The MX library is required + _Matlab_find_library( + ${_matlab_lib_prefix_for_search} + Matlab_MX_LIBRARY + mx + PATHS ${_matlab_lib_dir_for_search} + NO_DEFAULT_PATH + ) + list(APPEND _matlab_required_variables Matlab_MX_LIBRARY) + if(Matlab_MX_LIBRARY) + set(Matlab_MX_LIBRARY_FOUND TRUE) + endif() endif() if(Matlab_HAS_CPP_API) @@ -1689,7 +1759,6 @@ if(Matlab_HAS_CPP_API) DOC "MatlabEngine Library" NO_DEFAULT_PATH ) - list(APPEND _matlab_required_variables Matlab_ENGINE_LIBRARY) if(Matlab_ENGINE_LIBRARY) set(Matlab_ENGINE_LIBRARY_FOUND TRUE) endif() @@ -1703,7 +1772,6 @@ if(Matlab_HAS_CPP_API) DOC "MatlabDataArray Library" NO_DEFAULT_PATH ) - list(APPEND _matlab_required_variables Matlab_DATAARRAY_LIBRARY) if(Matlab_DATAARRAY_LIBRARY) set(Matlab_DATAARRAY_LIBRARY_FOUND TRUE) endif() diff --git a/sources/Simulink/CMakeLists.txt b/sources/Simulink/CMakeLists.txt index 7227719..c17eb07 100644 --- a/sources/Simulink/CMakeLists.txt +++ b/sources/Simulink/CMakeLists.txt @@ -11,7 +11,8 @@ matlab_add_mex( src/SimulinkBlockInformationImpl.cpp include/BlockFactory/Simulink/Private/SimulinkBlockInformationImpl.h src/BlockFactory.cpp - LINK_TO BlockFactory::Core shlibpp::shlibpp mxpp) + NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES + LINK_TO ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} BlockFactory::Core shlibpp::shlibpp mxpp) add_library(BlockFactory::Simulink ALIAS Simulink) target_compile_warnings(Simulink