Overview of the MATLAB Compiler¶
What it is¶
The "MATLAB compiler" is a program called "mcc" that ships with MATLAB. It compiles MATLAB code into (encrypted) binary code for the current platform. That is, it appears you must compile on the same machine architecture and operating system as you want to use the code on -- it doesn't cross-compile. You can then take this code to a different machine and run it using the (free) MCR runtime.
The compiler has a pretty wide range of options, described in the command-line help text (run mcc -?
). Note that there are examples at the bottom of the help.
The most basic usage is
$ mcc -m function
to compile the MATLAB file function.m
into a standalone executable.
Executing the file¶
If the compiled file is called foo.exe
, it should be called as:
foo.exe arg1 arg2
Note that MATLAB assumes that all arguments to be strings, so if you are expecting doubles, integers, etc these should be handled inside the function. For instance, if arg1 is an integer, one can do the conversion using
if ischar(arg1) arg1=str2num(arg1); end
Read more (including how to use matrices as arguments) here:
http://www.mathworks.co.uk/support/solutions/en/data/1-18448/?solution=1-18448
How to run the result on a different machine¶
The "target" machine doesn't have to have MATLAB installed or a MATLAB licence. You will need to install the MCR runtime, but you don't need to be root to do it -- you can just install into a random directory somewhere. If you're doing that, note that the installer puts all manner of crap directly in the directory you give it, so be sure to make a new directory for it.
If you run ldd
or otool -L
(depending on platform) on your compiled binary, you'll see that it depends on various shared libraries:
libmwlaunchermain.so => not found libmwmclmcrrt.so.8.1 => not found libmwcpp11compat.so => not found
You get these (in two separate locations, a bin
and a runtime
) when you install the MCR. You can make the executable run by adding both locations to the LD_LIBRARY_PATH
when you run it. The MCR comes with lots of instructions, but you don't really need them if you don't want a GUI.
(The default compiled application is very slow to start up, and will either need additional configuration for GUI support or else will complain about the lack of it when it starts. Adding the -R -nojvm -R -nodisplay
options to the mcc
command-line should fix this, assuming a GUI is not in fact required.)
Creating a C++ shared library¶
http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/
On OSX I had to add the following to DYLD_LIBRARY_PATH
:
/Applications/MATLAB_R2011a.app/runtime/maci64/:/Applications/MATLAB_R2011a.app/bin/maci64/:/Applications/MATLAB_R2011a.app//sys/os/maci64/
Creating the shared library¶
(Example for the following code, using OSX 10.7.5 and MATLAB_R2011a)
File gensin.m:
function gensin(freq) %% generates a 2 second long sine wave of a given frequency % freq should be in Hz % writes the output to file out.wav if ischar(freq) freq=str2double(freq); else freq=double(freq); end fs = 44100; t = 0:1/fs:2; % 2 second clip y = sin(2*pi*freq.*t); % writes the file - NBITS = 16 wavwrite(y, fs, 'out.wav'); end
Generating the library¶
/Applications/MATLAB_R2011a.app/bin/mcc -W cpplib:libmysine -T link:lib gensin
This will create several files:
- libmysine.h
- libmysine.cpp
- libmysine.dylib
- libmysine.exports
- mccExcludedFiles.txt
- readme.txt
An example c++ program¶
// testsin.cpp: generate a 2 sec sine wave // code to exemplify how to use MATLAB code as a C++ library // // Example adapted from: // http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/ // and http://www.mathworks.com/matlabcentral/answers/1720 #include "libmysine.h" #include <iostream.h> int run_main(int argc, const char *argv[]) { // I expecty only one argument which is the frequency // Initialize the MATLAB Compiler Runtime global state if (!mclInitializeApplication(NULL,0)) { std::cerr << "Could not initialize the application properly." << std::endl; return -1; } // Initialize the MySine library if( !libmysineInitialize() ) { std::cerr << "Could not initialize the library properly." << std::endl; return -1; } // Must declare all MATLAB data types after initializing the // application and the library, or their constructors will fail. // 100 Hz mwArray freq(100); gensin(freq); libmysineTerminate(); mclTerminateApplication(); return 0; } int main() { mclmcrInitialize(); return mclRunMain((mclMainFcnType)run_main,0,NULL); }
Compiling the C++ source with the library¶
In order to do this you should use mbuild:
/Applications/MATLAB_R2011a.app/bin/mbuild testsin.cpp libmysine.dylib