Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/3.4' into merge-3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
alalek committed Sep 17, 2018
2 parents da98966 + ff59193 commit 136baab
Show file tree
Hide file tree
Showing 4 changed files with 229 additions and 0 deletions.
3 changes: 3 additions & 0 deletions modules/matlab/CMakeLists.txt
Expand Up @@ -75,6 +75,9 @@ macro(WARN_MIXED_PRECISION COMPILER_BITNESS MATLAB_BITNESS)
message(WARNING ${MSG})
endmacro()

ocv_assert(DEFINED MATLAB_ARCH)
ocv_assert(DEFINED MATLAB_MEX_SCRIPT)
ocv_assert(DEFINED MATLAB_MEXEXT)

# If the user built OpenCV as X-bit, but they have a Y-bit version of Matlab,
# attempting to link to OpenCV during binding generation will fail, since
Expand Down
197 changes: 197 additions & 0 deletions modules/matlab/cmake/OpenCVFindMatlab.cmake
@@ -0,0 +1,197 @@
# ----- Find Matlab/Octave -----
#
# OpenCVFindMatlab.cmake attempts to locate the install path of Matlab in order
# to extract the mex headers, libraries and shell scripts. If found
# successfully, the following variables will be defined
#
# MATLAB_FOUND: true/false
# MATLAB_ROOT_DIR: Root of Matlab installation
# MATLAB_BIN: The main Matlab "executable" (shell script)
# MATLAB_MEX_SCRIPT: The mex script used to compile mex files
# MATLAB_INCLUDE_DIRS:Path to "mex.h"
# MATLAB_LIBRARY_DIRS:Path to mex and matrix libraries
# MATLAB_LIBRARIES: The Matlab libs, usually mx, mex, mat
# MATLAB_MEXEXT: The mex library extension. It will be one of:
# mexwin32, mexwin64, mexglx, mexa64, mexmac,
# mexmaci, mexmaci64, mexsol, mexs64
# MATLAB_ARCH: The installation architecture. It is **usually**
# the MEXEXT with the preceding "mex" removed,
# though it's different for linux distros.
#
# There doesn't appear to be an elegant way to detect all versions of Matlab
# across different platforms. If you know the matlab path and want to avoid
# the search, you can define the path to the Matlab root when invoking cmake:
#
# cmake -DMATLAB_ROOT_DIR='/PATH/TO/ROOT_DIR' ..

# ----- set_library_presuffix -----
#
# Matlab tends to use some non-standard prefixes and suffixes on its libraries.
# For example, libmx.dll on Windows (Windows does not add prefixes) and
# mkl.dylib on OS X (OS X uses "lib" prefixes).
# On some versions of Windows the .dll suffix also appears to not be checked.
#
# This function modifies the library prefixes and suffixes used by
# find_library when finding Matlab libraries. It does not affect scopes
# outside of this file.
function(set_libarch_prefix_suffix)
if (UNIX AND NOT APPLE)
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".so" ".a" PARENT_SCOPE)
elseif (APPLE)
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".a" PARENT_SCOPE)
elseif (WIN32)
set(CMAKE_FIND_LIBRARY_PREFIXES "lib" PARENT_SCOPE)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib" ".dll" PARENT_SCOPE)
endif()
endfunction()



# ----- locate_matlab_root -----
#
# Attempt to find the path to the Matlab installation. If successful, sets
# the absolute path in the variable MATLAB_ROOT_DIR
function(locate_matlab_root)

# --- UNIX/APPLE ---
if (UNIX)
# possible root locations, in order of likelihood
set(SEARCH_DIRS_ /Applications /usr/local /opt/local /usr /opt)
foreach (DIR_ ${SEARCH_DIRS_})
file(GLOB MATLAB_ROOT_DIR_ ${DIR_}/MATLAB/R* ${DIR_}/MATLAB_R*)
if (MATLAB_ROOT_DIR_)
# sort in order from highest to lowest
# normally it's in the format MATLAB_R[20XX][A/B]
# TODO: numerical rather than lexicographic sort. However,
# CMake does not support floating-point MATH(EXPR ...) at this time.
list(SORT MATLAB_ROOT_DIR_)
list(REVERSE MATLAB_ROOT_DIR_)
list(GET MATLAB_ROOT_DIR_ 0 MATLAB_ROOT_DIR_)
set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE)
return()
endif()
endforeach()

# --- WINDOWS ---
elseif (WIN32)
# 1. search the path environment variable
find_program(MATLAB_ROOT_DIR_ matlab PATHS ENV PATH)
if (MATLAB_ROOT_DIR_)
# get the root directory from the full path
# /path/to/matlab/rootdir/bin/matlab.exe
get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH)
get_filename_component(MATLAB_ROOT_DIR_ ${MATLAB_ROOT_DIR_} PATH)
set(MATLAB_ROOT_DIR ${MATLAB_ROOT_DIR_} PARENT_SCOPE)
return()
endif()

# 2. search the registry
# determine the available Matlab versions
set(REG_EXTENSION_ "SOFTWARE\\Mathworks\\MATLAB")
set(REG_ROOTS_ "HKEY_LOCAL_MACHINE" "HKEY_CURRENT_USER")
foreach(REG_ROOT_ ${REG_ROOTS_})
execute_process(COMMAND reg query "${REG_ROOT_}\\${REG_EXTENSION_}" OUTPUT_VARIABLE QUERY_RESPONSE_ ERROR_VARIABLE UNUSED_)
if (QUERY_RESPONSE_)
string(REGEX MATCHALL "[0-9]\\.[0-9]" VERSION_STRINGS_ ${QUERY_RESPONSE_})
list(APPEND VERSIONS_ ${VERSION_STRINGS_})
endif()
endforeach()

# select the highest version
list(APPEND VERSIONS_ "0.0")
list(SORT VERSIONS_)
list(REVERSE VERSIONS_)
list(GET VERSIONS_ 0 VERSION_)

# request the MATLABROOT from the registry
foreach(REG_ROOT_ ${REG_ROOTS_})
get_filename_component(QUERY_RESPONSE_ [${REG_ROOT_}\\${REG_EXTENSION_}\\${VERSION_};MATLABROOT] ABSOLUTE)
if (NOT ${QUERY_RESPONSE_} MATCHES "registry$")
set(MATLAB_ROOT_DIR ${QUERY_RESPONSE_} PARENT_SCOPE)
return()
endif()
endforeach()
endif()
endfunction()



# ----- locate_matlab_components -----
#
# Given a directory MATLAB_ROOT_DIR, attempt to find the Matlab components
# (include directory and libraries) under the root. If everything is found,
# sets the variable MATLAB_FOUND to TRUE
function(locate_matlab_components MATLAB_ROOT_DIR)
# get the mex extension
find_file(MATLAB_MEXEXT_SCRIPT_ NAMES mexext mexext.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH)
execute_process(COMMAND ${MATLAB_MEXEXT_SCRIPT_}
OUTPUT_VARIABLE MATLAB_MEXEXT_
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT MATLAB_MEXEXT_)
return()
endif()

# map the mexext to an architecture extension
set(ARCHITECTURES_ "maci64" "maci" "glnxa64" "glnx64" "sol64" "sola64" "win32" "win64" )
foreach(ARCHITECTURE_ ${ARCHITECTURES_})
if(EXISTS ${MATLAB_ROOT_DIR}/bin/${ARCHITECTURE_})
set(MATLAB_ARCH_ ${ARCHITECTURE_})
break()
endif()
endforeach()

# get the path to the libraries
set(MATLAB_LIBRARY_DIRS_ ${MATLAB_ROOT_DIR}/bin/${MATLAB_ARCH_})

# get the libraries
set_libarch_prefix_suffix()
find_library(MATLAB_LIB_MX_ mx PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH)
find_library(MATLAB_LIB_MEX_ mex PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH)
find_library(MATLAB_LIB_MAT_ mat PATHS ${MATLAB_LIBRARY_DIRS_} NO_DEFAULT_PATH)
set(MATLAB_LIBRARIES_ ${MATLAB_LIB_MX_} ${MATLAB_LIB_MEX_} ${MATLAB_LIB_MAT_})

# get the include path
find_path(MATLAB_INCLUDE_DIRS_ mex.h ${MATLAB_ROOT_DIR}/extern/include)

# get the mex shell script
find_program(MATLAB_MEX_SCRIPT_ NAMES mex mex.bat PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH)

# get the Matlab executable
find_program(MATLAB_BIN_ NAMES matlab PATHS ${MATLAB_ROOT_DIR}/bin NO_DEFAULT_PATH)

# export into parent scope
if (MATLAB_MEX_SCRIPT_ AND MATLAB_LIBRARIES_ AND MATLAB_INCLUDE_DIRS_)
set(MATLAB_BIN ${MATLAB_BIN_} PARENT_SCOPE)
set(MATLAB_MEX_SCRIPT ${MATLAB_MEX_SCRIPT_} PARENT_SCOPE)
set(MATLAB_INCLUDE_DIRS ${MATLAB_INCLUDE_DIRS_} PARENT_SCOPE)
set(MATLAB_LIBRARIES ${MATLAB_LIBRARIES_} PARENT_SCOPE)
set(MATLAB_LIBRARY_DIRS ${MATLAB_LIBRARY_DIRS_} PARENT_SCOPE)
set(MATLAB_MEXEXT ${MATLAB_MEXEXT_} PARENT_SCOPE)
set(MATLAB_ARCH ${MATLAB_ARCH_} PARENT_SCOPE)
endif()
endfunction()



# ----------------------------------------------------------------------------
# FIND MATLAB COMPONENTS
# ----------------------------------------------------------------------------
if (NOT MATLAB_FOUND)

# attempt to find the Matlab root folder
if (NOT MATLAB_ROOT_DIR)
locate_matlab_root()
endif()

# given the matlab root folder, find the library locations
if (MATLAB_ROOT_DIR)
locate_matlab_components(${MATLAB_ROOT_DIR})
endif()
find_package_handle_standard_args(Matlab DEFAULT_MSG
MATLAB_MEX_SCRIPT MATLAB_INCLUDE_DIRS
MATLAB_ROOT_DIR MATLAB_LIBRARIES
MATLAB_LIBRARY_DIRS MATLAB_MEXEXT
MATLAB_ARCH MATLAB_BIN)
endif()
9 changes: 9 additions & 0 deletions modules/matlab/cmake/hooks/STATUS_DUMP_EXTRA.cmake
@@ -0,0 +1,9 @@
# ========================= matlab =========================
if(WITH_MATLAB OR MATLAB_FOUND)
status("")
status(" Matlab:" MATLAB_FOUND THEN "YES" ELSE "NO")
if(MATLAB_FOUND)
status(" mex:" MATLAB_MEX_SCRIPT THEN "${MATLAB_MEX_SCRIPT}" ELSE NO)
status(" Compiler/generator:" MEX_WORKS THEN "Working" ELSE "Not working (bindings will not be generated)")
endif()
endif()
20 changes: 20 additions & 0 deletions modules/matlab/cmake/init.cmake
@@ -0,0 +1,20 @@
OCV_OPTION(WITH_MATLAB "Include Matlab support (opencv_contrib)" OFF IF (NOT ANDROID AND NOT IOS AND NOT WINRT))

ocv_assert(OPENCV_INITIAL_PASS)

if(WITH_MATLAB OR DEFINED MATLAB_FOUND)
ocv_cmake_hook_append(STATUS_DUMP_EXTRA "${CMAKE_CURRENT_LIST_DIR}/hooks/STATUS_DUMP_EXTRA.cmake")
endif()

# --- Matlab/Octave ---
if(WITH_MATLAB AND NOT DEFINED MATLAB_FOUND)
include(${CMAKE_CURRENT_LIST_DIR}/OpenCVFindMatlab.cmake)
if(NOT MATLAB_FOUND)
message(WARNING "Matlab or compiler (mex) was not found. Disabling Matlab bindings...")
ocv_module_disable(matlab)
endif()

# publish vars for status() dumper
set(MATLAB_FOUND "${MATLAB_FOUND}" PARENT_SCOPE)
set(MATLAB_MEX_SCRIPT "${MATLAB_MEX_SCRIPT}" PARENT_SCOPE)
endif()

0 comments on commit 136baab

Please sign in to comment.