|
| 1 | +# ----- Find Matlab/Octave ----- |
| 2 | +# |
| 3 | +# OpenCVFindMatlab.cmake attempts to locate the install path of Matlab in order |
| 4 | +# to extract the mex headers, libraries and shell scripts. If found |
| 5 | +# successfully, the following variables will be defined |
| 6 | +# |
| 7 | +# MATLAB_FOUND: true/false |
| 8 | +# MATLAB_ROOT_DIR: Root of Matlab installation |
| 9 | +# MATLAB_BIN: The main Matlab "executable" (shell script) |
| 10 | +# MATLAB_MEX_SCRIPT: The mex script used to compile mex files |
| 11 | +# MATLAB_INCLUDE_DIRS:Path to "mex.h" |
| 12 | +# MATLAB_LIBRARY_DIRS:Path to mex and matrix libraries |
| 13 | +# MATLAB_LIBRARIES: The Matlab libs, usually mx, mex, mat |
| 14 | +# MATLAB_MEXEXT: The mex library extension. It will be one of: |
| 15 | +# mexwin32, mexwin64, mexglx, mexa64, mexmac, |
| 16 | +# mexmaci, mexmaci64, mexsol, mexs64 |
| 17 | +# MATLAB_ARCH: The installation architecture. It is **usually** |
| 18 | +# the MEXEXT with the preceding "mex" removed, |
| 19 | +# though it's different for linux distros. |
| 20 | +# |
| 21 | +# There doesn't appear to be an elegant way to detect all versions of Matlab |
| 22 | +# across different platforms. If you know the matlab path and want to avoid |
| 23 | +# the search, you can define the path to the Matlab root when invoking cmake: |
| 24 | +# |
| 25 | +# cmake -DMATLAB_ROOT_DIR='/PATH/TO/ROOT_DIR' .. |
| 26 | + |
| 27 | +# ----- set_library_presuffix ----- |
| 28 | +# |
| 29 | +# Matlab tends to use some non-standard prefixes and suffixes on its libraries. |
| 30 | +# For example, libmx.dll on Windows (Windows does not add prefixes) and |
| 31 | +# mkl.dylib on OS X (OS X uses "lib" prefixes). |
| 32 | +# On some versions of Windows the .dll suffix also appears to not be checked. |
| 33 | +# |
| 34 | +# This function modifies the library prefixes and suffixes used by |
| 35 | +# find_library when finding Matlab libraries. It does not affect scopes |
| 36 | +# outside of this file. |
| 37 | +function(set_libarch_prefix_suffix) |
| 38 | + if (UNIX AND NOT APPLE) |
| 39 | + set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
| 40 | + set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a" PARENT_SCOPE) |
| 41 | + elseif (APPLE) |
| 42 | + set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
| 43 | + set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".a" PARENT_SCOPE) |
| 44 | + elseif (WIN32) |
| 45 | + set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE) |
| 46 | + set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll" PARENT_SCOPE) |
| 47 | + endif() |
| 48 | +endfunction() |
| 49 | + |
| 50 | + |
| 51 | + |
| 52 | +# ----- locate_matlab_root ----- |
| 53 | +# |
| 54 | +# Attempt to find the path to the Matlab installation. If successful, sets |
| 55 | +# the absolute path in the variable MATLAB_ROOT_DIR |
| 56 | +function(locate_matlab_root) |
| 57 | + |
| 58 | + # --- UNIX/APPLE --- |
| 59 | + if (UNIX) |
| 60 | + # possible root locations, in order of likelihood |
| 61 | + set(SEARCH_DIRS_ /Applications /usr/local /opt/local /usr /opt) |
| 62 | + foreach (DIR_ ${SEARCH_DIRS_}) |
| 63 | + file(GLOB MATLAB_ROOT_DIR_ ${DIR_}/MATLAB/R* ${DIR_}/MATLAB_R*) |
| 64 | + if (MATLAB_ROOT_DIR_) |
| 65 | + # sort in order from highest to lowest |
| 66 | + # normally it's in the format MATLAB_R[20XX][A/B] |
| 67 | + # TODO: numerical rather than lexicographic sort. However, |
| 68 | + # CMake does not support floating-point MATH(EXPR ...) at this time. |
| 69 | + list(SORT MATLAB_ROOT_DIR_) |
| 70 | + list(REVERSE MATLAB_ROOT_DIR_) |
| 71 | + list(GET MATLAB_ROOT_DIR_ 0 MATLAB_ROOT_DIR_) |
| 72 | + set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE) |
| 73 | + return() |
| 74 | + endif() |
| 75 | + endforeach() |
| 76 | + |
| 77 | + # --- WINDOWS --- |
| 78 | + elseif (WIN32) |
| 79 | + # 1. search the path environment variable |
| 80 | + find_program(MATLAB_ROOT_DIR_ matlab PATHS ENV PATH) |
| 81 | + if (MATLAB_ROOT_DIR_) |
| 82 | + # get the root directory from the full path |
| 83 | + # /path/to/matlab/rootdir/bin/matlab.exe |
| 84 | + get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH) |
| 85 | + get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH) |
| 86 | + set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE) |
| 87 | + return() |
| 88 | + endif() |
| 89 | + |
| 90 | + # 2. search the registry |
| 91 | + # determine the available Matlab versions |
| 92 | + set(REG_EXTENSION_ "SOFTWARE\\Mathworks\\MATLAB") |
| 93 | + set(REG_ROOTS_ "HKEY_LOCAL_MACHINE" "HKEY_CURRENT_USER") |
| 94 | + foreach(REG_ROOT_ ${REG_ROOTS_}) |
| 95 | + execute_process(COMMAND reg query "${REG_ROOT_}\\${REG_EXTENSION_}" OUTPUT_VARIABLE QUERY_RESPONSE_ ERROR_VARIABLE UNUSED_) |
| 96 | + if (QUERY_RESPONSE_) |
| 97 | + string(REGEX MATCHALL "[0-9]\\.[0-9]" VERSION_STRINGS_ ${QUERY_RESPONSE_}) |
| 98 | + list(APPEND VERSIONS_ ${VERSION_STRINGS_}) |
| 99 | + endif() |
| 100 | + endforeach() |
| 101 | + |
| 102 | + # select the highest version |
| 103 | + list(APPEND VERSIONS_ "0.0") |
| 104 | + list(SORT VERSIONS_) |
| 105 | + list(REVERSE VERSIONS_) |
| 106 | + list(GET VERSIONS_ 0 VERSION_) |
| 107 | + |
| 108 | + # request the MATLABROOT from the registry |
| 109 | + foreach(REG_ROOT_ ${REG_ROOTS_}) |
| 110 | + get_filename_component(QUERY_RESPONSE_ [${REG_ROOT_}\\${REG_EXTENSION_}\\${VERSION_};MATLABROOT] ABSOLUTE) |
| 111 | + if (NOT ${QUERY_RESPONSE_} MATCHES "registry$") |
| 112 | + set(MATLAB_ROOT_DIR ${QUERY_RESPONSE_} PARENT_SCOPE) |
| 113 | + return() |
| 114 | + endif() |
| 115 | + endforeach() |
| 116 | + endif() |
| 117 | +endfunction() |
| 118 | + |
| 119 | + |
| 120 | + |
| 121 | +# ----- locate_matlab_components ----- |
| 122 | +# |
| 123 | +# Given a directory MATLAB_ROOT_DIR, attempt to find the Matlab components |
| 124 | +# (include directory and libraries) under the root. If everything is found, |
| 125 | +# sets the variable MATLAB_FOUND to TRUE |
| 126 | +function(locate_matlab_components MATLAB_ROOT_DIR) |
| 127 | + # get the mex extension |
| 128 | + find_file(MATLAB_MEXEXT_SCRIPT_ NAMES mexext mexext.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
| 129 | + execute_process(COMMAND ${MATLAB_MEXEXT_SCRIPT_} |
| 130 | + OUTPUT_VARIABLE MATLAB_MEXEXT_ |
| 131 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 132 | + if (NOT MATLAB_MEXEXT_) |
| 133 | + return() |
| 134 | + endif() |
| 135 | + |
| 136 | + # map the mexext to an architecture extension |
| 137 | + set(ARCHITECTURES_ "maci64" "maci" "glnxa64" "glnx64" "sol64" "sola64" "win32" "win64" ) |
| 138 | + foreach(ARCHITECTURE_ ${ARCHITECTURES_}) |
| 139 | + if(EXISTS ${MATLAB_ROOT_DIR}/bin/${ARCHITECTURE_}) |
| 140 | + set(MATLAB_ARCH_ ${ARCHITECTURE_}) |
| 141 | + break() |
| 142 | + endif() |
| 143 | + endforeach() |
| 144 | + |
| 145 | + # get the path to the libraries |
| 146 | + set(MATLAB_LIBRARY_DIRS_ ${MATLAB_ROOT_DIR}/bin/${MATLAB_ARCH_}) |
| 147 | + |
| 148 | + # get the libraries |
| 149 | + set_libarch_prefix_suffix() |
| 150 | + find_library(MATLAB_LIB_MX_ mx PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
| 151 | + find_library(MATLAB_LIB_MEX_ mex PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
| 152 | + find_library(MATLAB_LIB_MAT_ mat PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH) |
| 153 | + set(MATLAB_LIBRARIES_ ${MATLAB_LIB_MX_} ${MATLAB_LIB_MEX_} ${MATLAB_LIB_MAT_}) |
| 154 | + |
| 155 | + # get the include path |
| 156 | + find_path(MATLAB_INCLUDE_DIRS_ mex.h ${MATLAB_ROOT_DIR}/extern/include) |
| 157 | + |
| 158 | + # get the mex shell script |
| 159 | + find_program(MATLAB_MEX_SCRIPT_ NAMES mex mex.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
| 160 | + |
| 161 | + # get the Matlab executable |
| 162 | + find_program(MATLAB_BIN_ NAMES matlab PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH) |
| 163 | + |
| 164 | + # export into parent scope |
| 165 | + if (MATLAB_MEX_SCRIPT_ AND MATLAB_LIBRARIES_ AND MATLAB_INCLUDE_DIRS_) |
| 166 | + set(MATLAB_BIN ${MATLAB_BIN_} PARENT_SCOPE) |
| 167 | + set(MATLAB_MEX_SCRIPT ${MATLAB_MEX_SCRIPT_} PARENT_SCOPE) |
| 168 | + set(MATLAB_INCLUDE_DIRS ${MATLAB_INCLUDE_DIRS_} PARENT_SCOPE) |
| 169 | + set(MATLAB_LIBRARIES ${MATLAB_LIBRARIES_} PARENT_SCOPE) |
| 170 | + set(MATLAB_LIBRARY_DIRS ${MATLAB_LIBRARY_DIRS_} PARENT_SCOPE) |
| 171 | + set(MATLAB_MEXEXT ${MATLAB_MEXEXT_} PARENT_SCOPE) |
| 172 | + set(MATLAB_ARCH ${MATLAB_ARCH_} PARENT_SCOPE) |
| 173 | + endif() |
| 174 | +endfunction() |
| 175 | + |
| 176 | + |
| 177 | + |
| 178 | +# ---------------------------------------------------------------------------- |
| 179 | +# FIND MATLAB COMPONENTS |
| 180 | +# ---------------------------------------------------------------------------- |
| 181 | +if (NOT MATLAB_FOUND) |
| 182 | + |
| 183 | + # attempt to find the Matlab root folder |
| 184 | + if (NOT MATLAB_ROOT_DIR) |
| 185 | + locate_matlab_root() |
| 186 | + endif() |
| 187 | + |
| 188 | + # given the matlab root folder, find the library locations |
| 189 | + if (MATLAB_ROOT_DIR) |
| 190 | + locate_matlab_components(${MATLAB_ROOT_DIR}) |
| 191 | + endif() |
| 192 | + find_package_handle_standard_args(Matlab DEFAULT_MSG |
| 193 | + MATLAB_MEX_SCRIPT MATLAB_INCLUDE_DIRS |
| 194 | + MATLAB_ROOT_DIR MATLAB_LIBRARIES |
| 195 | + MATLAB_LIBRARY_DIRS MATLAB_MEXEXT |
| 196 | + MATLAB_ARCH MATLAB_BIN) |
| 197 | +endif() |
0 commit comments