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