{"id":150,"date":"2008-08-11T11:00:15","date_gmt":"2008-08-11T16:00:15","guid":{"rendered":"https:\/\/blogs.mathworks.com\/loren\/2008\/08\/11\/path-management-in-deployed-applications\/"},"modified":"2016-07-31T13:45:49","modified_gmt":"2016-07-31T18:45:49","slug":"path-management-in-deployed-applications","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/loren\/2008\/08\/11\/path-management-in-deployed-applications\/","title":{"rendered":"Path Management in Deployed Applications"},"content":{"rendered":"<div class=\"content\">\n<p>This week, guest blogger <a href=\"mailto:pwebb@mathworks.com\">Peter Webb<\/a> continues his series of articles about the MATLAB Compiler. This week's topic: managing MATLAB's paths in a compiled application.<br \/>\nFor an introduction to writing deployable code, please see the <a href=\"https:\/\/blogs.mathworks.com\/loren\/2008\/06\/19\/writing-deployable-code\/\">June 19th article<\/a>.<\/p>\n<p>&nbsp;<\/p>\n<h3>Contents<\/h3>\n<div>\n<ul>\n<li><a href=\"#2\">General Guidelines<\/a><\/li>\n<li><a href=\"#3\">MATLAB Commands that Directly Access the Path<\/a><\/li>\n<li><a href=\"#7\">Paths as Arguments to MATLAB Functions<\/a><\/li>\n<li><a href=\"#11\">Relying on the Structure of External Paths<\/a><\/li>\n<li><a href=\"#12\">Next Up: Non-supported functions<\/a><\/li>\n<\/ul>\n<\/div>\n<p>One of the goals of the compilation process is to turn a flexible and easily modifiable MATLAB progam into a robust software<br \/>\ncomponent with consistiently predictable behavior: a compiled application should not be able to change which functions it<br \/>\ncalls or the way those functions work. As a result, certain aspects of the execution environment that are malleable in MATLAB<br \/>\nbecome fixed or constant in a deployed application. Perhaps the most important of these is the mechanism by which MATLAB locates<br \/>\nfunctions and data files: MATLAB's search paths.<\/p>\n<p>A <i>path<\/i> consists of a list of directories that MATLAB searches to find files. MATLAB typically searches a path in list order, stopping<br \/>\nat the first file that matches the search criteria. MATLAB uses paths for two reasons: to determine which functions to execute;<br \/>\nand to locate data files in the file system.<\/p>\n<p>MATLAB primarily interacts with four paths, two internal and two external: the MATLAB path; the MATLAB Java class path; the system path; and the system load library path.<\/p>\n<p>Most familar, perhaps, is the MATLAB path, which affects how MATLAB determines which MATLAB function files to run and which MAT-files to open. Though the MATLAB path is the most visible, of nearly equal importance is the MATLAB Java class<br \/>\npath, which specifies the directories in which MATLAB searches for Java functions. The two external paths list the locations<br \/>\nwhich the operating system will look for executables and shared libraries, respectively. The Windows operating system uses<br \/>\nthe same path to look for executables and shared libraries, but most Unix systems search separate paths for these two types<br \/>\nof files.<\/p>\n<p>When writing an application intended for deployment via the <a href=\"https:\/\/www.mathworks.com\/products\/compiler\">MATLAB Compiler<\/a>, keep in mind that MATLAB applications typically interact with paths in at least three independent ways:<\/p>\n<div>\n<ul>\n<li>Executing MATLAB commands to change a path<\/li>\n<li>Passing paths as arguments to MATLAB functions<\/li>\n<li>Relying on the existence or structure of external paths<\/li>\n<\/ul>\n<\/div>\n<p>After briefly listing some general guidelines for safely interacting with paths in MATLAB, I provide more detailed techniques<br \/>\nto manage problems that can occur in each of these areas.<\/p>\n<h3>General Guidelines<a name=\"2\"><\/a><\/h3>\n<p>A compiled application behaves more consistently if it:<\/p>\n<div>\n<ul>\n<li>Does not change any path during execution.<\/li>\n<li>Uses relative paths (or anchors paths to a known root via the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/matlabroot.html\"><tt>matlabroot<\/tt><\/a> or <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/ctfroot.html\"><tt>ctfroot<\/tt><\/a> functions).<\/li>\n<li>Avoids accessing or changing the current directory.<\/li>\n<\/ul>\n<\/div>\n<p>These guidelines become more important when the compiled application executes in an envrionment that differs from the one<br \/>\nin which it was developed: for example, when installed at a customer site.<\/p>\n<p>In cases where it is convenient to keep path management commands in your M-files when they run in MATLAB, you can use the<br \/>\n<a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/isdeployed.html\"><tt>isdeployed<\/tt><\/a> function to skip over calls to path management functions in deployed applications. For example, this M-code adds my \"beta\"-quality<br \/>\nM-files to the path when my applications run in MATLAB:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\"><span style=\"color: #0000ff;\">if<\/span> ~isdeployed\r\n    addpath <span style=\"color: #a020f0;\">\/home\/pwebb\/mfiles\/beta<\/span>\r\n<span style=\"color: #0000ff;\">end<\/span><\/pre>\n<h3>MATLAB Commands that Directly Access the Path<a name=\"3\"><\/a><\/h3>\n<p>All M-file and Java functions rely on the state of MATLAB's internal paths, but only a few MATLAB commands directly access<br \/>\nor modify these paths. Most of these functions should be avoided in deployed applications because they have the potential<br \/>\nto change the way the application works, either by changing the functions it calls or the data files it loads.<\/p>\n<table>\n<tbody>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/addpath.html\"> <tt>addpath<\/tt><\/a>:<\/td>\n<td>Add<br \/>\na directory to the MATLAB search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/cd.html\"><br \/>\n<tt>cd<\/tt>:<\/a><\/td>\n<td>Change the current directory.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javaaddpath.html\"><br \/>\n<tt>javaaddpath<\/tt><\/a>:<\/td>\n<td>Add a directory to MATLAB's Java search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javaclasspath.html\"><br \/>\n<tt>javaclasspath<\/tt><\/a>:<\/td>\n<td>Get or set MATLAB's Java search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javarmpath.html\"><br \/>\n<tt>javarmpath<\/tt><\/a>:<\/td>\n<td>Remove a directory from MATLAB's Java search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/path.html\"><br \/>\n<tt>path<\/tt><\/a>:<\/td>\n<td>Get or set the MATLAB search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/rmpath.html\"><br \/>\n<tt>rmpath<\/tt><\/a>:<\/td>\n<td>Remove a directory from MATLAB's search path.<\/td>\n<\/tr>\n<tr>\n<td><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/savepath.html\"><br \/>\n<tt>savepath<\/tt><\/a>:<\/td>\n<td>Save the current MATLAB path.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Path management commands often appear in startup or initialization code; when it comes time to deploy your application, you<br \/>\nmay have forgotten that the application relies on these path settings. Problematic path settings sometimes occur in these<br \/>\noft-forgotten files:<\/p>\n<table>\n<tbody>\n<tr>\n<td style=\"vertical-align: top;\"><tt>pathdef<\/tt>:<\/td>\n<td>Used by MATLAB to establish the initial MATLAB search path, <tt>pathdef.m<\/tt> may be modified,<br \/>\nin particular by the <tt>savepath<\/tt> command.<\/td>\n<\/tr>\n<tr>\n<td style=\"vertical-align: top;\"><a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/startup.html\"><br \/>\n<tt>startup<\/tt><\/a>:<\/td>\n<td>The MATLAB Compiler incorporates <tt>startup.m<\/tt> into every generated executable and shared<br \/>\nlibrary; any path management commands in <tt>startup.m<\/tt> therefore need to work in the deployed application. Directories<br \/>\nadded to MATLAB path by <tt>startup.m<\/tt> are automatically added to the MATLAB path in a deployed application by the MATLAB<br \/>\nCompiler if the deployed application uses any files from those directories, thus making the <tt>addpath<\/tt> calls in <tt>startup.m<\/tt><br \/>\nboth redundant and dangerous.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Protect all calls to path management functions in these files by enclosing them in an <tt>~isdeployed<\/tt> <tt>if<\/tt>-block.<\/p>\n<div class=\"hlist\">addpath,<br \/>\npath, rmpath<\/div>\n<div class=\"content\">Getting the MATLAB search path is safe, but setting it is not: a deployed application<br \/>\nexpects its MATLAB path to remain constant. If a directory is on the MATLAB search path in a deployed application, there's<br \/>\na code path through the application that uses at least one file in that directory. During program execution (as opposed to<br \/>\nMATLAB startup or initialization) <tt>addpath<\/tt> is often used to navigate through MATLAB's flat function namespace, and<br \/>\nchange the order in which MATLAB searches directories for matching file names. Don't use <tt>rmpath<\/tt> in a deployed application,<br \/>\nas it will almost surely cause undefined function errors. All of the MATLAB Deployment products prune the MATLAB search path<br \/>\nto exclude unused directories.<\/div>\n<p><b>Instead<\/b>: Ask yourself why you're changing the path. Rename functions or use <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/object-oriented-programming.html\"> MATLAB Objects<\/a> to manage your<br \/>\nfunction namespace. Change the path before running the MATLAB Compiler to add optional or conditional functionality to your<br \/>\napplication.<\/p>\n<\/div>\n<div class=\"hlist\">cd<\/div>\n<div class=\"content\">Try to avoid using the <tt>cd<\/tt> command<br \/>\nin deployed applications because it creates implicit dependencies between the application and the structure of the file system.<br \/>\nIf the machine running the application does not meet these requirements, the application will fail in confusing ways.<\/div>\n<p><b>Instead<\/b>:<br \/>\nUse paths relative to <tt>matlabroot<\/tt> or <tt>ctfroot<\/tt>.<\/p>\n<p>Change code like this:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">cd <span style=\"color: #a020f0;\">my\/data\/directory<\/span>\r\nfp = fopen(<span style=\"color: #a020f0;\">'data.file'<\/span>, <span style=\"color: #a020f0;\">'r'<\/span>);<\/pre>\n<p>To code like this:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">fp = fopen(fullfile(ctfroot, <span style=\"color: #a020f0;\">'my'<\/span>, <span style=\"color: #a020f0;\">'data'<\/span>, <span style=\"color: #a020f0;\">'directory'<\/span>, <span style=\"color: #a020f0;\">'data.file'<\/span>));<\/pre>\n<p>&nbsp;<\/p>\n<div class=\"hlist\">javaaddpath, javaclasspath, javarmpath<\/div>\n<div class=\"content\">Like <tt>addpath<\/tt><br \/>\ndoes for the MATLAB search path, <tt>javaaddpath<\/tt> adds a directory to MATLAB's Java search path. <tt>javaclasspath<\/tt><br \/>\ngets or sets MATLAB's Java search path. While getting the Java class path, e.g., <tt> jcp = javaclasspath<\/tt>, is completely<br \/>\nsafe, setting it can lead to problems in deployed applications. Removing directories from the Java class path will likely<br \/>\nresult in undefined function errors.<b>Instead<\/b>: Set the Java class path before running the MATLAB Compiler. Use<br \/>\n<a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_external\/java-class-path.html\"> <tt>classpath.txt<\/tt><\/a> or<br \/>\n<tt>javaaddpath<\/tt>.<\/div>\n<div class=\"hlist\">savepath<\/div>\n<div class=\"content\"><tt>savepath<\/tt> saves the current<br \/>\npath by overwriting <tt>pathdef.m<\/tt>. In a deployed application, this would create an unencrypted <tt>pathdef.m<\/tt> which<br \/>\ncould not be run. Therefore <tt>savepath<\/tt> issues an error message when run from a deployed application.<b>Instead<\/b>:<br \/>\nIf you must save the path, save it to a MAT-file; otherwise, enclose the call to <tt>savepath<\/tt> in an <tt>~isdeployed<\/tt><br \/>\n<tt>if<\/tt>-block.<\/div>\n<p>&nbsp;<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">p = path;\r\nsave <span style=\"color: #a020f0;\">savedpath<\/span> <span style=\"color: #a020f0;\">p<\/span><\/pre>\n<p>As further incentive to avoid these functions in deployed applications, please note the commands that change the Java class<br \/>\npath (<tt>javaaddpath<\/tt>, <tt>javarmpath<\/tt>) also clear the values of global variables.<\/p>\n<p>For more details on how to manage the MATLAB function namespace with MATLAB objects, please see the polynomial example in the MATLAB documentation.<\/p>\n<h3>Paths as Arguments to MATLAB Functions<a name=\"7\"><\/a><\/h3>\n<p>Many MATLAB programs assume that the directory structure of the filesystem cannot change. When this assumption leads to the<br \/>\nuse of absolute paths in file names, e.g., <tt>load('c:\/Work\/MATLAB\/data.mat')<\/tt> or an implicit dependency on MATLAB's ability to locate a file, e.g., <tt>load data.mat<\/tt>, it creates problems for deployed applications. A deployed application is very likely going to be installed on a machine<br \/>\nthat has neither the same directory structure nor the access to the same filesystem as the machine on which it was developed.<br \/>\nThe use of absolute paths causes errors because of differences between the development and the deployment file system structures.<br \/>\nBut relying entirely on relative paths establishes a fragile dependency on the location of the current directory. The solution:<br \/>\nbase all file locations on a known root.<\/p>\n<p>In MATLAB, there are typically two file system roots that matter: the root of the external file system, typically <tt>\/<\/tt> or <tt>c:\/<\/tt> on Unix and Windows systems respectively; and the MATLAB root, the directory in which MATLAB has been installed. In a deployed<br \/>\napplication there is an additional root: the CTF root, which is the location of the application's MATLAB content (M-files,<br \/>\ndata files, JAR files -- everything that the MATLAB Compiler put into the application's CTF file). In MATLAB <tt>ctfroot<\/tt> and <tt>matlabroot<\/tt> refer to the same directory: MATLAB's installation directory. In a deployed application, <tt>matlabroot<\/tt> refers to the directory in which the MATLAB Common Runtime (the MCR) is installed and <tt>ctfroot<\/tt> to the CTF root.<\/p>\n<p>Deployed applications typically base their file names on the the CTF root. For example, assume an application that reads and<br \/>\nwrites MAT files. To ensure that the MATLAB Compiler includes the input data files in the CTF archive, specify the data files<br \/>\nwith <a href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/mcc.html\"><tt>mcc<\/tt><\/a>'s <tt>-a<\/tt> (add) flag:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">mcc <span style=\"color: #a020f0;\">fcn.m<\/span> <span style=\"color: #a020f0;\">-a<\/span> <span style=\"color: #a020f0;\">data.mat<\/span><\/pre>\n<p>In the application code, use <tt>which<\/tt> or <tt>ctfroot<\/tt> to construct a full path to the files being loaded or saved.<\/p>\n<p>Use <tt>which<\/tt> when a known filename exists on the application's path:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">[pathstr,name]=fileparts(which(<span style=\"color: #a020f0;\">'data.mat'<\/span>));\r\n<span style=\"color: #228b22;\">% Load x from the MAT file<\/span>\r\nload(name);\r\nx = x + 17;\r\n<span style=\"color: #228b22;\">% Save x back to the MAT file<\/span>\r\nsave(fullfile(pathstr, <span style=\"color: #a020f0;\">'data.mat'<\/span>), x);<\/pre>\n<p>Use <tt>ctfroot<\/tt> when creating a new file:<\/p>\n<pre style=\"background: #F9F7F3; padding: 10px; border: 1px solid #c8c8c8;\">data = input(<span style=\"color: #a020f0;\">'Enter data: '<\/span>);\r\nsave(fullfile(ctfroot, <span style=\"color: #a020f0;\">'more_data.mat'<\/span>), data, <span style=\"color: #a020f0;\">'-append'<\/span>);<\/pre>\n<p>This use of <tt>ctfroot<\/tt> assumes that the application has permission to write to the file system on the deployment machine. This is not always true<br \/>\nby default, especially with network installations. Work with your IT department to secure the appropriate file system access.<\/p>\n<h3>Relying on the Structure of External Paths<a name=\"11\"><\/a><\/h3>\n<p>A MATLAB application that uses the <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/system.html\"><tt>system<\/tt><\/a> or <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/loadlibrary.html\"><tt>loadlibrary<\/tt><\/a> functions or calls MEX files linked to non-MathWorks shared libraries has a dependency on the external system paths. The<br \/>\n<tt>system<\/tt> command allows MATLAB programs to directly execute operating system commands and capture their output as text. This can be<br \/>\nvery convenient, but it of course requires that the command be available in the current file system. <tt>loadlibrary<\/tt> allows MATLAB programs to load shared libraries and call their exported APIs; it similarly requires that the library in question<br \/>\nbe available on the deployment machine's file system.<\/p>\n<p>The techniques for managing external path dependencies are very similar to those used to manage internal path dependencies:<br \/>\nuse full paths, favor explicit dependencies over implicit ones, and include all required files in the deployed application.<\/p>\n<div>\n<ul>\n<li>Use full path names, rooted in the <tt>ctfroot<\/tt>, to specify the arguments to the <tt>system<\/tt> and <tt>loadlibrary<\/tt> functions.<\/li>\n<li>Include non-standard applications and shared libraries in the deployed application by using <tt>mcc<\/tt>'s <tt>-a<\/tt> switch.<\/li>\n<li>Ensure the necessary applications and libraries are present on the deployment machine or in a network location accessible<br \/>\nfrom the deployment machine.<\/li>\n<\/ul>\n<\/div>\n<h3>Next Up: Non-supported functions<a name=\"12\"><\/a><\/h3>\n<p>The next post in this series will explore mechanisms for identifying and managing calls to non-supported functions. In the<br \/>\nmeantime, you can refer to the <a href=\"https:\/\/www.mathworks.com\/help\/compiler\/index.html\">documentation<\/a> for the MATLAB Compiler or post follow-up questions <a href=\"https:\/\/blogs.mathworks.com\/loren\/?p=150#respond\">here<\/a>.<\/p>\n<p><script>\/\/ <![CDATA[\nfunction grabCode_1aabaf6d3964456894a3a7594d40dffc() {\n        \/\/ Remember the title so we can use it in the new page\n        title = document.title;\n\n        \/\/ Break up these strings so that their presence\n        \/\/ in the Javascript doesn't mess up the search for\n        \/\/ the MATLAB code.\n        t1='1aabaf6d3964456894a3a7594d40dffc ' + '##### ' + 'SOURCE BEGIN' + ' #####';\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 1aabaf6d3964456894a3a7594d40dffc';\n    \n        b=document.getElementsByTagName('body')[0];\n        i1=b.innerHTML.indexOf(t1)+t1.length;\n        i2=b.innerHTML.indexOf(t2);\n \n        code_string = b.innerHTML.substring(i1, i2);\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\n\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \n        \/\/ in the XML parser.\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\n        \/\/ doesn't go ahead and substitute the less-than character. \n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\n\n        author = 'Loren Shure';\n        copyright = 'Copyright 2008 The MathWorks, Inc.';\n\n        w = window.open();\n        d = w.document;\n        d.write('\n\n\n\n\n\n\n\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add author and copyright lines at the bottom if specified.\r\n        if ((author.length > 0) || (copyright.length > 0)) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (author.length > 0) {\r\n                d.writeln('% _' + author + '_');\r\n            }\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\n\n\n\n\n\n\n\n\n\\n');\n      \n      d.title = title + ' (MATLAB code)';\n      d.close();\n      }\n\/\/ ]]><\/script><\/p>\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\"><a><span style=\"font-size: x-small; font-style: italic;\">Get<br \/>\nthe MATLAB code<br \/>\n<noscript>(requires JavaScript)<\/noscript><\/span><\/a><\/p>\n<p>Published with MATLAB\u00ae 7.6<\/p>\n<p><!--\n1aabaf6d3964456894a3a7594d40dffc ##### SOURCE BEGIN #####\n%% Path Management in Deployed Applications\n% This week, guest blogger <mailto:pwebb@mathworks.com Peter Webb>\n% continues his series of articles about the MATLAB Compiler. This week's\n% topic: managing MATLAB's paths in a compiled application. For an\n% introduction to writing deployable code, please see the\n% <https:\/\/blogs.mathworks.com\/loren\/2008\/06\/19\/writing-deployable-code\/ % June 19th article>.\n\n%%\n% One of the goals of the compilation process is to turn a flexible and\n% easily modifiable MATLAB progam into a robust software component with\n% consistiently predictable behavior: a compiled application should not be\n% able to change which functions it calls or the way those functions work.\n% As a result, certain aspects of the execution environment that are\n% malleable in MATLAB become fixed or constant in a deployed application.\n% Perhaps the most important of these is the mechanism by which MATLAB\n% locates functions and data files: MATLAB's search paths.\n%\n% A _path_ consists of a list of directories that MATLAB searches to find\n% files. MATLAB typically searches a path in list order, stopping at the\n% first file that matches the search criteria. MATLAB uses paths for two\n% reasons: to determine which functions to execute; and to locate data\n% files in the file system.\n%\n% MATLAB primarily interacts with four paths, two internal and two\n% external: the\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/techdoc\/matlab_env\/f10-26235.html MATLAB path>; the\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/javaaddpath.html % MATLAB Java class path>; the system path; and the system load library\n% path.\n%\n% Most familar, perhaps, is the MATLAB path, which affects how\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/techdoc\/matlab_env\/f10-26235.html#f10-26295 MATLAB determines which MATLAB function files to run>\n% and which MAT-files to open. Though the MATLAB path is the most visible,\n% of nearly equal importance is the MATLAB Java class path, which specifies\n% the directories in which MATLAB searches for Java functions. The two\n% external paths list the locations which the operating system will look\n% for executables and shared libraries, respectively. The Windows operating\n% system uses the same path to look for executables and shared libraries,\n% but most Unix systems search separate paths for these two types of files.\n%\n% When writing an application intended for deployment via the\n% <https:\/\/www.mathworks.com\/products\/compiler MATLAB Compiler>, keep in\n% mind that MATLAB applications typically interact with paths in at least\n% three independent ways:\n%\n% * Executing MATLAB commands to change a path\n% * Passing paths as arguments to MATLAB functions\n% * Relying on the existence or structure of external paths\n%\n% After briefly listing some general guidelines for safely interacting with\n% paths in MATLAB, I provide more detailed techniques to manage\n% problems that can occur in each of these areas.\n\n%% General Guidelines\n% A compiled application behaves more consistently if it:\n%\n% * Does not change any path during execution.\n% * Uses relative paths (or anchors paths to a known root via the\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/matlabroot.html % |matlabroot|> or\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/ctfroot.html % |ctfroot|> functions).\n% * Avoids accessing or changing the current directory.\n%\n% These guidelines become more important when the compiled application\n% executes in an envrionment that differs from the one in which it was\n% developed: for example, when installed at a customer site.\n%\n% In cases where it is convenient to keep path management commands in\n% your M-files when they run in MATLAB, you can use the\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/isdeployed.html % |isdeployed|> function to skip over calls to path management functions in\n% deployed applications. For example, this M-code adds my \"beta\"-quality\n% M-files to the path when my applications run in MATLAB:\nif ~isdeployed\naddpath \/home\/pwebb\/mfiles\/beta\nend\n\n%% MATLAB Commands that Directly Access the Path\n% All M-file and Java functions rely on the state of MATLAB's internal\n% paths, but only a few MATLAB commands directly access or modify these\n% paths. Most of these functions should be avoided in deployed applications\n% because they have the potential to change the way the application works,\n% either by changing the functions it calls or the data files it loads.\n%\n% <html>\n%\n\n\n<table>\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/addpath.html\">\n% <tt>addpath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Add a directory to the MATLAB search path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/cd.html\">\n% <tt>cd<\/tt>:<\/a><\/td>\n\n\n\n\n<td>Change the current directory.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javaaddpath.html\">\n% <tt>javaaddpath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Add a directory to MATLAB's Java search\n% path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javaclasspath.html\">\n% <tt>javaclasspath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Get or set MATLAB's Java search path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/javarmpath.html\">\n% <tt>javarmpath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Remove a directory from MATLAB's Java search\n% path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/path.html\">\n% <tt>path<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Get or set the MATLAB search path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/rmpath.html\">\n% <tt>rmpath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Remove a directory from MATLAB's search path.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/savepath.html\">\n% <tt>savepath<\/tt><\/a>:<\/td>\n\n\n\n\n<td>Save the current MATLAB path.<\/td>\n\n\n<\/tr>\n\n\n%<\/table>\n\n\n% <\/html>\n%\n% Path management commands often appear in startup or initialization code;\n% when it comes time to deploy your application, you may have forgotten\n% that the application relies on these path settings. Problematic path settings\n% sometimes occur in these oft-forgotten files:\n%\n% <html>\n%\n\n\n<table>\n%\n\n\n<tr>\n\n\n<td style=\"vertical-align: top\"><a % href=\"https:\/\/www.mathworks.com\/access\/helpdesk\/help\/techdoc\/ref\/pathdef.html\">\n% <tt>pathdef<\/tt><\/a>:<\/td>\n\n\n\n\n<td>\n% Used by MATLAB to establish the initial MATLAB search path,\n% <tt>pathdef.m<\/tt> may be modified, in particular by the\n% <tt>savepath<\/tt> command.<\/td>\n\n\n<\/tr>\n\n\n%\n\n\n<tr>\n\n\n<td style=\"vertical-align: top\"><a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/ref\/startup.html\">\n% <tt>startup<\/tt><\/a>:<\/td>\n\n\n\n\n<td>\n% The MATLAB Compiler incorporates <tt>startup.m<\/tt> into every\n% generated executable and shared library; any path management commands\n% in <tt>startup.m<\/tt> therefore need to work in the deployed application.\n% Directories added to MATLAB path by <tt>startup.m<\/tt> are automatically\n% added to the MATLAB path in a deployed application by the MATLAB Compiler\n% if the deployed application uses any files from those directories, thus\n% making the <tt>addpath<\/tt> calls in <tt>startup.m<\/tt> both redundant and dangerous.\n%<\/td>\n\n\n<\/tr>\n\n\n%<\/table>\n\n\n% <\/html>\n%\n% Protect all calls to path management functions in these files by\n% enclosing them in an |~isdeployed| |if|-block.\n%\n% <html>\n%\n\n\n\n<style type=\"text\/css\">\n% .hlist { color: #990000; font-family: monospace; font-weight: bold; }\n% <\/style>\n\n%\n\n\n<div class=\"hlist\">addpath, path, rmpath<\/div>\n\n\n\n\n<div class=\"content\">\n% Getting the MATLAB search path is safe, but setting it is not: a deployed\n% application expects its MATLAB path to remain constant. If a directory\n% is on the MATLAB search path in a deployed application, there's a code path\n% through the application that uses at least one file in that directory.\n% During program execution (as opposed to\n% MATLAB startup or initialization) <tt>addpath<\/tt> is often used to\n% navigate through MATLAB's flat function namespace, and change the order\n% in which MATLAB searches directories for matching file names.\n% Don't use <tt>rmpath<\/tt> in a deployed application, as it will almost surely\n% cause undefined function errors. All of the MATLAB Deployment products\n% prune the MATLAB search path to exclude unused directories.\n\n%<b>Instead<\/b>: Ask yourself why you're changing the path.\n% Rename functions or use <a % href=\"https:\/\/www.mathworks.com\/help\/matlab\/object-oriented-programming.html\">\n% MATLAB Objects<\/a> to manage your function\n% namespace. Change the path before running the MATLAB Compiler to add\n% optional or conditional functionality to your application.\n\n<\/div>\n\n\n% <\/html>\n% <html>\n%\n\n\n<div class=\"hlist\">cd<\/div>\n\n\n\n\n<div class=\"content\">Try to avoid using the <tt>cd<\/tt> command in\n% deployed applications because it creates implicit dependencies between the\n% application and the structure of the file system. If the machine running\n% the application does not meet these requirements, the application will\n% fail in confusing ways.\n%\n\n<b>Instead<\/b>: Use paths relative to <tt>matlabroot<\/tt> or <tt>ctfroot<\/tt>.\n% <\/html>\n%\n% Change code like this:\ncd my\/data\/directory\nfp = fopen('data.file', 'r');\n%%%\n% To code like this:\nfp = fopen(fullfile(ctfroot, 'my', 'data', 'directory', 'data.file'));\n%%%\n% <html>\n%\n\n<\/div>\n\n\n%\n\n\n<div class=\"hlist\">javaaddpath, javaclasspath, javarmpath<\/div>\n\n\n\n\n<div class=\"content\">\n% Like <tt>addpath<\/tt> does for the MATLAB\n% search path, <tt>javaaddpath<\/tt> adds a directory to MATLAB's Java search path.\n% <tt>javaclasspath<\/tt> gets or sets\n% MATLAB's Java search path. While getting the Java class path, e.g., <tt> jcp =\n% javaclasspath<\/tt>, is completely safe, setting it can lead to problems\n% in deployed applications.\n% Removing directories from the Java class path will likely result in\n% undefined function errors.\n%\n\n<b>Instead<\/b>: Set the Java class path before running the MATLAB Compiler.\n%  Use <a href=\"https:\/\/www.mathworks.com\/help\/matlab\/matlab_external\/java-class-path.html\">\n% <tt>classpath.txt<\/tt><\/a> or <tt>javaaddpath<\/tt>.\n\n<\/div>\n\n\n%\n\n\n<div class=\"hlist\">savepath<\/div>\n\n\n\n\n<div class=\"content\">\n% <tt>savepath<\/tt> saves the current path by\n% overwriting <tt>pathdef.m<\/tt>. In a deployed application, this would create an\n% unencrypted <tt>pathdef.m<\/tt> which could not be run. Therefore <tt>savepath<\/tt> issues\n% an error message when run from a deployed application.\n%\n\n<b>Instead<\/b>: If you must\n% save the path, save it to a MAT-file; otherwise, enclose the call to\n% <tt>savepath<\/tt>\n% in an <tt>~isdeployed<\/tt> <tt>if<\/tt>-block.\n\n<\/div>\n\n\n% <\/html>\n\np = path;\nsave savedpath p\n%%%\n% As further incentive to avoid these functions in deployed applications,\n% please note the commands that change the Java class path (|javaaddpath|,\n% |javarmpath|) also clear the values of global variables.\n%\n% For more details on how to manage the MATLAB function namespace with\n% MATLAB objects, please see the\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/techdoc\/matlab_oop\/f3-28024.html polynomial example>\n% in the MATLAB documentation.\n\n%% Paths as Arguments to MATLAB Functions\n% Many MATLAB programs assume that the directory structure of the\n% filesystem cannot change. When this assumption leads to the use of absolute\n% paths in file names, e.g., |load('c:\/Work\/MATLAB\/data.mat')| or\n% an implicit dependency on MATLAB's ability to locate a file, e.g.,\n% |load data.mat|, it creates problems for deployed applications.\n% A deployed application is very likely going to be installed on a machine\n% that has neither the same directory structure nor the access to the same\n% filesystem as the machine on which it was developed. The use of absolute paths\n% causes errors because of differences between the development and the\n% deployment file system structures. But relying entirely on relative paths\n% establishes a fragile dependency on the location of the current\n% directory. The solution: base all file locations on a known root.\n%\n% In MATLAB, there are typically two file system roots that matter:\n% the root of the external file system, typically |\/| or |c:\/| on Unix and\n% Windows systems respectively; and the MATLAB root, the directory in which\n% MATLAB has been installed. In a deployed application there is an\n% additional root: the CTF root, which is the location of the application's\n% MATLAB content (M-files, data files, JAR files REPLACE_WITH_DASH_DASH everything that the\n% MATLAB Compiler put into the application's CTF file). In MATLAB |ctfroot|\n% and |matlabroot| refer to the same directory: MATLAB's installation\n% directory. In a deployed application, |matlabroot| refers to the\n% directory in which the\n% <https:\/\/www.mathworks.com\/help\/compiler\/index.htmlf12-999353.html MATLAB Common Runtime>\n% (the MCR) is installed and |ctfroot| to the CTF root.\n%\n% Deployed applications typically base their file names on the the CTF\n% root. For example, assume an application that reads and writes MAT files.\n% To ensure that the MATLAB Compiler includes the input data files in the\n% CTF archive, specify the data files with\n% <https:\/\/www.mathworks.com\/access\/helpdesk\/help\/toolbox\/compiler\/mcc.html |mcc|>'s\n% |-a| (add) flag:\nmcc fcn.m -a data.mat\n%%%\n% In the application code, use |which| or |ctfroot| to construct a full\n% path to the files being loaded or saved.\n%\n% Use |which| when a known filename exists on the application's path:\n[pathstr,name]=fileparts(which('data.mat'));\n% Load x from the MAT file\nload(name);\nx = x + 17;\n% Save x back to the MAT file\nsave(fullfile(pathstr, 'data.mat'), x);\n%%%\n% Use |ctfroot| when creating a new file:\ndata = input('Enter data: ');\nsave(fullfile(ctfroot, 'more_data.mat'), data, '-append');\n%%%\n% This use of |ctfroot| assumes that the application has permission to\n% write to the file system on the deployment machine. This is not always\n% true by default, especially with network installations. Work with your IT\n% department to secure the appropriate file system access.\n\n%% Relying on the Structure of External Paths\n% A MATLAB application that uses the\n% <https:\/\/www.mathworks.com\/help\/matlab\/ref\/system.html % |system|> or <https:\/\/www.mathworks.com\/help\/matlab\/ref\/loadlibrary.html % |loadlibrary|> functions or calls MEX files linked to non-MathWorks\n% shared libraries has a dependency on the external system paths. The\n% |system| command allows MATLAB programs to directly execute operating\n% system commands and capture their output as text. This can be very\n% convenient, but it of course requires that the command be available in\n% the current file system. |loadlibrary| allows MATLAB programs to load\n% shared libraries and call their exported APIs; it similarly requires that\n% the library in question be available on the deployment machine's file\n% system.\n%\n% The techniques for managing external path dependencies are very similar\n% to those used to manage internal path dependencies: use full paths, favor\n% explicit dependencies over implicit ones, and include all required files\n% in the deployed application.\n%\n% * Use full path names, rooted in the |ctfroot|, to specify the arguments\n% to the |system| and |loadlibrary| functions.\n% * Include non-standard applications and shared libraries in the deployed\n% application by using |mcc|'s |-a| switch.\n% * Ensure the necessary applications and libraries are present on the\n% deployment machine or in a network location accessible from the\n% deployment machine.\n%\n\n%% Next Up: Non-supported functions\n% The next post in this series will explore mechanisms for identifying\n% and managing calls to non-supported functions. In the meantime,\n% you can refer to the <https:\/\/www.mathworks.com\/help\/compiler\/index.html documentation>\n% for the MATLAB Compiler or post follow-up questions\n% <https:\/\/blogs.mathworks.com\/loren\/?p=150#respond here>.\n\n##### SOURCE END ##### 1aabaf6d3964456894a3a7594d40dffc\n--><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\nThis week, guest blogger Peter Webb continues his series of articles about the MATLAB Compiler. This week's topic: managing MATLAB's paths in a compiled application.<br \/>\nFor an introduction to writing... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/loren\/2008\/08\/11\/path-management-in-deployed-applications\/\">read more >><\/a><\/p>\n","protected":false},"author":39,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[16,24],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/150"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/users\/39"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/comments?post=150"}],"version-history":[{"count":3,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/150\/revisions"}],"predecessor-version":[{"id":1835,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/posts\/150\/revisions\/1835"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/media?parent=150"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/categories?post=150"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/loren\/wp-json\/wp\/v2\/tags?post=150"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}