3

I am trying to call Matlab functions from C++ code.

With Matlab it comes an example of such code at /extern/examples/eng_mat/engdemo.cpp, however I found no way to build that source code.

Here is the makefile I use:

CFLAGS = -Wall -O3

INCLUDES = -I/opt/Matlab-2009a/extern/include

LIBRARIES = -Wl,-R/opt/Matlab-2009a/bin/glnx86 -L/opt/Matlab-2009a/bin/glnx86 -lmx -lmat -leng

out : engdemo.cpp
    g++ $(CFLAGS) $(INCLUDES) -static $^ $(LIBRARIES) -o out

clean :
    rm -f out

(Here /opt/Matlab-2009a is my Matlab root.) I am getting a linker error like this:

/usr/bin/ld: cannot find -lmx
collect2: ld returned 1 exit status
make: *** [out] Error 1

And the question is: how can I make g++ to compile engdemo.cpp ?

Note, that the shared library exists:

$ locate libmx.so
/opt/Matlab-2009a/bin/glnx86/libmx.so
/opt/Matlab-2009a/bin/glnx86/libmx.so.csf

and

$ ldd /opt/Matlab-2009a/bin/glnx86/libmx.so
    linux-gate.so.1 =>  (0x004b4000)
    libut.so => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libut.so (0x0078f000)
    libmwfl.so => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libmwfl.so (0x00110000)
    libicudata.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicudata.so.38 (0xb7f82000)
    libicuuc.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicuuc.so.38 (0x00bee000)
    libicui18n.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicui18n.so.38 (0x001f7000)
    libicuio.so.38 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/libicuio.so.38 (0x00e1c000)
    libz.so.1 => /usr/lib/libz.so.1 (0x0098e000)
    libstdc++.so.6 => /opt/Matlab-2009a/bin/glnx86/../../sys/os/glnx86/libstdc++.so.6 (0x00531000)
    libm.so.6 => /lib/libm.so.6 (0x00194000)
    libgcc_s.so.1 => /opt/Matlab-2009a/bin/glnx86/../../sys/os/glnx86/libgcc_s.so.1 (0x00eaa000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x00900000)
    libc.so.6 => /lib/libc.so.6 (0x00345000)
    librt.so.1 => /lib/librt.so.1 (0x00964000)
    libdl.so.2 => /lib/libdl.so.2 (0x0014e000)
    libexpat.so.1 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libexpat.so.1 (0x00152000)
    libboost_thread-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_thread-gcc42-mt-1_36.so.1.36.0 (0x00fc2000)
    libboost_signals-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_signals-gcc42-mt-1_36.so.1.36.0 (0x0017d000)
    libboost_system-gcc42-mt-1_36.so.1.36.0 => /opt/Matlab-2009a/bin/glnx86/../../bin/glnx86/../../bin/glnx86/libboost_system-gcc42-mt-1_36.so.1.36.0 (0x00a06000)
    /lib/ld-linux.so.2 (0x001db000)

So, how can I make g++ to compile engdemo.cpp ?

1

3 Answers 3

2

Assuming $MATLABROOT is the path to MATLAB:

$MATLABROOT/bin/mex -f $MATLABROOT/bin/engopts.sh engdemo.cpp

If you add the -v switch, the verbose output will show you what commands are being used to compile the engine application.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer, especially for mentioning the -v option.
0

Why are you compiling with -static? From "man gcc":

-static On systems that support dynamic linking, this prevents linking with the shared libraries. On other systems, this option has no effect.

In other words, the -static option forces the linker to only consider static libraries, meaning that it will try to find libmx.a rather than libmx.so. Since Matlab only ships with shared (dynamic) libraries, it fails.

Try removing that option & see what happens.

If that doesn't work, you may need to run libtool to help it find the .so's at runtime.

1 Comment

Thanks for the answer. The -static option there, is a side effect of copy-pasting the makefile :). You are absolutely right, and removing that option makes the code compile. However, as it follows from SCFrench's answer, there are several -D (macro defining) options which should be passed to g++.
0

I thought I'd post something that related that might be of use to someone who stumbles upon this post in the future, on the theme of calling a Matlab function from C++.

In a tutorial posted on the Mathworks site the use of shared libraries is demonstrated for calling Matlab function(s) from a C++ file. Here, the mcc command is used to create a shared library.

Subsequently, the mbuild command is used to build the executable. However, if you have a complicated C++ code, which itself needs its own set of shared libraries for compilation, mbuild won't work. The tutorial doesn't demonstrate what needs to be done in this case. So, the purpose of my reply is to post that solution. The user C++ file is vigenere.cpp, and the shared library to be linked in this case is libvigenere.so, and this is the resultant call to g++:

g++ -o vigenere -L/usr/local/MATLAB/R2013b/runtime/glnxa64 -L. -I/usr/local/MATLAB/R2013b/extern/include/ vigenere.cpp -lmwmclmcrrt -lm -lvigenere

Some prerequisites:

  1. The Matlab Compiler Runtime (MCR) needs to be installed. Either type mcrinstaller at the Matlab prompt, or download the appropriate installer from the Matlab site.
  2. After doing this, make sure to set your LD_LIBRARY_PATH as per the instructions at the end of the installer.
  3. The current working directory needs to be added to the LD_LIBRARY_PATH. In bash, I do this by export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD

Note that 1&2 are also described in a readme.txt file generated by the mcc command.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.