Overview of the MATLAB Compiler » History » Version 1

Chris Cannam, 2014-03-11 03:11 PM

1 1 Chris Cannam
h1. Overview of the MATLAB Compiler
2 1 Chris Cannam
3 1 Chris Cannam
h2. What it is
4 1 Chris Cannam
5 1 Chris Cannam
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.
6 1 Chris Cannam
7 1 Chris Cannam
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.
8 1 Chris Cannam
9 1 Chris Cannam
The most basic usage is
10 1 Chris Cannam
11 1 Chris Cannam
<pre>
12 1 Chris Cannam
$ mcc -m function
13 1 Chris Cannam
</pre>
14 1 Chris Cannam
15 1 Chris Cannam
to compile the MATLAB file @function.m@ into a standalone executable.
16 1 Chris Cannam
17 1 Chris Cannam
h3. Executing the file
18 1 Chris Cannam
19 1 Chris Cannam
If the compiled file is called @foo.exe@, it should be called as: 
20 1 Chris Cannam
21 1 Chris Cannam
<pre>
22 1 Chris Cannam
foo.exe arg1 arg2 
23 1 Chris Cannam
</pre>
24 1 Chris Cannam
25 1 Chris Cannam
*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
26 1 Chris Cannam
27 1 Chris Cannam
<pre>
28 1 Chris Cannam
if ischar(arg1)
29 1 Chris Cannam
    arg1=str2num(arg1);
30 1 Chris Cannam
end
31 1 Chris Cannam
</pre>
32 1 Chris Cannam
33 1 Chris Cannam
Read more (including how to use matrices as arguments) here: 
34 1 Chris Cannam
35 1 Chris Cannam
http://www.mathworks.co.uk/support/solutions/en/data/1-18448/?solution=1-18448
36 1 Chris Cannam
37 1 Chris Cannam
38 1 Chris Cannam
h2. How to run the result on a different machine
39 1 Chris Cannam
40 1 Chris Cannam
The "target" machine doesn't have to have MATLAB installed or a MATLAB licence. You will need to install the "MCR runtime":http://www.mathworks.co.uk/help/compiler/working-with-the-mcr.html, 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.
41 1 Chris Cannam
42 1 Chris Cannam
If you run @ldd@ or @otool -L@ (depending on platform) on your compiled binary, you'll see that it depends on various shared libraries:
43 1 Chris Cannam
44 1 Chris Cannam
<pre>
45 1 Chris Cannam
	libmwlaunchermain.so => not found
46 1 Chris Cannam
	libmwmclmcrrt.so.8.1 => not found
47 1 Chris Cannam
	libmwcpp11compat.so => not found
48 1 Chris Cannam
</pre>
49 1 Chris Cannam
50 1 Chris Cannam
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.
51 1 Chris Cannam
52 1 Chris Cannam
(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.)
53 1 Chris Cannam
54 1 Chris Cannam
h2. Creating a C++ shared library 
55 1 Chris Cannam
56 1 Chris Cannam
http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/
57 1 Chris Cannam
58 1 Chris Cannam
On OSX I had to add the following to @DYLD_LIBRARY_PATH@: 
59 1 Chris Cannam
60 1 Chris Cannam
<pre>
61 1 Chris Cannam
  /Applications/MATLAB_R2011a.app/runtime/maci64/:/Applications/MATLAB_R2011a.app/bin/maci64/:/Applications/MATLAB_R2011a.app//sys/os/maci64/
62 1 Chris Cannam
</pre>
63 1 Chris Cannam
64 1 Chris Cannam
h3. Creating the shared library
65 1 Chris Cannam
66 1 Chris Cannam
67 1 Chris Cannam
68 1 Chris Cannam
(Example for the following code, using OSX 10.7.5 and MATLAB_R2011a)
69 1 Chris Cannam
70 1 Chris Cannam
File gensin.m:
71 1 Chris Cannam
<pre>
72 1 Chris Cannam
function gensin(freq)
73 1 Chris Cannam
%% generates a 2 second long sine wave of a given frequency
74 1 Chris Cannam
% freq should be in Hz
75 1 Chris Cannam
% writes the output to file out.wav
76 1 Chris Cannam
77 1 Chris Cannam
if ischar(freq)
78 1 Chris Cannam
    freq=str2double(freq);
79 1 Chris Cannam
else
80 1 Chris Cannam
    freq=double(freq);
81 1 Chris Cannam
end
82 1 Chris Cannam
83 1 Chris Cannam
fs = 44100;
84 1 Chris Cannam
t = 0:1/fs:2; % 2 second clip
85 1 Chris Cannam
86 1 Chris Cannam
y = sin(2*pi*freq.*t);
87 1 Chris Cannam
88 1 Chris Cannam
% writes the file - NBITS = 16
89 1 Chris Cannam
wavwrite(y, fs, 'out.wav');
90 1 Chris Cannam
91 1 Chris Cannam
end
92 1 Chris Cannam
</pre>
93 1 Chris Cannam
94 1 Chris Cannam
h3. Generating the library
95 1 Chris Cannam
96 1 Chris Cannam
<pre>
97 1 Chris Cannam
  /Applications/MATLAB_R2011a.app/bin/mcc -W cpplib:libmysine -T link:lib gensin
98 1 Chris Cannam
</pre>
99 1 Chris Cannam
100 1 Chris Cannam
This will create several files: 
101 1 Chris Cannam
102 1 Chris Cannam
* libmysine.h
103 1 Chris Cannam
* libmysine.cpp
104 1 Chris Cannam
* libmysine.dylib
105 1 Chris Cannam
* libmysine.exports
106 1 Chris Cannam
* mccExcludedFiles.txt
107 1 Chris Cannam
* readme.txt
108 1 Chris Cannam
109 1 Chris Cannam
h3. An example c++ program
110 1 Chris Cannam
111 1 Chris Cannam
<pre>
112 1 Chris Cannam
// testsin.cpp: generate a 2 sec sine wave
113 1 Chris Cannam
// code to exemplify how to use MATLAB code as a C++ library
114 1 Chris Cannam
//
115 1 Chris Cannam
// Example adapted from:
116 1 Chris Cannam
//   http://blogs.mathworks.com/loren/2011/02/03/creating-c-shared-libraries-and-dlls/
117 1 Chris Cannam
//   and http://www.mathworks.com/matlabcentral/answers/1720
118 1 Chris Cannam
119 1 Chris Cannam
#include "libmysine.h"
120 1 Chris Cannam
#include <iostream.h>
121 1 Chris Cannam
122 1 Chris Cannam
int run_main(int argc, const char *argv[])
123 1 Chris Cannam
{
124 1 Chris Cannam
    // I expecty only one argument which is the frequency
125 1 Chris Cannam
126 1 Chris Cannam
    // Initialize the MATLAB Compiler Runtime global state
127 1 Chris Cannam
    if (!mclInitializeApplication(NULL,0))
128 1 Chris Cannam
    {
129 1 Chris Cannam
        std::cerr << "Could not initialize the application properly."
130 1 Chris Cannam
                  << std::endl;
131 1 Chris Cannam
        return -1;
132 1 Chris Cannam
    }
133 1 Chris Cannam
134 1 Chris Cannam
    // Initialize the MySine library
135 1 Chris Cannam
    if( !libmysineInitialize() )
136 1 Chris Cannam
    {
137 1 Chris Cannam
        std::cerr << "Could not initialize the library properly."
138 1 Chris Cannam
                  << std::endl;
139 1 Chris Cannam
        return -1;
140 1 Chris Cannam
    }
141 1 Chris Cannam
142 1 Chris Cannam
    // Must declare all MATLAB data types after initializing the
143 1 Chris Cannam
    // application and the library, or their constructors will fail.
144 1 Chris Cannam
145 1 Chris Cannam
    // 100 Hz
146 1 Chris Cannam
    mwArray freq(100);
147 1 Chris Cannam
148 1 Chris Cannam
    gensin(freq);
149 1 Chris Cannam
150 1 Chris Cannam
    libmysineTerminate();
151 1 Chris Cannam
152 1 Chris Cannam
    mclTerminateApplication();
153 1 Chris Cannam
    return 0;
154 1 Chris Cannam
}
155 1 Chris Cannam
156 1 Chris Cannam
int main() {
157 1 Chris Cannam
    mclmcrInitialize();
158 1 Chris Cannam
    return mclRunMain((mclMainFcnType)run_main,0,NULL);
159 1 Chris Cannam
}
160 1 Chris Cannam
</pre>
161 1 Chris Cannam
162 1 Chris Cannam
h3. Compiling the C++ source with the library 
163 1 Chris Cannam
164 1 Chris Cannam
In order to do this you should use *mbuild*:
165 1 Chris Cannam
166 1 Chris Cannam
<pre>
167 1 Chris Cannam
/Applications/MATLAB_R2011a.app/bin/mbuild testsin.cpp libmysine.dylib
168 1 Chris Cannam
</pre>