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