{"id":1020,"date":"2017-08-21T13:18:24","date_gmt":"2017-08-21T17:18:24","guid":{"rendered":"https:\/\/blogs.mathworks.com\/developer\/?p=1020"},"modified":"2017-08-22T05:11:55","modified_gmt":"2017-08-22T09:11:55","slug":"packaging-pitfalls","status":"publish","type":"post","link":"https:\/\/blogs.mathworks.com\/developer\/2017\/08\/21\/packaging-pitfalls\/","title":{"rendered":"Packaging Pitfalls"},"content":{"rendered":"<div class=\"content\">\r\n\r\n<!--introduction-->\r\n\r\n<i>Hello readers, today we have another post from <a href=\"https:\/\/www.mathworks.com\/services\/consulting\/meet-our-team.html#amy_koh\">Amy<\/a>, who is here to share more of her valuable experience deploying toolboxes. Take note of some of these tips after you have thoroughly enjoyed any eclipse observations you have been lucky enough to witness this time around. Just like looking at an eclipse directly is something you want to avoid, so are these packaging anti-patterns. Take it away Amy!<\/i>\r\n\r\n<!--\/introduction-->\r\n\r\n<br\/>\r\n<br\/>\r\n\r\n<p><b>What are some common pitfalls when packaging a toolbox?<\/b><\/p>\r\n\r\n<p>In one of my <a href=\"https:\/\/blogs.mathworks.com\/developer\/2017\/01\/13\/matlab-toolbox-best-practices\/\">previous posts<\/a>, I described how to set up your development environment in MATLAB when developing and packaging a MATLAB toolbox. In this post, I'll share ways to avoid common pitfalls which can cause the toolbox packaging process to fail.<\/p>\r\n\r\n<p><b>Toolbox project file contains absolute paths to files<\/b><\/p>\r\n\r\n<p>It's important to understand how the project file (<tt>.prj<\/tt>) handles paths to ensure that they function correctly irrespective of the absolute sandbox path. In my <a href=\"https:\/\/blogs.mathworks.com\/developer\/2017\/01\/13\/matlab-toolbox-best-practices\/\">other post<\/a>, I recommend that the toolbox content sits below the folder containing the project file (i.e. the \"project root folder\") in the folder hierarchy. In this case, the project file stores paths relative to the project root folder.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/y2017PackagingFullpaths.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nWhen the project content is not below the project root folder, including the case when the project content is directly <i>*in<\/i>* the project root folder, the project file stores absolute paths. If someone attempts to use such a project file in another location the file fails to load.<\/p>\r\n\r\n<p><b>Sandbox code not on the MATLAB path<\/b><\/p>\r\n\r\n<p>Make sure that the sandbox code is always on the MATLAB path when packaging. Prior to R2016a, if the packaged folders are not on your path when packaging, they won't be added to the user path when your user installs the package, even though the content is installed. Consequently, users won't be able to access the toolbox functionality without manually adding the toolbox folder to the path. From R2016a, you can select which toolbox folders are added to the user's MATLAB path when they install a toolbox. By default, the list includes any of the toolbox folders that are on your path when you package the toolbox. You can exclude folders from being added to the user's path by clearing them from the list.\r\n\r\n<a href=\"https:\/\/blogs.mathworks.com\/developer\/files\/install_path.png\"><img decoding=\"async\" loading=\"lazy\" width=\"768\" height=\"200\" class=\"aligncenter size-full wp-image-1031\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/install_path.png\" alt=\"\" \/><\/a>\r\n\r\nIt's useful to write scripts for adding and removing sandbox code, i.e. <tt>addsandbox.m<\/tt> and <tt>rmsandbox.m<\/tt>, from the MATLAB path. Always make sure to run <tt>addsandbox.m<\/tt> when packaging and <tt>rmsandbox.m<\/tt> before testing the packaged content.<p>\r\n\r\n<p><b>Accidentally resetting your GUID<\/b><\/p>\r\n\r\n<p>Each project file (<tt>.prj<\/tt>) is associated with a unique identifier or GUID. MATLAB uses this identifier to manage the toolbox upgrade and installation process. When a new version of a toolbox is installed, MATLAB removes older versions of the toolbox packaged using the same project file. Essentially these are <tt>.mltbx<\/tt> files that can be identified using the same GUID. However, if a new version is packaged using a new or different project file, MATLAB will recognise these as two separate toolboxes even though they might have the same name.<\/p>\r\n\r\n<p><b>Conflicting external dependencies<\/b><\/p>\r\n\r\n<p>MATLAB checks and identifies external files required for your toolbox code to run during the packaging process.\r\n\r\n<img decoding=\"async\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/y2017PackagingDependencyConflicts.png\" alt=\"\" hspace=\"5\" vspace=\"5\" \/>\r\n\r\nYou can choose to exclude any files you don't want. Again, the project file (<tt>.prj<\/tt>) stores the absolute path of these external files when they are not below the project root folder. If someone tries to repackage the toolbox in another location using the same project file, but doesn't have the same environment set up, the packaging process will fail. For ease of portability I recommend excluding external files from your packaged toolbox. You can remove these external dependencies from your MATLAB path when packaging so that MATLAB doesn't identify them.\r\n\r\nWhen external dependencies are excluded from the packaged toolbox, you'll want to check that the users have installed these prior to running your toolbox code. If the external dependencies are MATLAB toolboxes, you can use the <tt><a href=\"http:\/\/uk.mathworks.com\/help\/matlab\/ref\/matlab.addons.toolbox.installtoolbox.html\">matlab.addons.toolbox.installToolboxes<\/a><\/tt> API to query information about installed toolboxes from R2016a. Otherwise, if a toolbox contains a <tt>Contents.m<\/tt> file, users can query version information of the toolbox using the <tt>ver<\/tt> command.<\/p>\r\n\r\n<p><b>Thoughts?<\/b><\/p>\r\n\r\nDo you have any experiences to share that can help avoid packaging pitfalls? If so, let me know about it in the comments!\r\n\r\n<script language=\"JavaScript\"> <!-- \r\n    function grabCode_51884fd2870e4726ada1139bf42f02d0() {\r\n        \/\/ Remember the title so we can use it in the new page\r\n        title = document.title;\r\n\r\n        \/\/ Break up these strings so that their presence\r\n        \/\/ in the Javascript doesn't mess up the search for\r\n        \/\/ the MATLAB code.\r\n        t1='51884fd2870e4726ada1139bf42f02d0 ' + '##### ' + 'SOURCE BEGIN' + ' #####';\r\n        t2='##### ' + 'SOURCE END' + ' #####' + ' 51884fd2870e4726ada1139bf42f02d0';\r\n    \r\n        b=document.getElementsByTagName('body')[0];\r\n        i1=b.innerHTML.indexOf(t1)+t1.length;\r\n        i2=b.innerHTML.indexOf(t2);\r\n \r\n        code_string = b.innerHTML.substring(i1, i2);\r\n        code_string = code_string.replace(\/REPLACE_WITH_DASH_DASH\/g,'--');\r\n\r\n        \/\/ Use \/x3C\/g instead of the less-than character to avoid errors \r\n        \/\/ in the XML parser.\r\n        \/\/ Use '\\x26#60;' instead of '<' so that the XML parser\r\n        \/\/ doesn't go ahead and substitute the less-than character. \r\n        code_string = code_string.replace(\/\\x3C\/g, '\\x26#60;');\r\n\r\n        copyright = 'Copyright 2017 The MathWorks, Inc.';\r\n\r\n        w = window.open();\r\n        d = w.document;\r\n        d.write('<\/p>\r\n<pre>\\n');\r\n        d.write(code_string);\r\n\r\n        \/\/ Add copyright line at the bottom if specified.\r\n        if (copyright.length > 0) {\r\n            d.writeln('');\r\n            d.writeln('%%');\r\n            if (copyright.length > 0) {\r\n                d.writeln('% _' + copyright + '_');\r\n            }\r\n        }\r\n\r\n        d.write('<\/pre>\r\n<p>\\n');\r\n\r\n        d.title = title + ' (MATLAB code)';\r\n        d.close();\r\n    }   \r\n     --> <\/script>\r\n<p style=\"text-align: right; font-size: xx-small; font-weight: lighter; font-style: italic; color: gray;\">\r\n<a><span style=\"font-size: x-small; font-style: italic;\">Get\r\nthe MATLAB code<noscript>(requires JavaScript)<\/noscript><\/span><\/a>\r\n\r\nPublished with MATLAB\u00ae R2017a<\/p>\r\n\r\n<\/div>\r\n<!--\r\n51884fd2870e4726ada1139bf42f02d0 ##### SOURCE BEGIN #####\r\n%%\r\n% _Hello readers, today we have another post from\r\n% <https:\/\/www.mathworks.com\/services\/consulting\/meet-our-team.html#amy_koh % Amy>, who is here to share more of her valuable experience deploying toolboxes. Take it away Amy!_\r\n%%\r\n% *What are some common pitfalls when packaging a toolbox?*\r\n%\r\n% In one of my\r\n% <https:\/\/blogs.mathworks.com\/developer\/2017\/01\/13\/matlab-toolbox-best-practices\/ % previous posts>, I described how to set up your development environment\r\n% in MATLAB when developing and packaging a MATLAB toolbox. In this post,\r\n% I'll share ways to avoid common pitfalls which can cause the toolbox\r\n% packaging process to fail.\r\n%\r\n%\r\n%%\r\n% *Toolbox project file contains absolute paths to files*\r\n%\r\n% It's important to understand how the project file (|.prj|) handles paths\r\n% to ensure that they function correctly irrespective of the absolute\r\n% sandbox path. In my\r\n% <https:\/\/blogs.mathworks.com\/developer\/2017\/01\/13\/matlab-toolbox-best-practices\/ % other post>, I recommend that the toolbox content sits below the folder\r\n% containing the project file (i.e. the \"project root folder\") in the\r\n% folder hierarchy. In this case, the project file stores paths relative to\r\n% the project root folder.\r\n%\r\n% <<y2017PackagingFullpaths.png>>\r\n%\r\n% When the project content is not below the project root folder, including\r\n% the case when the project content is directly _*in_* the project root folder,\r\n% the project file stores absolute paths. If someone attempts to use such a project\r\n% file in another location the file fails to load.\r\n%\r\n%\r\n%%\r\n% *Sandbox code not on the MATLAB path*\r\n%\r\n% Make sure that the sandbox code is always on the MATLAB path when packaging.\r\n% Prior to R2016a, if the packaged folders are not on your path when packaging,\r\n% they won't be added to the user path when your user installs the package, even\r\n% though the content is installed. Consequently, users won't be able to access\r\n% the toolbox functionality without manually adding the toolbox folder to the\r\n% path.\r\n%\r\n% It's useful to write scripts for adding and removing sandbox code, i.e.\r\n% |addsandbox.m| and |rmsandbox.m|, from the MATLAB path. Always make sure to\r\n% run |addsandbox.m| when packaging and |rmsandbox.m| before testing the packaged\r\n% content.\r\n%\r\n%\r\n%%\r\n% *Accidentally resetting your GUID*\r\n%\r\n% Each project file (|.prj|) is associated with a unique identifier or GUID.\r\n% MATLAB uses this identifier to manage the toolbox upgrade and installation process.\r\n% When a new version of a toolbox is installed, MATLAB removes older versions\r\n% of the toolbox packaged using the same project file. Essentially these are |.mltbx|\r\n% files that can be identified using the same GUID.\r\n%\r\n% However, if a new version is packaged using a new or different project\r\n% file, MATLAB will recognise these as two separate toolboxes even though they\r\n% might have the same name.\r\n%\r\n%\r\n%%\r\n% *Conflicting external dependencies*\r\n%\r\n% MATLAB checks and identifies external files required for your toolbox code\r\n% to run during the packaging process.\r\n%\r\n% <<y2017PackagingDependencyConflicts.png>>\r\n%\r\n% You can choose to exclude any files you don't want. Again, the project\r\n% file (|.prj|) stores the absolute path of these external files when they are\r\n% not below the project root folder. If someone tries to repackage the toolbox\r\n% in another location using the same project file, but doesn't have the same environment\r\n% set up, the packaging process will fail. For ease of portability I recommend\r\n% excluding external files from your packaged toolbox. You can remove these external\r\n% dependencies from your MATLAB path when packaging so that MATLAB doesn't identify\r\n% them.\r\n%\r\n% When external dependencies are excluded from the packaged toolbox, you'll\r\n% want to check that the users have installed these prior to running your toolbox\r\n% code. If the external dependencies are MATLAB toolboxes, you can use the |<http:\/\/uk.mathworks.com\/help\/matlab\/ref\/matlab.addons.toolbox.installtoolbox.html % matlab.addons.toolbox.installToolboxes>| API to query information about installed\r\n% toolboxes from R2016a. Prior to R2016a, if a toolbox contains a |Contents.m|\r\n% file, users can query version information of the toolbox using the  |ver| command.\r\n%\r\n%%\r\n% *Thoughts?*\r\n%\r\n% Do you have any experiences to share that can help avoid packaging\r\n% pitfalls? If so, let me know about it in the comments!\r\n##### SOURCE END ##### 51884fd2870e4726ada1139bf42f02d0\r\n-->","protected":false},"excerpt":{"rendered":"<div class=\"overview-image\"><img decoding=\"async\"  class=\"img-responsive\" src=\"https:\/\/blogs.mathworks.com\/developer\/files\/y2017PackagingDependencyConflicts.png\" onError=\"this.style.display ='none';\" \/><\/div><!--introduction-->\r\n\r\n<i>Hello readers, today we have another post from <a href=\"https:\/\/www.mathworks.com\/services\/consulting\/meet-our-team.html#amy_koh\">Amy<\/a>, who is here to share more of her valuable experience deploying toolboxes. Take note of some of these tips after you have thoroughly enjoyed any eclipse observations you have been lucky enough to witness this time around. Just like looking at an eclipse directly is something you want to avoid, so are these packaging anti-patterns. Take it away Amy!<\/i>\r\n\r\n<!--\/introduction-->... <a class=\"read-more\" href=\"https:\/\/blogs.mathworks.com\/developer\/2017\/08\/21\/packaging-pitfalls\/\">read more >><\/a><\/p>","protected":false},"author":90,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[17],"tags":[],"_links":{"self":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1020"}],"collection":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/users\/90"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/comments?post=1020"}],"version-history":[{"count":23,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1020\/revisions"}],"predecessor-version":[{"id":1057,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/posts\/1020\/revisions\/1057"}],"wp:attachment":[{"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/media?parent=1020"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/categories?post=1020"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.mathworks.com\/developer\/wp-json\/wp\/v2\/tags?post=1020"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}