1

we use a scripting environment to automatically build, run and verify a stand-alone executable. We are working with Matlab R2010a x64. The Matlab compiler mcc is called from the Windows command line building a stand-alone application:

mcc -m -v -w enable -I source_folder -I common_folder -a specific_files_we_need our_program

The program consists of about 25 modules (.m files) and is using about 5 toolboxes. This is working fine as long as the correct license is available. mcc checks for a compiler license available, resolves dependencies, packs everything in the executable.

However if the license does not include the required toolboxes, mcc does not issue any warning or error. It builds the executable without the toolboxes. So the executable starts, seems to run at a first glance but crashes if a line of code requiring a toolbox is reached.

I am expecting from a compiler that it informs me about missing components. What can I do to get informed about missing components? How can I make sure that mcc does not put together incomplete executables? Am I missing something in the call to mcc?

Preferably I would like to setup the compiling in a way that it stops if things are missing.

\Zweikeks

Zweikeks
  • 300
  • 1
  • 11

3 Answers3

1

The simplest way is in your compilation script you can checkout the licenses required, i.e.

license('checkout','Compiler')
license('checkout','control_toolbox')

You just add the 5 toolboxes that need to be checked out -> if the license function cant checkout the license it returns false which you can then use to abort the compilation.

matlabgui
  • 5,642
  • 1
  • 12
  • 15
  • This helps already, thanks matlabgui. However, I have to specify a fixed set of toolboxes. In case a developer changes the sources in a way that another toolbox is needed, the compilation might fail again without notice. – Zweikeks Jul 22 '16 at 21:35
  • That is true. You could possibly loop through all the dependent source files and see what toolbox they come from. – matlabgui Jul 22 '16 at 21:38
0

This is what I finally came up with:

I can check before compilation which toolboxes are needed and call license() accordingly. Or I can implement a built-in check into the executable itself. (Called with a special parameter after compilation triggers a self-check for available toolboxes.) In either case I need the names of the required toolboxes.

I tried several ways to generate a list of toolboxes. In short: Running the program in Matlab and then entering license('inuse') is not very reliable. depfun() descends way to much. mydepfun() and fdep() do not descend enough.

I think the problem with mydepfun() and fdep() is that they do not descend into the \toolbox\shared folder. So I took mydepfun() from Tobias Kienzler (link to the original sources) and modified it:

function [list,callers,tboxes_found] = i_scan(f)

func = i_function_name(f);

[list,~,~,~,~,~,callers,~] = depfun(func,'-toponly','-quiet');

toolboxroot = fullfile(matlabroot,'toolbox');
sharedroot  = strcat(toolboxroot, filesep, 'shared');

intoolbox = strncmpi(list,toolboxroot,numel(toolboxroot));
inshared  = strncmpi(list,sharedroot, numel(sharedroot));

tboxes_found = list(intoolbox & ~inshared);
tboxes_found = regexpi(tboxes_found, '[\\/]toolbox[\\/](.+?)[\\/]', 'tokens');
tboxes_found = cellfun(@(cfun) cfun{1}, tboxes_found);

list = list(~intoolbox | inshared);
callers = callers(~intoolbox | inshared);
for jj = 1:numel(list)
    c = callers{jj};
    cs = cell(numel(c),1);
    for kk = 1:numel(c)
        cs{kk} = list{c(kk)};
    end;
    callers{jj} = cs;
end;

This way i_scan(f) is returning the toolboxes and also descends into \toolbox\shared. The main function of mydepfun() just collects the toolboxes:

function [filelist,callers,toolboxes] = mydepfun(fn,recursive)
.
.
toolboxes = {};
[filelist,callers,tboxes_found] = i_scan(foundfile);
toolboxes = [toolboxes; tboxes_found];
.
.
[newlist,newcallers,tboxes_found] = i_scan(toscan{1});
toolboxes = [toolboxes; tboxes_found];
.
.
toolboxes = unique(toolboxes);

The toolboxes listed are the ones our source code uses. The modified mydepfun() seems to work fine. (Apart from the typical problems caused by elements only resolved during run time like eval(), function handles, callbacks etc.)

And: The dependeny walkers I have seen - like mydepfun() - are using depfun() inside. depfun() is not reliable since it silently ignores all source code not on the path (also its return prob_files is empty in this case). So care has to be taken that the Matlab path is set correctly. (Also any additional pathes are problematic since Matlab may take unexpectedly functions with the same name from other locations.)

After all, I think, this is a good way to make my build process more reliable.

/Zweikeks

Zweikeks
  • 300
  • 1
  • 11
0

I just got another hint from the Mathworks forum. The compiler writes out mccExludedFiles.log. This is listing missing toolboxes. For example

mccExludedFiles.log:
C:\Program Files\MATLAB\R2010a\toolbox\shared\optimlib\fmincon.m
called by ...c:\temp\whatever\source\code.m
(because the required licenses are not available.)

(Other missing files in the source code do not get listed, though.)

/Zweikeks

Zweikeks
  • 300
  • 1
  • 11