Guest blogger Peter Webb presents another post about building applications with the MATLAB Compiler. This week's topic: understanding the types of functions that cannot be deployed and managing those that behave differently
For an introduction to writing deployable code, please see the June 19th post.
When you're writing an application you intend to deploy with the MATLAB Compiler, you need to be aware that a subset of MATLAB's
functions either cannot be deployed or behave differently when deployed.
There are two classes of non-deployable functions: functions that are not licensed for deployment; and functions that the
deployment runtime (the MATLAB Common Runtime or MCR) cannot support.
The intent of the MATLAB Compiler and the Builders is to create a robust application with predictable behavior. In part, this
means that the users of the deployed application should not be able to modify it. Preventing users from modifying deployed
applications has several benefits:
- Predictable performance and results: The application will always work just as it did when it was deployed.
- Easier to support: The support organization does not have to cope with user-introduced bugs.
- Protection of intellectual property: Making the code unreadable (and hence, unmodifiable) means users cannot copy the algorithms.
- Increased security: An application distributed in binary, encrypted form is more tamper-resistant than one for which the source
code is available.
To prevent the modification of deployed applications, the Compiler includes only those M-files the application actually uses,
encrypts the M-files (this also protects the intellectual property they contain), creates MEX authorization files, and truncates
the MATLAB path. But editing M-files and modifying the MATLAB path is not the only way to change a MATLAB application. Certain
MATLAB and toolbox functions can themselves change an application's behavior. For example, the MATLAB debugger can interactively
modify the contents of variables and change the order in which the interpreter calls functions. Similarly, the figure property
editor can modify figure callback strings. The Compiler prevents these types of modifications by refusing to compile the functions
that perform them; these functions are excluded from the generated CTF archive.
In general the Compiler excludes those functions used when developing an application. Most of these design time functions fall into one of two categories: those that permit the application to change the way it works, like dbstop and propedit; and those that are complete mini-applications in and of themselves, like imtool and guide. This includes, but is not limited to:
- All types of debugging functions.
- Most of the toolbox functions ending in tool, such as imtool and sptool.
- Functions that generate or edit M-code directly or indirectly; this includes, for example, the Deep Learning Toolbox network training functions such as train.
- Functions or GUIs that you use to design solutions, like the Database Toolbox's Visual Query Builder, the Curve Fitting Toolbox's interactive curvefitting tool, and the ANFIS training algorithm used in the Fuzzy Logic Toolbox. However, you typically can deploy the output of these functions: the generated database query, the M-file generated by the curve fitting tool and the fuzzy inference system trained by anfis.
Many of these restrictions have no workaround: debugging functions and functions which generate M-code simply cannot be deployed.
There's no workaround for the debugging functions because they are builtins, and there's no effective way to debug MATLAB
code using M-files. Functions which generate M-code will not work in a deployed application because they have no way of encrypting
the generated M-code, which the MCR requires. You can, of course, write your own code to compensate for other types of excluded
functions, but keep in mind that cloning MATLAB or toolbox functions violates your license agreement, which we don't encourage.
The Compiler creates a list of excluded functions in the output directory. This list, mccExcludedFiles.log, which is often quite long, contains the full paths to the M-files that the Compiler removed from the list produced by depfun and a short explanation for why each function cannot be deployed.
We publish a list of deployable functions; this list may change with each release of MATLAB and the deployable toolboxes.
Certain MATLAB functions cannot be deployed because they act on objects that are not present in a deployed application. For
example, since deployed applications have no command window, functions that modify the command window can't be deployed.
Use of these functions in deployed application will result in mlint warnings in the MATLAB editor and runtime warnings in the deployed application. For example, calls to help generate this text when deployed:
Warning: The HELP function cannot be used in compiled applications.
You can prevent your deployed applications from displaying warnings like this via the isdeployed function. For more details, see the previous blog posting about path management in deployed applications.
There are currently four non-deployable MATLAB functions:
- help: Deployed applications typically do not include MATLAB or toolbox help files, so there's no need for a help function.
- helpwin: helpwin displays help text in a new window; like help it is of very little use in deployed applications because deployed applications do not contain MATLAB's help files.
- keyboard: Since a deployed component may be part of a graphical application with no keyboard input stream, the MATLAB Compiler does
not not support deployment of the keyboard function.
- savepath: A deployed application's path is fixed and unchangeable, which means there's no need to save the path.
The versions of these functions that issue warnings override the versions in MATLAB because of their location in toolbox/compiler/deploy which always appears first on the path used by mcc and depfun.
Where the differences between MATLAB and the deployed environment are not insurmountable, the MATLAB Compiler and the Builder
tools offer versions of MATLAB functions that have been modified to work in deployed applications.
Eight important MATLAB functions work differently in deployed applications:
- clc: In MATLAB, clc clears the command window. Since deployed applications do not display a command window, clc clears the shell or DOS window in which the application was started.
- fopen: In a deployed application, fopen looks for the specified file in the unpacked CTF archive before looking for it in the current directory. This means that
fopen will preferentially open files shipped with application, even if there's a file in the current directory with the same name.
Note that preferring files contained in the CTF archive is most often exactly what you want the deployed fopen to do. Please don't be tempted to use a full path to work around this behavior as that may create further problems when the
application is deployed. For more details on why, see the previous blog posting in this series.
- home: In MATLAB, home returns the prompt to the upper left of the command window. In a deployed application, it moves the prompt to the upper left
of the shell or DOS window from which the application was started. Unlike clc, home does not clear the existing text in the window.
- input: The deployed version of input reads from the shell or DOS command window instead of the MATLAB command window. If there is no command window available,
input will hang or fail.
- loadlibrary: The version of loadlibrary which operates on C-style header interfaces is not available in deployed applications; but the Compiler does support loadlibrary with M-file prototypes.
- pause: Like input, pause (without a timeout argument) reads from the shell or DOS command window in a deployed application. If no such window is available
pause will pause forever.
- print: A full accounting of the differences between printing in a deployed application and printing in MATLAB is beyond the scope
of this posting. While you can still use print for generating bitmaps or JPEGs from your figures, for hardcopy you must use deployprint instead. For example:
if isdeployed deployprint else print end
- printdlg: Deployed applications only support the single argument version of printdlg, i.e., printdlg(fig).
You'll find the code for the deployment-specific versions of these functions in toolbox/compiler/deploy. You can control if these functions get called in deployed applications using the isdeployed function. In the unlikely event that you need to change how these functions work, you can overload them by creating a function
of the same name in your top-level application directory. The Compiler will set the path of the generated application so that
your M-file gets called instead of the one in toolbox/compiler/deploy.
Finally, please note that functions deployed as the main routine of a standalone executable may need to process their input
arguments differently when deployed. When making a standalone executable from a MATLAB function that takes parameters, the
MATLAB Compiler generates code to pass any user-supplied command line arguments to the compiled MATLAB function. However,
the command line arguments are passed to the MATLAB function as strings, even if they are numeric. Therefore, any M-function
serving as the entry point for a compiled MATLAB program should expect (or at least test for) string input. For example:
function y = addten(x) if isstr(x) x = str2num(x); end
y = x + 10;
Deploying your applications will be easier if you follow these guidelines:
- Use isdeployed to protect non-deployable code from being called by deployed applications.
- Remember that a deployed application has no MATLAB command window (or any of the other desktop tools, like the editor).
- Don't change the path or rely on the current directory; deployed applications are supposed to be less flexible than MATLAB
applications (this makes them more secure and easier to support).
- Check the list of deployable functions before writing your application to make sure you can deploy the functions you plan to use.
Most of the information in this series of postings will eventually end up in the documentation for the MATLAB Compiler. Please
comment on anything you feel was unclear, and ask any questions you think were unanswered. And feel free to contact me if
you have other questions about the MATLAB Compiler or the Builders or post your thoughts here.
Published with MATLAB® 7.6