FindMatlab

尋找 Matlab 或 Matlab Compiler Runtime (MCR),並為 CMake 提供 Matlab 工具、函式庫和編譯器。

此套件的主要目的是尋找與 Matlab 或 MCR 相關聯的函式庫,以便能夠建置 Matlab 擴充功能 (mex 檔案)。它也可以用於

  • 在 Matlab 可用的情況下,於 Matlab 中執行特定指令

  • 宣告 Matlab 單元測試

  • 從 Matlab 擷取各種資訊 (mex 擴充功能、版本和發行版本查詢,...)

版本 3.12 新增:新增 Matlab Compiler Runtime (MCR) 支援。

此模組支援以下組件

  • ENG_LIBRARYMAT_LIBRARY:分別為 Matlab 的 ENGMAT 函式庫

  • MAIN_PROGRAM Matlab 二進制程式。請注意,此組件在 MCR 版本上不可用,如果找到 MCR 而不是常規 Matlab 安裝,將會產生錯誤。

  • MEX_COMPILER MEX 編譯器。

  • MCC_COMPILER MCC 編譯器,包含在 Matlab Compiler 附加元件中。

  • SIMULINK Simulink 環境。

版本 3.7 新增:新增 MAT_LIBRARY 組件。

版本 3.13 新增:新增 ENGINE_LIBRARYDATAARRAY_LIBRARYMCC_COMPILER 組件。

版本 3.14 變更:移除 MX_LIBRARYENGINE_LIBRARYDATAARRAY_LIBRARY 組件。這些函式庫會無條件地被找到。

版本 3.30 新增:新增對 find_package() 指定版本範圍的支援,並新增對 find_package() 指定 REGISTRY_VIEW 的支援、matlab_extract_all_installed_versions_from_registry()matlab_get_all_valid_matlab_roots_from_registry()。預設行為保持不變,使用登錄檢視 TARGET

注意

給予 find_package() 指令的版本是 Matlab 的版本,不應與 Matlab 的發行版本名稱 (例如 R2023b) 混淆。matlab_get_version_from_release_name()matlab_get_release_name_from_version() 提供了發行版本名稱和版本之間的對應關係。

可以指定變數 Matlab_ROOT_DIR 以給定所需 Matlab 版本的路徑。否則,行為會是平台特定的

  • Windows:Matlab/MCR 的已安裝版本是從 Windows 登錄檔中檢索的。可以選擇性地指定 REGISTRY_VIEW 參數,以手動控制應搜尋 32 位元或 64 位元版本。

  • macOS:Matlab/MCR 的已安裝版本由 $HOME/Applications/Applications 下的 MATLAB 預設安裝路徑給定。如果找不到此類應用程式,則會回退到可能從 PATH 存取的一個。

  • Unix:所需的 Matlab 應可從 PATH 存取。這不適用於 MCR 安裝,並且應在此平台上指定 Matlab_ROOT_DIR

當設定 MATLAB_FIND_DEBUG 時,會提供額外資訊。當自動找到 Matlab/MCR 安裝且未給定 MATLAB_VERSION 時,版本會直接從 Matlab (在 Windows 上,這可能會彈出 Matlab 視窗) 或從 MCR 安裝中查詢。

發行版本名稱和 Matlab 版本的對應是透過定義配對 (名稱,版本) 來執行的。可以在呼叫 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 安裝。如果 MCR 提供,則適用於 MCR 安裝。

Matlab::mx

Matlab 的 mx 函式庫 (陣列),始終適用於 MATLAB 安裝。如果 MCR 提供,則適用於 MCR 安裝。

Matlab::eng

Matlab 引擎函式庫。僅當請求 ENG_LIBRARY 組件時可用。

Matlab::mat

Matlab 矩陣函式庫。僅當請求 MAT_LIBRARY 組件時可用。

Matlab::MatlabEngine

Matlab C++ 引擎函式庫,始終適用於 MATLAB R2018a 及更新版本。如果 MCR 提供,則適用於 MCR 安裝。

Matlab::MatlabDataArray

Matlab C++ 資料陣列函式庫,始終適用於 MATLAB R2018a 及更新版本。如果 MCR 提供,則適用於 MCR 安裝。

模組定義的變數

結果變數

Matlab_FOUND

如果找到 Matlab 安裝,則為 TRUE,否則為 FALSE。如果找到 Matlab,則定義以下所有變數。

Matlab_VERSION

版本 3.27 新增。

找到的 Matlab 的數值版本 (例如 23.2.0)。不要與 Matlab 發行版本名稱 (例如 R2023b) 混淆,可以使用 matlab_get_release_name_from_version() 取得。

Matlab_ROOT_DIR

由 FindMatlab 模組確定的 Matlab 安裝的最終根目錄。

Matlab_MAIN_PROGRAM

Matlab 二進制程式。僅當 find_package() 指令中給定組件 MAIN_PROGRAM 時可用。

Matlab_INCLUDE_DIRS

Matlab 函式庫標頭的路徑

Matlab_MEX_LIBRARY

mex 的函式庫,始終適用於 MATLAB 安裝。如果 MCR 提供,則適用於 MCR 安裝。

Matlab_MX_LIBRARY

Matlab 的 mx 函式庫 (陣列),始終適用於 MATLAB 安裝。如果 MCR 提供,則適用於 MCR 安裝。

Matlab_ENG_LIBRARY

Matlab 引擎函式庫。僅當請求 ENG_LIBRARY 組件時可用。

Matlab_MAT_LIBRARY

Matlab 矩陣函式庫。僅當請求 MAT_LIBRARY 組件時可用。

Matlab_ENGINE_LIBRARY

版本 3.13 新增。

Matlab C++ 引擎函式庫,始終適用於 MATLAB R2018a 及更新版本。如果 MCR 提供,則適用於 MCR 安裝。

Matlab_DATAARRAY_LIBRARY

版本 3.13 新增。

Matlab C++ 資料陣列函式庫,始終適用於 MATLAB R2018a 及更新版本。如果 MCR 提供,則適用於 MCR 安裝。

Matlab_LIBRARIES

Matlab 的整組函式庫

Matlab_MEX_COMPILER

Matlab 的 mex 編譯器。目前未使用。僅當請求 MEX_COMPILER 組件時可用。

Matlab_MCC_COMPILER

版本 3.13 新增。

Matlab 的 mcc 編譯器。包含在 Matlab Compiler 附加元件中。僅當請求 MCC_COMPILER 組件時可用。

快取變數

Matlab_MEX_EXTENSION

目前平台的 mex 檔案的擴充功能 (由 Matlab 給定)。

Matlab_ROOT_DIR

找到的 Matlab 安裝的根目錄位置。如果使用者變更此值,則會重新計算結果變數。

提供的指令

matlab_get_version_from_release_name()

從 Matlab 發行版本名稱回傳版本

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 目標中的符號衝突

預設情況下,使用指令 matlab_add_mex() 定義的 MEX 檔案內部的每個符號都具有隱藏的可見性,除了進入點之外。這是 MEX 編譯器的預設行為,它降低了 Matlab 隨附的函式庫與 MEX 檔案連結到的函式庫之間發生符號衝突的風險。這也是 Windows 平台上的預設行為。

但是,在某些情況下,這是不夠的,例如,您的 MEX 檔案連結到 Matlab 已載入的函式庫,即使這些函式庫具有不同的 SONAME。可能的解決方案是隱藏 MEX 目標連結到的函式庫的符號。這可以使用連結器選項 -Wl,--exclude-libs,ALL 在 GNU GCC 編譯器中實現。

使用 GPU 資源的測試

在您的 MEX 檔案使用 GPU 的情況下,為了能夠在此 MEX 檔案上執行單元測試,GPU 資源應由 Matlab 正確釋放。可能的解決方案是讓 Matlab 知道在會話中使用 GPU 資源,這可以透過命令 (例如測試腳本開頭的 D = gpuDevice()) 或透過 fixture 來執行。

參考

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
matlab_get_version_from_release_name(release version)
  • 輸入:release 是發行版本名稱 (例如 R2023b)

  • 輸出:version 是 Matlab 的版本 (例如 23.2.0)

從發行版本名稱回傳 Matlab 的版本

注意

此指令為 Matlab 提供正確的版本對應,但不為 MCR 提供。

matlab_get_release_name_from_version
matlab_get_release_name_from_version(version release_name)
  • 輸入:version 是 Matlab 的版本 (例如 23.2.0)

  • 輸出:release_name 是發行版本名稱 (R2023b)

從 Matlab 版本回傳發行版本名稱

注意

此指令為 Matlab 提供正確的版本對應,但不為 MCR 提供。

matlab_extract_all_installed_versions_from_registry

此函數剖析 Windows 登錄檔,並尋找已安裝的 Matlab 版本。找到的版本儲存在給定的 <versions-var> 中。

matlab_extract_all_installed_versions_from_registry(<versions-var> [REGISTRY_VIEW view])

版本 3.30 新增。

  • 輸出:<versions-var> 是找到的所有 Matlab 版本的清單

  • 輸入:REGISTRY_VIEW 用於登錄檔互動的可選登錄檢視。參數會傳遞 (或省略) 到 cmake_host_system_information(),而無需進一步檢查或修改。

matlab_extract_all_installed_versions_from_registry(<win64> <versions-var>)
  • 輸入:win64 是一個布林值,用於搜尋 64 位元版本的 Matlab。設定為 ON 以使用 64 位元登錄檢視,或設定為 OFF 以使用 32 位元登錄檢視。如果需要更精細的控制,請參閱上面的簽章。

  • 輸出:<versions-var> 是找到的所有 Matlab 版本的清單

回傳的清單包含 HKLM\SOFTWARE\Mathworks\MATLABHKLM\SOFTWARE\Mathworks\MATLAB RuntimeHKLM\SOFTWARE\Mathworks\MATLAB Compiler Runtime 下的所有版本,或者如果發生錯誤 (或找不到任何內容),則為空清單。

注意

僅提供版本。不檢查登錄檔中引用的安裝是否存在,

matlab_get_all_valid_matlab_roots_from_registry

使用有效的 Matlab 或 Matlab Runtime (MCR) 版本填入 Matlab 根目錄。回傳的 matlab_roots 以三元組 (type,version_number,matlab_root_path) 組織,其中 type 指示 MATLABMCR

matlab_get_all_valid_matlab_roots_from_registry(matlab_versions matlab_roots [REGISTRY_VIEW view])
  • 輸入:每個 Matlab 或 MCR 安裝的 matlab_versions

  • 輸出:每個 Matlab 或 MCR 安裝的 matlab_roots 位置

  • 輸入:REGISTRY_VIEW 用於登錄檔互動的可選登錄檢視。參數會傳遞 (或省略) 到 cmake_host_system_information(),而無需進一步檢查或修改。

版本 3.30 新增:新增了可選的 REGISTRY_VIEW 參數,以提供更精確的介面來描述如何與 Windows 登錄檔互動。

matlab_get_mex_suffix

回傳 mex 檔案的擴充功能 (後綴)。不應在找到適當的 Matlab 根目錄之前呼叫此函數。

matlab_get_mex_suffix(matlab_root mex_suffix)
  • 輸入:Matlab/MCR 安裝的 matlab_root 根目錄,例如 Matlab_ROOT_DIR

  • 輸出:將在其中回傳後綴的 mex_suffix 變數名稱。

matlab_get_version_from_matlab_run

此函數執行在引數上指定的 Matlab 程式,並擷取其版本。如果為 Matlab 安裝提供的路徑指向 MCR 安裝,則從已安裝的檔案中擷取版本。

matlab_get_version_from_matlab_run(matlab_binary_path matlab_list_versions)
  • 輸入:matlab 二進制可執行檔的路徑 matlab_binary_path

  • 輸出:從 Matlab 擷取的版本 matlab_list_versions

matlab_add_unit_test

將 Matlab 單元測試新增到 cmake/ctest 的測試集。此指令需要組件 MAIN_PROGRAM,因此不適用於 MCR 安裝。

除非給定選項 NO_UNITTEST_FRAMEWORK,否則單元測試使用 Matlab unittest 框架 (預設,從 Matlab 2013b+ 開始可用)。

此函數預期給定一個 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]
    )

函數參數

NAME

ctest 中 unittest 的名稱。

UNITTEST_FILE

matlab unittest 檔案。其路徑將自動新增到 Matlab 路徑。

CUSTOM_TEST_COMMAND

要作為測試執行的 Matlab 腳本指令。如果未設定此項,則會執行以下操作:runtests('matlab_file_name'), exit(max([ans(1,:).Failed])),其中 matlab_file_name 是不含擴充功能的 UNITTEST_FILE

UNITTEST_PRECOMMAND

在包含測試的檔案之前要執行的 Matlab 腳本指令 (例如,基於 CMake 變數的 GPU 裝置初始化)。

TIMEOUT

測試逾時 (秒)。預設值為 180 秒,因為 Matlab 單元測試可能會掛起。

ADDITIONAL_PATH

要在執行單元測試之前新增到 Matlab 路徑的路徑清單。

MATLAB_ADDITIONAL_STARTUP_OPTIONS

為了從命令列執行 Matlab 的其他選項清單。-nosplash -nodesktop -nodisplay 始終會新增。

TEST_ARGS

提供給 add_test 指令的其他選項。這些選項會新增到預設選項 (例如 "CONFIGURATIONS Release")。

NO_UNITTEST_FRAMEWORK

設定後,表示測試不應使用 Matlab 的 unittest 框架 (適用於版本 >= R2013a)。

WORKING_DIRECTORY

這將是測試的工作目錄。如果指定,它也將是測試執行日誌檔案所使用的輸出目錄。如果未指定,則臨時目錄 ${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]
    [...]
)

函數參數

NAME

目標的名稱。

SRC

來源檔案清單。

LINK_TO

其他連結相依性的清單。目標預設連結到 libmexlibmx,除非傳遞 NO_IMPLICIT_LINK_TO_MATLAB_LIBRARIES 選項。

OUTPUT_NAME

如果給定,則覆寫預設名稱。預設名稱是沒有任何前綴且具有 Matlab_MEX_EXTENSION 後綴的目標名稱。

DOCUMENTATION

如果給定,檔案 file.txt 將被視為 MEX 檔案的文件檔案。此檔案會複製到同一個資料夾中,不進行任何處理,名稱與最終 mex 檔案相同,且擴充功能為 .m。在這種情況下,在 Matlab 中輸入 help <name> 會印出此檔案中包含的文件。

R2017bR2018a

版本 3.14 新增。

可以給定以指定要使用的 C API 版本:R2017b 指定傳統的 (獨立複數) C API,並對應於 mex 指令的 -R2017b 旗標。R2018a 指定新的交錯複數 C API,並對應於 mex 指令的 -R2018a 旗標。如果 MATLAB 版本早於 R2018a,則忽略。預設值為 R2017b

MODULESHARED

版本 3.7 新增。

可以給定以指定要建立的函式庫類型。

EXECUTABLE

版本 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)