Merge topic 'FindMatlab-2018a-API'

42731e94be FindMatlab: Fix linker command under Windows.
ee73e733e4 FindMatlab: Fix compilation error in one specific test configuration.
160499296c FindMatlab: added unit tests for new functionality.
ee7e97a7d3 FindMatlab: add change log item.
d7e19032d5 FindMatlab: `matlab_add_mex` has new options `R2017b` and `R2018a`.
518553d953 FindMatlab: Always find core libraries.

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !2508
This commit is contained in:
Brad King
2018-10-30 14:55:43 +00:00
committed by Kitware Robot
11 changed files with 328 additions and 128 deletions

View File

@@ -0,0 +1,7 @@
FindMatlab-2018a-API
--------------------
* The :module:`FindMatlab` module gained new options ``R2017b`` and
``R2018a`` to specify the MEX API version to use; these options
mirror the new options to the ``mex`` command in MATLAB R2018a.
The option ``MX_LIBRARY`` is no longer needed.

View File

@@ -19,10 +19,8 @@ can also be used:
The module supports the following components:
* ``MX_LIBRARY``, ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``MX``,
``ENG`` and ``MAT`` libraries of Matlab
* ``ENGINE_LIBRARY``, ``DATAARRAY_LIBRARY``: respectively the ``MatlabEngine``
and ``MatlabDataArray`` libraries of Matlab (Matlab 2018a and later)
* ``ENG_LIBRARY`` and ``MAT_LIBRARY``: respectively the ``ENG`` and ``MAT``
libraries of Matlab
* ``MAIN_PROGRAM`` the Matlab binary program. Note that this component is not
available on the MCR version, and will yield an error if the MCR is found
instead of the regular Matlab installation.
@@ -101,8 +99,7 @@ Result variables
``Matlab_MEX_LIBRARY``
library for mex, always available.
``Matlab_MX_LIBRARY``
mx library of Matlab (arrays). Available only if the component
``MX_LIBRARY`` has been requested.
mx library of Matlab (arrays), always available.
``Matlab_ENG_LIBRARY``
Matlab engine library. Available only if the component ``ENG_LIBRARY``
is requested.
@@ -110,11 +107,9 @@ Result variables
Matlab matrix library. Available only if the component ``MAT_LIBRARY``
is requested.
``Matlab_ENGINE_LIBRARY``
Matlab C++ engine library. Available only if the component ``ENGINE_LIBRARY``
is requested.
Matlab C++ engine library, always available for R2018a and newer.
``Matlab_DATAARRAY_LIBRARY``
Matlab C++ data array library. Available only if the component ``DATAARRAY_LIBRARY``
is requested.
Matlab C++ data array library, always available for R2018a and newer.
``Matlab_LIBRARIES``
the whole set of libraries of Matlab
``Matlab_MEX_COMPILER``
@@ -889,6 +884,7 @@ endfunction()
[OUTPUT_NAME output_name]
[DOCUMENTATION file.txt]
[LINK_TO target1 target2 ...]
[R2017b | R2018a]
[...]
)
@@ -898,8 +894,7 @@ endfunction()
list of source files.
``LINK_TO``
a list of additional link dependencies. The target links to ``libmex``
by default. If ``Matlab_MX_LIBRARY`` is defined, it also
links to ``libmx``.
and ``libmx`` by default.
``OUTPUT_NAME``
if given, overrides the default name. The default name is
the name of the target without any prefix and
@@ -910,6 +905,12 @@ endfunction()
the same folder without any processing, with the same name as the final
mex file, and with extension `.m`. In that case, typing ``help <name>``
in Matlab prints the documentation contained in this file.
``R2017b`` or ``R2018a`` may be given to specify the version of the C API
to use: ``R2017b`` specifies the traditional (separate complex) C API,
and corresponds to the ``-R2017b`` flag for the `mex` command. ``R2018a``
specifies the new interleaved complex C API, and corresponds to the
``-R2018a`` flag for the `mex` command. Ignored if MATLAB version prior
to R2018a. Defaults to ``R2017b``.
``MODULE`` or ``SHARED`` may be given to specify the type of library to be
created. ``EXECUTABLE`` may be given to create an executable instead of
a library. If no type is given explicitly, the type is ``SHARED``.
@@ -939,7 +940,7 @@ function(matlab_add_mex)
endif()
set(options EXECUTABLE MODULE SHARED)
set(options EXECUTABLE MODULE SHARED R2017b R2018a)
set(oneValueArgs NAME DOCUMENTATION OUTPUT_NAME)
set(multiValueArgs LINK_TO SRC)
@@ -954,9 +955,25 @@ function(matlab_add_mex)
set(${prefix}_OUTPUT_NAME ${${prefix}_NAME})
endif()
if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.1") # For 9.1 (R2016b) and newer, add version source file
# TODO: check the file extensions in ${${prefix}_SRC} to see if they're C or C++ files
# Currently, the C and C++ versions of the version files are identical, so this doesn't matter.
set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/c_mexapi_version.c")
#set(MEX_VERSION_FILE "${Matlab_ROOT_DIR}/extern/version/cpp_mexapi_version.cpp")
endif()
if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.4") # For 9.4 (R2018a) and newer, add API macro
if(${${prefix}_R2018a})
set(MEX_API_MACRO "MATLAB_DEFAULT_RELEASE=R2018a")
else()
set(MEX_API_MACRO "MATLAB_DEFAULT_RELEASE=R2017b")
endif()
endif()
if(${prefix}_EXECUTABLE)
add_executable(${${prefix}_NAME}
${${prefix}_SRC}
${MEX_VERSION_FILE}
${${prefix}_DOCUMENTATION}
${${prefix}_UNPARSED_ARGUMENTS})
else()
@@ -969,31 +986,25 @@ function(matlab_add_mex)
add_library(${${prefix}_NAME}
${type}
${${prefix}_SRC}
${MEX_VERSION_FILE}
${${prefix}_DOCUMENTATION}
${${prefix}_UNPARSED_ARGUMENTS})
endif()
target_include_directories(${${prefix}_NAME} PRIVATE ${Matlab_INCLUDE_DIRS})
if(DEFINED Matlab_MX_LIBRARY)
target_link_libraries(${${prefix}_NAME} ${Matlab_MX_LIBRARY})
if(Matlab_HAS_CPP_API)
target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY} ${Matlab_DATAARRAY_LIBRARY})
endif()
if(DEFINED Matlab_ENGINE_LIBRARY)
target_link_libraries(${${prefix}_NAME} ${Matlab_ENGINE_LIBRARY})
endif()
if(DEFINED Matlab_DATAARRAY_LIBRARY)
target_link_libraries(${${prefix}_NAME} ${Matlab_DATAARRAY_LIBRARY})
endif()
target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${${prefix}_LINK_TO})
target_link_libraries(${${prefix}_NAME} ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${${prefix}_LINK_TO})
set_target_properties(${${prefix}_NAME}
PROPERTIES
PREFIX ""
OUTPUT_NAME ${${prefix}_OUTPUT_NAME}
SUFFIX ".${Matlab_MEX_EXTENSION}")
target_compile_definitions(${${prefix}_NAME} PRIVATE ${MEX_API_MACRO} MATLAB_MEX_FILE)
# documentation
if(NOT ${${prefix}_DOCUMENTATION} STREQUAL "")
@@ -1007,82 +1018,82 @@ function(matlab_add_mex)
endif() # documentation
# entry point in the mex file + taking care of visibility and symbol clashes.
if (MSVC)
get_target_property(
_previous_link_flags
${${prefix}_NAME}
LINK_FLAGS)
if(NOT _previous_link_flags)
set(_previous_link_flags)
endif()
set_target_properties(${${prefix}_NAME}
PROPERTIES
LINK_FLAGS "${_previous_link_flags} /EXPORT:mexFunction")
endif()
if(WIN32)
if (MSVC)
set(_link_flags "${_link_flags} /EXPORT:mexFunction")
if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.1") # For 9.1 (R2016b) and newer, export version
set(_link_flags "${_link_flags} /EXPORT:mexfilerequiredapiversion")
endif()
if(Matlab_HAS_CPP_API)
set(_link_flags "${_link_flags} /EXPORT:mexCreateMexFunction /EXPORT:mexDestroyMexFunction /EXPORT:mexFunctionAdapter")
#TODO: Is this necessary?
endif()
set_property(TARGET ${${prefix}_NAME} APPEND PROPERTY LINK_FLAGS ${_link_flags})
endif() # TODO: what if there's a different compiler on Windows?
set_target_properties(${${prefix}_NAME}
PROPERTIES
DEFINE_SYMBOL "DLL_EXPORT_SYM=__declspec(dllexport)")
else()
if(HAS_MINUS_PTHREAD AND NOT APPLE)
# Apparently, compiling with -pthread generated the proper link flags
# and some defines at compilation
target_compile_options(${${prefix}_NAME} PRIVATE "-pthread")
if(${Matlab_VERSION_STRING} VERSION_LESS "9.1") # For versions prior to 9.1 (R2016b)
set(_ver_map_files ${Matlab_EXTERN_LIBRARY_DIR}/mexFunction.map)
else() # For 9.1 (R2016b) and newer
set(_ver_map_files ${Matlab_EXTERN_LIBRARY_DIR}/c_exportsmexfileversion.map)
endif()
if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.5") # For 9.5 (R2018b) (and newer?)
target_compile_options(${${prefix}_NAME} PRIVATE "-fvisibility=default")
# This one is weird, it might be a bug in <mex.h> for R2018b. When compiling with
# -fvisibility=hidden, the symbol `mexFunction` cannot be exported. Reading the
# source code for <mex.h>, it seems that the preprocessor macro `MW_NEEDS_VERSION_H`
# needs to be defined for `__attribute__ ((visibility("default")))` to be added
# in front of the declaration of `mexFunction`. In previous versions of MATLAB this
# was not the case, there `DLL_EXPORT_SYM` needed to be defined.
# Adding `-fvisibility=hidden` to the `mex` command causes the build to fail.
# TODO: Check that this is still necessary in R2019a when it comes out.
endif()
# if we do not do that, the symbols linked from eg. boost remain weak and
# then clash with the ones defined in the matlab process. So by default
# the symbols are hidden.
# This also means that for shared libraries (like MEX), the entry point
# should be explicitly declared with default visibility, otherwise Matlab
# cannot find the entry point.
# Note that this is particularly meaningful if the MEX wrapper itself
# contains symbols that are clashing with Matlab (that are compiled in the
# MEX file). In order to propagate the visibility options to the libraries
# to which the MEX file is linked against, the -Wl,--exclude-libs,ALL
# option should also be specified.
if(APPLE)
set_target_properties(${${prefix}_NAME}
PROPERTIES
CXX_VISIBILITY_PRESET "hidden"
C_VISIBILITY_PRESET "hidden"
VISIBILITY_INLINES_HIDDEN ON
)
if(Matlab_HAS_CPP_API)
list(APPEND _ver_map_files ${Matlab_EXTERN_LIBRARY_DIR}/cppMexFunction.map) # This one doesn't exist on Linux
set(_link_flags "${_link_flags} -Wl,-U,_mexCreateMexFunction -Wl,-U,_mexDestroyMexFunction -Wl,-U,_mexFunctionAdapter")
# On MacOS, the MEX command adds the above, without it the link breaks
# because we indiscriminately use "cppMexFunction.map" even for C API MEX-files.
endif()
# get_target_property(
# _previous_link_flags
# ${${prefix}_NAME}
# LINK_FLAGS)
# if(NOT _previous_link_flags)
# set(_previous_link_flags)
# endif()
set(_export_flag_name -exported_symbols_list)
# if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# set_target_properties(${${prefix}_NAME}
# PROPERTIES
# LINK_FLAGS "${_previous_link_flags} -Wl,--exclude-libs,ALL"
# # -Wl,--version-script=${_FindMatlab_SELF_DIR}/MatlabLinuxVisibility.map"
# )
# elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# # in this case, all other symbols become hidden.
# set_target_properties(${${prefix}_NAME}
# PROPERTIES
# LINK_FLAGS "${_previous_link_flags} -Wl,-exported_symbol,_mexFunction"
# #-Wl,-exported_symbols_list,${_FindMatlab_SELF_DIR}/MatlabOSXVisilibity.map"
# )
# endif()
else() # Linux
if(HAS_MINUS_PTHREAD)
# Apparently, compiling with -pthread generated the proper link flags
# and some defines at compilation
target_compile_options(${${prefix}_NAME} PRIVATE "-pthread")
endif()
set(_link_flags "${_link_flags} -Wl,--as-needed")
set(_export_flag_name --version-script)
endif()
foreach(_file ${_ver_map_files})
set(_link_flags "${_link_flags} -Wl,${_export_flag_name},${_file}")
endforeach()
set_target_properties(${${prefix}_NAME}
PROPERTIES
DEFINE_SYMBOL "DLL_EXPORT_SYM=__attribute__ ((visibility (\"default\")))"
)
LINK_FLAGS "${_link_flags}"
) # The `mex` command doesn't add this define. Is it necessary?
endif()
@@ -1449,6 +1460,7 @@ if(DEFINED Matlab_ROOT_DIR_LAST_CACHED)
if(NOT Matlab_ROOT_DIR_LAST_CACHED STREQUAL Matlab_ROOT_DIR)
set(_Matlab_cached_vars
Matlab_VERSION_STRING
Matlab_INCLUDE_DIRS
Matlab_MEX_LIBRARY
Matlab_MEX_COMPILER
@@ -1466,7 +1478,7 @@ if(DEFINED Matlab_ROOT_DIR_LAST_CACHED)
Matlab_MEXEXTENSIONS_PROG
Matlab_ROOT_DIR_LAST_CACHED
#Matlab_PROG_VERSION_STRING_AUTO_DETECT
Matlab_VERSION_STRING_INTERNAL
#Matlab_VERSION_STRING_INTERNAL
)
foreach(_var IN LISTS _Matlab_cached_vars)
if(DEFINED ${_var})
@@ -1491,7 +1503,9 @@ if(MATLAB_FIND_DEBUG)
message(STATUS "[MATLAB] Current version is ${Matlab_VERSION_STRING} located ${Matlab_ROOT_DIR}")
endif()
if(NOT ${Matlab_VERSION_STRING} VERSION_LESS "9.4") # MATLAB 9.4 (R2018a) and newer have a new C++ API
set(Matlab_HAS_CPP_API 1)
endif()
if(Matlab_ROOT_DIR)
file(TO_CMAKE_PATH ${Matlab_ROOT_DIR} Matlab_ROOT_DIR)
@@ -1530,6 +1544,8 @@ set(Matlab_BINARIES_DIR
${Matlab_ROOT_DIR}/bin/${_matlab_bin_prefix}${_matlab_current_suffix})
set(Matlab_EXTERN_LIBRARY_DIR
${Matlab_ROOT_DIR}/extern/lib/${_matlab_bin_prefix}${_matlab_current_suffix})
set(Matlab_EXTERN_BINARIES_DIR
${Matlab_ROOT_DIR}/extern/bin/${_matlab_bin_prefix}${_matlab_current_suffix})
if(WIN32)
if(MINGW)
@@ -1539,7 +1555,7 @@ if(WIN32)
endif()
set(_matlab_lib_prefix_for_search "lib")
else()
set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR})
set(_matlab_lib_dir_for_search ${Matlab_BINARIES_DIR} ${Matlab_EXTERN_BINARIES_DIR})
set(_matlab_lib_prefix_for_search "lib")
endif()
@@ -1590,7 +1606,6 @@ _Matlab_find_library(
PATHS ${_matlab_lib_dir_for_search}
NO_DEFAULT_PATH
)
list(APPEND _matlab_required_variables Matlab_MEX_LIBRARY)
# the MEX extension is required
@@ -1631,21 +1646,18 @@ if(_matlab_find_matlab_program GREATER -1)
endif()
unset(_matlab_find_matlab_program)
# Component MX library
list(FIND Matlab_FIND_COMPONENTS MX_LIBRARY _matlab_find_mx)
if(_matlab_find_mx GREATER -1)
_Matlab_find_library(
${_matlab_lib_prefix_for_search}
Matlab_MX_LIBRARY
mx
PATHS ${_matlab_lib_dir_for_search}
NO_DEFAULT_PATH
)
if(Matlab_MX_LIBRARY)
set(Matlab_MX_LIBRARY_FOUND TRUE)
endif()
# The MX library is required
_Matlab_find_library(
${_matlab_lib_prefix_for_search}
Matlab_MX_LIBRARY
mx
PATHS ${_matlab_lib_dir_for_search}
NO_DEFAULT_PATH
)
list(APPEND _matlab_required_variables Matlab_MX_LIBRARY)
if(Matlab_MX_LIBRARY)
set(Matlab_MX_LIBRARY_FOUND TRUE)
endif()
unset(_matlab_find_mx)
# Component ENG library
list(FIND Matlab_FIND_COMPONENTS ENG_LIBRARY _matlab_find_eng)
@@ -1711,9 +1723,9 @@ if(_matlab_find_mcc_compiler GREATER -1)
endif()
unset(_matlab_find_mcc_compiler)
# component MatlabEngine
list(FIND Matlab_FIND_COMPONENTS ENGINE_LIBRARY _matlab_find_matlab_engine)
if(_matlab_find_matlab_engine GREATER -1)
if(Matlab_HAS_CPP_API)
# The MatlabEngine library is required for R2018a+
_Matlab_find_library(
${_matlab_lib_prefix_for_search}
Matlab_ENGINE_LIBRARY
@@ -1722,40 +1734,33 @@ if(_matlab_find_matlab_engine GREATER -1)
DOC "MatlabEngine Library"
NO_DEFAULT_PATH
)
list(APPEND _matlab_required_variables Matlab_ENGINE_LIBRARY)
if(Matlab_ENGINE_LIBRARY)
set(Matlab_ENGINE_LIBRARY_FOUND TRUE)
endif()
endif()
unset(_matlab_find_matlab_engine)
# component MatlabDataArray
list(FIND Matlab_FIND_COMPONENTS DATAARRAY_LIBRARY _matlab_find_matlab_dataarray)
if(_matlab_find_matlab_dataarray GREATER -1)
# The MatlabDataArray library is required for R2018a+
_Matlab_find_library(
${_matlab_lib_prefix_for_search}
${_matlab_lib_prefix_for_search}
Matlab_DATAARRAY_LIBRARY
MatlabDataArray
PATHS ${_matlab_lib_dir_for_search}
DOC "MatlabDataArray Library"
NO_DEFAULT_PATH
)
list(APPEND _matlab_required_variables Matlab_DATAARRAY_LIBRARY)
if(Matlab_DATAARRAY_LIBRARY)
set(Matlab_DATAARRAY_LIBRARY_FOUND TRUE)
endif()
endif()
unset(_matlab_find_matlab_dataarray)
unset(_matlab_lib_dir_for_search)
set(Matlab_LIBRARIES ${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY} ${Matlab_ENG_LIBRARY} ${Matlab_MAT_LIBRARY})
if(Matlab_DATAARRAY_LIBRARY_FOUND)
set(Matlab_LIBRARIES ${Matlab_LIBRARIES} ${Matlab_DATAARRAY_LIBRARY})
endif()
if(Matlab_ENGINE_LIBRARY_FOUND)
set(Matlab_LIBRARIES ${Matlab_LIBRARIES} ${Matlab_ENGINE_LIBRARY})
endif()
set(Matlab_LIBRARIES
${Matlab_MEX_LIBRARY} ${Matlab_MX_LIBRARY}
${Matlab_ENG_LIBRARY} ${Matlab_MAT_LIBRARY}
${Matlab_DATAARRAY_LIBRARY} ${Matlab_ENGINE_LIBRARY})
find_package_handle_standard_args(
Matlab

View File

@@ -1493,13 +1493,18 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
# Matlab module
# CMake_TEST_FindMatlab: indicates to look for Matlab (from PATH for Linux)
# CMake_TEST_FindMatlab_ROOT_DIR: indicates an optional root directory for Matlab, allows to select a version.
# CMake_TEST_FindMatlab_MCR: indicates the MCR is installed
# CMake_TEST_FindMatlab_MCR_ROOT_DIR: indicates an optional root directory for the MCR, required on Linux
if(CMake_TEST_FindMatlab OR CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL ""))
if(CMake_TEST_FindMatlab OR (NOT "${CMake_TEST_FindMatlab_ROOT_DIR}" STREQUAL "") OR
CMake_TEST_FindMatlab_MCR OR (NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL ""))
set(FindMatlab_additional_test_options )
if(CMake_TEST_FindMatlab_MCR OR NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options -DIS_MCR=TRUE)
endif()
if(NOT "${CMake_TEST_FindMatlab_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMatlab_ROOT_DIR=${CMake_TEST_FindMatlab_ROOT_DIR}")
endif()
if(NOT "${CMake_TEST_FindMatlab_MCR_ROOT_DIR}" STREQUAL "")
set(FindMatlab_additional_test_options ${FindMatlab_additional_test_options} "-DMCR_ROOT:FILEPATH=${CMake_TEST_FindMatlab_MCR_ROOT_DIR}")
endif()
@@ -1511,6 +1516,8 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
ADD_TEST_MACRO(FindMatlab.components_checks ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
set(FindMatlab.failure_reports_BUILD_OPTIONS ${FindMatlab_additional_test_options})
ADD_TEST_MACRO(FindMatlab.failure_reports ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
set(FindMatlab.r2018a_check_BUILD_OPTIONS ${FindMatlab_additional_test_options})
ADD_TEST_MACRO(FindMatlab.r2018a_check ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>)
endif()
find_package(GTK2 QUIET)

View File

@@ -10,11 +10,10 @@ set(MATLAB_FIND_DEBUG TRUE)
# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab
if(IS_MCR)
set(components MX_LIBRARY)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MX_LIBRARY MAIN_PROGRAM)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
@@ -34,7 +33,7 @@ matlab_add_mex(
OUTPUT_NAME cmake_matlab_mex1
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
)
)
if(RUN_UNIT_TESTS)
matlab_add_unit_test(

View File

@@ -0,0 +1,28 @@
classdef cmake_matlab_unit_tests4 < matlab.unittest.TestCase
% Testing R2017b and R2018a APIs
properties
end
methods (Test)
function testR2017b(testCase)
ret = cmake_matlab_mex2a(5+6i);
testCase.verifyEqual(ret, 8);
end
function testR2018a(testCase)
ret = cmake_matlab_mex2b(5+6i);
v = version;
n = find(v=='.');
v = str2double(v(1:n(2)-1));
disp(v)
if v>= 9.4 % R2018a
testCase.verifyEqual(ret, 16);
disp('TESTING version >= 9.4')
else
testCase.verifyEqual(ret, 8);
end
end
end
end

View File

@@ -0,0 +1,20 @@
classdef cmake_matlab_unit_tests5 < matlab.unittest.TestCase
% C++ API test
properties
end
methods (Test)
function testDummyCall(testCase)
% very simple call test
disp('TESTING C++')
ret = cmake_matlab_mex3(162);
testCase.verifyEqual(ret, 162);
end
function testFailTest(testCase)
testCase.verifyError(@() cmake_matlab_mex3, 'MATLAB:mex:CppMexException');
end
end
end

View File

@@ -15,7 +15,7 @@ endif()
# the success of the following command is dependent on the current configuration:
# - on 32bits builds (cmake is building with 32 bits), it looks for 32 bits Matlab
# - on 64bits builds (cmake is building with 64 bits), it looks for 64 bits Matlab
find_package(Matlab REQUIRED COMPONENTS MX_LIBRARY ENG_LIBRARY MAT_LIBRARY
find_package(Matlab REQUIRED COMPONENTS ENG_LIBRARY MAT_LIBRARY
OPTIONAL_COMPONENTS MAIN_PROGRAM)
message(STATUS "FindMatlab libraries: ${Matlab_LIBRARIES}")
@@ -28,4 +28,4 @@ matlab_add_mex(
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
LINK_TO ${Matlab_LIBRARIES}
)
)

View File

@@ -8,11 +8,10 @@ project(failure_reports)
set(MATLAB_FIND_DEBUG TRUE)
if(IS_MCR)
set(components MX_LIBRARY)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MX_LIBRARY MAIN_PROGRAM)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
@@ -32,7 +31,7 @@ matlab_add_mex(
OUTPUT_NAME cmake_matlab_mex1
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper1.cpp
DOCUMENTATION ${CMAKE_CURRENT_SOURCE_DIR}/../help_text1.m.txt
)
)
if(RUN_UNIT_TESTS)
# the unit test file does not exist: the failure should be properly reported

View File

@@ -0,0 +1,22 @@
// simple workaround to some compiler specific problems
// see
// http://stackoverflow.com/questions/22367516/mex-compile-error-unknown-type-name-char16-t/23281916#23281916
#include <algorithm>
#include "mex.h"
// This test uses the new complex-interleaved C API (R2018a and newer)
// The input should be a complex array (scalar is OK). It returns the number of
// bytes in a matrix element. For the old (R2017b) API, this is 8. For the new
// (R2018a) API, this is 16.
void mexFunction(const int nlhs, mxArray* plhs[], const int nrhs,
const mxArray* prhs[])
{
if (nrhs != 1 || !mxIsComplex(prhs[0])) {
mexErrMsgTxt("Incorrect arguments");
}
plhs[0] = mxCreateDoubleScalar(mxGetElementSize(prhs[0]));
}

View File

@@ -0,0 +1,29 @@
#include "mex.hpp"
#include "mexAdapter.hpp"
// This test uses the new C++ API (R2018a and newer)
// The input should be a scalar double array. The output is a copy of that
// array.
using namespace matlab::data;
using matlab::mex::ArgumentList;
class MexFunction : public matlab::mex::Function
{
public:
void operator()(ArgumentList outputs, ArgumentList inputs)
{
std::shared_ptr<matlab::engine::MATLABEngine> matlabPtr = getEngine();
ArrayFactory factory;
if (inputs[0].getType() != ArrayType::DOUBLE ||
inputs[0].getType() == ArrayType::COMPLEX_DOUBLE ||
inputs[0].getNumberOfElements() != 1) {
matlabPtr->feval(
u"error", 0,
std::vector<Array>({ factory.createScalar("Incorrect arguments") }));
}
double a = inputs[0][0];
outputs[0] = factory.createScalar(a);
}
};

View File

@@ -0,0 +1,84 @@
cmake_minimum_required (VERSION 2.8.12)
enable_testing()
project(r2018a_checks)
set(MATLAB_FIND_DEBUG TRUE)
# this test doesn't do much if MATLAB version < R2018a
if(IS_MCR)
set(RUN_UNIT_TESTS FALSE)
else()
set(RUN_UNIT_TESTS TRUE)
set(components MAIN_PROGRAM)
endif()
if(NOT "${MCR_ROOT}" STREQUAL "")
set(Matlab_ROOT_DIR "${MCR_ROOT}")
if(NOT EXISTS "${MCR_ROOT}")
message(FATAL_ERROR "MCR does not exist ${MCR_ROOT}")
endif()
endif()
find_package(Matlab REQUIRED COMPONENTS ${components})
set(IS_R2018a 1)
if(${Matlab_VERSION_STRING} VERSION_LESS "9.4")
# This is an older version of MATLAB, tests will fail
set(IS_R2018a 0)
endif()
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper2a
# output name
OUTPUT_NAME cmake_matlab_mex2a
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper2.cpp
R2017b
)
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper2b
# output name
OUTPUT_NAME cmake_matlab_mex2b
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper2.cpp
R2018a
)
if(IS_R2018a)
matlab_add_mex(
# target name
NAME cmake_matlab_test_wrapper3
# output name
OUTPUT_NAME cmake_matlab_mex3
SRC ${CMAKE_CURRENT_SOURCE_DIR}/../matlab_wrapper3.cpp
)
set_target_properties(
cmake_matlab_test_wrapper3
PROPERTIES
CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
)
endif()
if(RUN_UNIT_TESTS)
# Check that the R2017b and R2018a APIs work.
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-1
TIMEOUT 300
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests4.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper2a>
)
# Check that the C++ API works (test run only on R2018a and newer)
if(IS_R2018a)
matlab_add_unit_test(
NAME ${PROJECT_NAME}_matlabtest-3
TIMEOUT 300
UNITTEST_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../cmake_matlab_unit_tests5.m
ADDITIONAL_PATH $<TARGET_FILE_DIR:cmake_matlab_test_wrapper3>
)
endif()
endif()