I am trying to setup a CMakeLists.txt
under Windows to compile matlab-mex-files. But I struggle with find_package(Matlab)
to select the correct version.
I am using cmake 3.26.4 under Windows 10. I have matlab versions 8.2, 9.3, 9.12, and 9.13 installed.
My CMakeLists.txt
looks as follows
cmake_minimum_required(VERSION 3.26)
project(MatlabMex)
set(MATLAB_FIND_DEBUG ON)
find_package(Matlab 9.3 EXACT REQUIRED)
matlab_extract_all_installed_versions_from_registry(TRUE matlab_versions)
matlab_get_all_valid_matlab_roots_from_registry("${matlab_versions}" matlab_roots)
message("${matlab_roots}")
IF(MATLAB_FOUND)
matlab_get_release_name_from_version(${Matlab_VERSION_STRING} Matlab_release)
message(STATUS "Matlab found: ${Matlab_release}")
ELSE(MATLAB_FOUND)
message("Matlab not found")
ENDIF(MATLAB_FOUND)
The debug output of FindMatlab provides:
-- [MATLAB] Matlab root folders are UNKNOWN;9.13;C:/Program Files/MATLAB/R2022b
-- [MATLAB] Current version is 9.13 located C:/Program Files/MATLAB/R2022b
-- [MATLAB] [DEBUG]_matlab_lib_prefix_for_search = lib | _matlab_lib_dir_for_search = C:/Program Files/MATLAB/R2022b/extern/lib/win64/mingw64
When using the EXACT
in find_package
I then get the error, that no suitable version can be found:
Could NOT find Matlab: Found unsuitable version "9.13", but required is
exact version "9.3" (found C:/Program Files/MATLAB/R2022b/extern/include, )
However, when I omit EXACT
, it selects 9.13 and runs the two macros to retrieve the information from the registry. This yields the following, which clearly includes all installed versions.
MATLAB;9.13;C:/Program Files/MATLAB/R2022b;MATLAB;9.12;C:/Program Files/MATLAB/R2022a;MATLAB;9.3;C:/Program Files/MATLAB/R2017b;MATLAB;8.2;C:/Program Files/MATLAB/R2013b
So now the question: Why does FindMatlab not find all versions in the first place and selects my desired 9.3?
I came across two issues, which seem to relate, but are solved a long time ago:
For now I consider a user error rather than a cmake issue.
It turned out to be a user error or at least a misunderstanding of how cmake works ;-)
Thank you @Tsyvarev for bringing me on the right track.
Tight Scope to original Question
FindMatlab.cmake only searches for Matlab instances if Matlab_ROOT_DIR
is not set. But cmake caches the value as it is the normal behavior of cmake (once again thanks to @Tsyvarev). So after my first tests the value for version 9.13 was in the cache and no subsequent runs of cmake performed a new search during find_package
. The other calls still worked fine and thus returned the list of all installed matlab versions.
So make sure to clear the cache for every new test.
Extended Thoughts
If you want to change the matlab version to compile for, the best option I found is to have a specific build directory for each matlab version.
With a CMakeLists.txt
like the following
cmake_minimum_required(VERSION 3.26)
project(MatlabMex)
find_package(Matlab ${MATLAB_VERSION} EXACT REQUIRED)
one could run
cmake . -b build_2017b -DMATLAB_VERSION="9.3"
cmake --build build_2017b
or
cmake . -b build_2022b -DMATLAB_VERSION="9.13"
cmake --build build_2022b
Using different versions in one CMakeLists.txt
This Link suggests the usage of multiple version in the same CMakeLists.txt
. But this does not seem to work, because the first call to find_package specifies Matlab_ROOT_DIRĀ“, which will make the next call not work. Even after clearing
Matlab_ROOT_DIRin between, did not work for me. The correct matlab version was then found, but cmake complained about multiple targets with the same name. I have to admit that I tested without the
foreach`, which might add a new scope. But this topic anyway is not really part of the original question anymore. I only wanted to include some remarks as I brought it up in the comments of the original question.