查找Matlab

查找 Matlab 或 Matlab Compiler Runtime (MCR) 并为 CMake 提供 Matlab 工具、库和编译器。

这个包的主要目的是找到与 Matlab 或 MCR 相关的库,以便能够构建 Matlab 扩展(mex 文件)。它也可以用于:

  • 在 Matlab 可用的情况下在 Matlab 中运行特定命令

  • 用于声明 Matlab 单元测试

  • 从 Matlab 检索各种信息(mex 扩展、版本和发布查询,...)

在 3.12 版本加入: 添加了 Matlab 编译器运行时 (MCR) 支持。

该模块支持以下组件:

  • ENG_LIBRARYMAT_LIBRARY:分别是 Matlab 的 ENGMAT

  • MAIN_PROGRAM Matlab 二进制程序。请注意,此组件在 MCR 版本上不可用,如果找到 MCR 而不是常规的 Matlab 安装,则会产生错误。

  • MEX_COMPILER MEX 编译器。

  • MCC_COMPILER MCC 编译器,包含在 Matlab 编译器附加组件中。

  • SIMULINK Simulink 环境。

在 3.7 版本加入: 添加了``MAT_LIBRARY`` 组件。

在 3.13 版本加入: 添加了``ENGINE_LIBRARY``、DATAARRAY_LIBRARY 和``MCC_COMPILER`` 组件。

在 3.14 版本发生变更: 删除了 MX_LIBRARYENGINE_LIBRARYDATAARRAY_LIBRARY 组件。这些库是无条件找到的。

备注

提供给 find_package() 指令的版本是 Matlab version,不应与 Matlab release 名称(例如 R2014)混淆。 matlab_get_version_from_release_name()matlab_get_release_name_from_version() 提供发布名称和版本之间的映射。

可以指定变量 Matlab_ROOT_DIR 以提供所需 Matlab 版本的路径。否则,行为是特定于平台的:

  • Windows:从 Windows 注册表中检索已安装的 Matlab/MCR 版本

  • OS X:安装的 Matlab/MCR 版本由 /Application 中的 MATLAB 默认安装路径给出。如果没有找到这样的应用程序,它会回退到可以从 PATH 访问的应用程序。

  • Unix:所需的 Matlab 应该可以从 PATH 访问。这不适用于 MCR 安装,应在此平台上指定 Matlab_ROOT_DIR

设置 MATLAB_FIND_DEBUG 时会提供其他信息。当自动找到 Matlab/MCR 安装且未给出 MATLAB_VERSION 时,将直接从 Matlab(在 Windows 上这可能会弹出一个 Matlab 窗口)或从 MCR 安装查询版本。

发布名称和 Matlab 版本的映射是通过定义对 (name, version) 来执行的。可以在调用 find_package() 之前提供变量 MATLAB_ADDITIONAL_VERSIONS 以处理其他版本。

可以使用 matlab_add_unit_test() 将 Matlab 脚本添加到测试集中。默认情况下,将使用 Matlab 单元测试框架 (>= 2013a) 来运行此脚本,但也可以使用返回退出代码的常规 .m 文件(0 表示成功)。

模块输入变量

用户或项目可以设置以下变量来配置模块行为:

Matlab_ROOT

在 3.25 版本加入.

Matlab_ROOT_DIR 的默认值,Matlab 安装的根目录。

Matlab_ROOT_DIR

Matlab 安装的根目录。

MATLAB_FIND_DEBUG

输出调试信息

MATLAB_ADDITIONAL_VERSIONS

其他版本的 Matlab 用于自动检索已安装的版本。

导入目标

在 3.22 版本加入.

该模块定义了以下 IMPORTED 目标:

Matlab::mex

mex 库,始终可用。

Matlab::mx

Matlab 的 mx 库(数组),始终可用。

Matlab::eng

Matlab引擎库。仅在请求“ENG_LIBRARY”组件时可用。

Matlab::mat

Matlab矩阵库。仅在请求“MAT_LIBRARY”组件时可用。

Matlab::MatlabEngine

Matlab C++ 引擎库,始终适用于 R2018a 及更新版本。

Matlab::Matlab 数据数组

Matlab C++ 数据数组库,始终适用于 R2018a 及更新版本。

模块定义的变量

结果变量

Matlab_FOUND

如果找到 Matlab 安装,则为 TRUE,否则为 FALSE。如果找到 Matlab,则定义以下所有变量。

Matlab_ROOT_DIR

由 FindMatlab 模块确定的 Matlab 安装的最终根目录。

Matlab_MAIN_PROGRAM

Matlab 二进制程序。只有在 find_package() 指令中给出了组件 MAIN_PROGRAM 才可用。

Matlab_INCLUDE_DIRS

Matlab 库标题的路径

Matlab_MEX_LIBRARY

mex 库,始终可用。

Matlab_MX_LIBRARY

Matlab 的 mx 库(数组),始终可用。

Matlab_ENG_LIBRARY

Matlab引擎库。仅在请求组件“ENG_LIBRARY”时可用。

Matlab_MAT_LIBRARY

Matlab矩阵库。仅在请求组件“MAT_LIBRARY”时可用。

Matlab_ENGINE_LIBRARY

在 3.13 版本加入.

Matlab C++ 引擎库,始终适用于 R2018a 及更新版本。

Matlab_DATAARRAY_LIBRARY

在 3.13 版本加入.

Matlab C++ 数据数组库,始终适用于 R2018a 及更新版本。

Matlab_LIBRARIES

整套Matlab库

Matlab_MEX_COMPILER

Matlab 的 mex 编译器。目前没有使用。仅在请求组件“MEX_COMPILER”时可用。

Matlab_MCC_COMPILER

在 3.13 版本加入.

Matlab的mcc编译器。包含在 Matlab 编译器附加组件中。仅在请求组件“MCC_COMPILER”时可用。

缓存变量

Matlab_MEX_EXTENSION

当前平台的 mex 文件扩展名(由 Matlab 提供)。

Matlab_ROOT_DIR

找到 Matlab 安装根目录的位置。如果用户更改了该值,则会重新计算结果变量。

提供的宏

matlab_get_version_from_release_name()

从发布名称返回版本

matlab_get_release_name_from_version()

返回 Matlab 版本的发布名称

提供的功能

matlab_add_mex()

添加编译 MEX 文件的目标。

matlab_add_unit_test()

添加一个 Matlab 单元测试文件作为对项目的测试。

matlab_extract_all_installed_versions_from_registry()

解析所有 Matlab 版本的注册表。仅适用于 Windows。解析的注册表部分取决于主机处理器

matlab_get_all_valid_matlab_roots_from_registry()

根据先前给定的列表,返回所有可能的 Matlab 或 MCR 路径。只保留现有/可访问的路径。这主要用于搜索所有可能的 Matlab 安装。

matlab_get_mex_suffix()

返回用于 mex 文件的后缀(取决于平台/体系结构)

matlab_get_version_from_matlab_run()

返回 Matlab/MCR 的版本,给定 Matlab/MCR 安装路径的完整目录。

已知的问题

MEX 目标中的符号冲突

默认情况下,MEX 文件中使用命令 matlab_add_mex 定义的每个符号都隐藏可见性,入口点除外。这是 MEX 编译器的默认行为,它降低了 Matlab 附带的库与 MEX 文件链接到的库之间发生符号冲突的风险。这也是 Windows 平台上的默认设置。

但是,这在某些情况下是不够的,例如您的 MEX 文件链接到 Matlab 已经加载的库,即使这些库具有不同的 SONAMES。一种可能的解决方案是隐藏 MEX 目标链接到的库的符号。这可以在 GNU GCC 编译器中使用链接器选项“-Wl,--exclude-libs,ALL”来实现。

使用 GPU 资源进行测试

如果您的 MEX 文件正在使用 GPU,并且为了能够对此 MEX 文件运行单元测试,Matlab 应正确释放 GPU 资源。一个可能的解决方案是让 Matlab 知道会话中 GPU 资源的使用,这可以通过在测试脚本开头(或通过夹具)执行诸如“D = gpuDevice()”之类的命令.

参考

Matlab_ROOT_DIR

Matlab 安装的根文件夹。如果在调用 find_package() 之前设置,模块将在该路径中查找组件。如果未设置,则将执行 Matlab 的自动搜索。如果设置,它应该指向一个有效的 Matlab 版本。

MATLAB_FIND_DEBUG

如果设置,Matlab 的查找和中间配置步骤将输出到控制台。

MATLAB_ADDITIONAL_VERSIONS

如果设置,指定可能查找的其他版本的 Matlab。该变量应该是一个字符串列表,由成对的发布名称和版本组织,例如:

set(MATLAB_ADDITIONAL_VERSIONS
    "release_name1=corresponding_version1"
    "release_name2=corresponding_version2"
    ...
    )

例子::

set(MATLAB_ADDITIONAL_VERSIONS
    "R2013b=8.2"
    "R2013a=8.1"
    "R2012b=8.0")

当安装了多个版本的 Matlab 时,此列表中的条目顺序很重要。优先级是根据此列表中的顺序设置的。

matlab_get_version_from_release_name

从发布名称 (R2017k) 返回 Matlab (17.58) 的版本

matlab_get_release_name_from_version

返回 Matlab (17.58) 版本的发布名称 (R2017k)

matlab_extract_all_installed_versions_from_registry

此函数解析注册表并找到已安装的 Matlab 版本。找到的版本在“matlab_versions”中返回。如果要查找 64 位版本的 Matlab,请将 win64 设置为 TRUE 返回的列表包含 HKLM\\SOFTWARE\\Mathworks\\MATLABHKLM\\SOFTWARE\\Mathworks 下的所有版本\\MATLAB Runtime 或一个空列表,以防发生错误(或未找到任何内容)。

备注

仅提供版本。不检查注册表中引用的安装是否存在,

matlab_get_all_valid_matlab_roots_from_registry

使用有效版本的 Matlab 或 Matlab Runtime (MCR) 填充 Matlab 根目录。返回的 matlab_roots 被组织成三元组``(type,version_number,matlab_root_path)``,其中``type`` 表示``MATLAB`` 或``MCR``。

matlab_get_all_valid_matlab_roots_from_registry(
    matlab_versions
    matlab_roots)
matlab_versions

每个 Matlab 或 MCR 安装的版本

matlab_roots

每个 Matlab 或 MCR 安装的位置

matlab_get_mex_suffix

返回 mex 文件的扩展名(后缀)。在找到适当的 Matlab 根之前,不应调用此函数。

matlab_get_mex_suffix(
    matlab_root
    mex_suffix)
matlab_root

Matlab/MCR 安装的根目录

mex_suffix

返回后缀的变量名。

matlab_get_version_from_matlab_run

此函数运行参数指定的 Matlab 程序并提取其版本。如果为 Matlab 安装提供的路径指向 MCR 安装,则会从安装的文件中提取版本。

matlab_get_version_from_matlab_run(
    matlab_binary_path
    matlab_list_versions)
matlab_binary_path

matlab 二进制可执行文件的位置

matlab_list_versions

从 Matlab 中提取的版本

matlab_add_unit_test

将 Matlab 单元测试添加到 cmake/ctest 的测试集中。此命令需要组件“MAIN_PROGRAM”,因此不适用于 MCR 安装。

单元测试使用 Matlab unittest 框架(默认,从 Matlab 2013b+ 开始可用)除非给出选项 NO_UNITTEST_FRAMEWORK

该函数需要一个 Matlab 测试脚本文件。在给出 NO_UNITTEST_FRAMEWORK 的情况下,unittest 脚本文件应包含要运行的脚本,以及带有退出值的退出命令。此退出值将传递给 ctest 框架(0 成功,非 0 失败)。 add_test() 接受的附加参数可以通过 TEST_ARGS 传递(例如 CONFIGURATION <config> ...)。

matlab_add_unit_test(
    NAME <name>
    UNITTEST_FILE matlab_file_containing_unittest.m
    [CUSTOM_TEST_COMMAND matlab_command_to_run_as_test]
    [UNITTEST_PRECOMMAND matlab_command_to_run]
    [TIMEOUT timeout]
    [ADDITIONAL_PATH path1 [path2 ...]]
    [MATLAB_ADDITIONAL_STARTUP_OPTIONS option1 [option2 ...]]
    [TEST_ARGS arg1 [arg2 ...]]
    [NO_UNITTEST_FRAMEWORK]
    )

函数参数是:

名字

ctest中单元测试的名称。

UNITTEST_FILE

matlab 单元测试文件。它的路径将自动添加到 Matlab 路径中。

CUSTOM_TEST_COMMAND

作为测试运行的 Matlab 脚本命令。如果未设置,则运行以下命令:runtests('matlab_file_name'), exit(max([ans(1,:).Failed])) 其中 matlab_file_name``UNITTEST_FILE `` 没有扩展名。

UNITTEST_PRECOMMAND

在包含测试的文件之前运行的 Matlab 脚本命令(例如,基于 CMake 变量的 GPU 设备初始化)。

超时

以秒为单位的测试超时。默认为 180 秒,因为 Matlab 单元测试可能会挂起。

ADDITIONAL_PATH

在运行单元测试之前添加到 Matlab 路径的路径列表。

MATLAB_ADDITIONAL_STARTUP_OPTIONS

为了从命令行运行 Matlab 的附加选项列表。 -nosplash -nodesktop -nodisplay 总是被添加。

测试参数

提供给 add_test 命令的附加选项。这些选项被添加到默认选项(例如“CONFIGURATIONS Release”)

NO_UNITTEST_FRAMEWORK

设置后,表示测试不应使用 Matlab 的单元测试框架(适用于 >= R2013a 的版本)。

工作目录

这将是测试的工作目录。如果指定,它也将是用于测试运行日志文件的输出目录。如果未指定临时目录 ${CMAKE_BINARY_DIR}/Matlab 将用作工作目录和日志位置。

matlab_add_mex

添加 Matlab MEX 目标。此命令使用当前工具链编译给定源以生成 MEX 文件。可以指定生成的输出的最终名称,以及其他链接库和 MEX 文件的文档条目。调用的其余参数传递给 add_library()add_executable() 命令。

matlab_add_mex(
    NAME <name>
    [EXECUTABLE | MODULE | SHARED]
    SRC src1 [src2 ...]
    [OUTPUT_NAME output_name]
    [DOCUMENTATION file.txt]
    [LINK_TO target1 target2 ...]
    [R2017b | R2018a]
    [EXCLUDE_FROM_ALL]
    [NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES]
    [...]
)
名字

目标的名称。

SRC

源文件列表。

LINK_TO

附加链接依赖项的列表。默认情况下,目标链接到 libmexlibmx,除非传递了 NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES 选项。

OUTPUT_NAME

如果给定,则覆盖默认名称。默认名称是没有任何前缀和带有“Matlab_MEX_EXTENSION”后缀的目标名称。

文档

如果给定,文件 file.txt 将被视为 MEX 文件的文档文件。该文件未经任何处理被复制到同一文件夹中,与最终的 mex 文件同名,扩展名为“.m”。在这种情况下,在 Matlab 中键入 help <name> 将打印此文件中包含的文档。

R2017bR2018a

在 3.14 版本加入.

可以给出指定要使用的 C API 的版本:R2017b 指定传统的(单独的复杂)C API,并且对应于``-R2017b`` 标志用于`mex` 命令。 R2018a 指定新的交错复杂 C API,对应于 mex 命令的 -R2018a 标志。如果 MATLAB 版本早于 R2018a,则忽略。默认为“R2017b”。

MODULESHARED

在 3.7 版本加入.

可以给出指定要创建的库的类型。

可执行

在 3.7 版本加入.

可以创建一个可执行文件而不是一个库。如果没有明确给出类型,则类型为“SHARED”。

EXCLUDE_FROM_ALL

此选项与 EXCLUDE_FROM_ALL 具有相同的含义,并转发到 add_library()add_executable() 命令。

NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES

在 3.24 版本加入.

此选项允许禁用 MATLAB 库的自动链接,以便只有实际需要的库可以通过“LINK_TO”选项链接。

文档文件未处理,应采用以下格式:

% This is the documentation
function ret = mex_target_output_name(input1)