function cct_setup(mdlname)
%CCT_SETUP Checks compilers and applies build settings for code coverage.
%
% CCT_SETUP('model_name') applies the necessary build settings to
% model_name for code coverage measurement in generated S-Functions. The
% S-functions will be compiled using lcc.
% Copyright 2009 The MathWorks, Inc.
% $File: $
% $Revision: $
% $Date: $
if nargin ~= 1 || ~ischar(mdlname),
error('cct:Usage','Usage: cct_setup(''model_name'')');
end
mexcompiler = '';
% Test that this is the mex compiler
if exist([prefdir '\mexopts.bat'],'file'),
try
% Open the mexopts file and check it is for lcc
fid=fopen([prefdir '\mexopts.bat']);
while 1,
fl=fgetl(fid);
if isempty(fl)
error('cct:WrongCompiler','mex compiler must be set to lcc. Type mex -setup at the command prompt and select lcc from the list.')
end
if strmatch(fl,'rem LCCOPTS.BAT','exact')
mexcompiler = 'lcc';
end
if ~isempty(mexcompiler),break,end
end
% If we break out of the while loop then we are OK
fclose(fid);
catch
fclose(fid);
rethrow(lasterror);
end
else
error('cct:NoMex','Could not find mexopts.bat file in preferences directory. Type mex -setup at the command prompt and select lcc from the list.')
end
% Now that we know the mex compiler is OK, ensure that the tool executables
% are built and up to date
dos(['gmake -s -f cct.mk MATLABROOT="' matlabroot '"']);
%Requires Embedded Coder. Do we have the right version?
tmp=ver('ecoder');
if isempty(tmp),
error('cct:NoRTWEC','Code coverage tool requires Embedded Coder.')
end
tmp=tmp.Version;
if str2double(tmp(1:3)) < 4.4,
error('cct:WrongRTWECVer','Code coverage tool requires Embedded Coder 4.4 (R2006a) or later.');
end
% Now verify install location for cct tools
% This file should be alongside coverage object
% Only interested in the path
toolroot = [fileparts(which('cct_setup')) filesep];
% Does the batch file exist?
if ~exist([toolroot 'coverage.bat'],'file'),
error('cct:NoMexBatchFile',['Could not find coverage.bat in tool install directory ' toolroot '. Check cct installation and rerun cct_setup on model.']);
end
% Now test lcccov and lcccovlnk
if strcmp(mexcompiler,'lcc')
[s,w] = system(['"' toolroot 'lcccov" -test']);
if s,error('cct:LcccovNotOnPath',['Could not find lcccov.exe in tool install directory ' toolroot '. Check cct installation.']);,end
if ~findstr(w,'lcccov test OK'),
error('cct:LcccovTestNotOK','lcccov execution test failed. Check cct installation.');
end
[s,w] = system(['"' toolroot 'lcccovlnk" -test']);
if s,error('cct:LcccovlnkNotOnPath',['Could not find lcccovlnk.exe in tool install directory ' toolroot '. Check cct installation.']);,end
if ~findstr(w,'lcccovlnk test OK'),
error('cct:LcccovlnkNotOK','lcccovlnk execution test failed. Check cct installation.');
end
end
%Now check the properties of the supplied model
%Check specified model name, shouldn't matter if it is a model path or
%has a .mdl extension
%Root only if GCS supplied
mdlname=strtok(mdlname,'/');
%Strip off mdl name if required
tmp = regexp(mdlname,'\.mdl','once');
if tmp,
mdlname=mdlname(1:tmp-1);
end
%Try and retreive config set for supplied model
cs=getActiveConfigSet(mdlname);
% As a second check, see if the model has a terminate function. It
% could be that the path to a block has been supplied instead
if ~isfield(get_param(cs,'ObjectParameters'),'CustomTerminator'),
error('cct:NotTopLevel',[mdlname ' is not a path to the top level model. The path supplied to CCT must be the top level.']);
end
%Certain build options must be set. Check for these next
if ~strcmp('ert.tlc',get_param(cs,'SystemTargetFile')),
error('cct:NotErt','System target file must be ert.tlc (Embedded Coder)');
end
% Must be S-function for lcc cov build
if strcmp(get_param(cs,'GenerateErtSFunction'),'off'),
disp('Turning on Generate ERT S-Function ...');
set_param(cs,'GenerateErtSFunction','on');
end
% This would stop the build
if strcmp(get_param(cs,'GenCodeOnly'),'on'),
disp('Turning off Generate Code Only Option ...');
set_param(cs,'GenCodeOnly','off');
end
% Need the code generation report so there is somthing to insert the
% coverage into
if strcmp(get_param(cs,'GenerateReport'),'off')
disp('Turning on Code Generation Report ...');
set_param(cs,'GenerateReport','on')
end
% This would mean the build type was unknown
if strcmp(get_param(cs,'GenerateMakefile'),'off'),
disp('Turning on Generate Makefile Option ...');
set_param(cs,'GenerateMakefile','on');
end
% Force fixed step discrete
if ~strcmp(get_param(cs,'Solver'),'FixedStepDiscrete'),
disp('Turning on continuous time option since solver is not fixed step discrete ...');
set_param(cs,'SupportContinuousTime','on');
end
% This overwrites the default setting 'ert_default_tmf' which is an
% m-script that sets the appropriate tmf. We will always build using lcc,
% so can set this explicitly. This makes it clearer to the user which tmf
% is controlling the build. User could modify this script to redirect to
% their own tmf.
if ~strcmp(get_param(cs,'TemplateMakefile'),'ert_default_tmf'),
disp('Setting system target file to ert_default_tmf ...');
set_param(cs,'TemplateMakefile','ert_default_tmf');
end
% Must have Terminate function
if strcmp(get_param(cs,'IncludeMdlTerminateFcn'),'off'),
disp('Setting model terminate function to required ...');
set_param(cs,'IncludeMdlTerminateFcn','on');
end
% Must zero init to get repeatable simulation runs
% This is only required on R2006a
if strcmp(get_param(cs,'ZeroExternalMemoryAtStartup'),'off'),
disp('Setting model to zero initialise external memory at startup ...');
set_param(cs,'ZeroExternalMemoryAtStartup','on');
end
% Must zero init to get repeatable simulation runs
% This is only required on R2006a
if strcmp(get_param(cs,'ZeroInternalMemoryAtStartup'),'off'),
disp('Setting model to zero initialise internal memory at startup ...');
set_param(cs,'ZeroExternalMemoryAtStartup','on');
end
% Always force custom code settings
set_param(cs,'CustomHeaderCode',sprintf('extern void __cct_dump(void);\nextern void pilMarshallInitSFcnSimStruct(void*);\nextern void pilMarshallInitRootSimStruct(void*);\n'));
set_param(cs,'CustomTerminator','__cct_dump();');
% Ensure coverage.bat picks up correct toolroot
if ~strcmp(get_param(mdlname,'InitFcn'),['setenv(''TOOLROOT'',''' toolroot ''');']);
disp('Setting model to coverage tools path.')
set_param(mdlname,'InitFcn',['setenv(''TOOLROOT'',''' toolroot ''');']);
end
% Setup mex options file
if strcmp(mexcompiler,'lcc')
if ~strcmp(get_param(cs,'MakeCommand'),['make_rtw MEX_OPT_FILE="-g -v -f """' toolroot 'coverage.bat""" CC="""' toolroot 'lcccov"""']),
disp('Setting make command ...');
set_param(cs,'MakeCommand',['make_rtw MEX_OPT_FILE="-g -v -f """' toolroot 'coverage.bat""" CC="""' toolroot 'lcccov"""']);
end
end
disp('Code coverage tool model setup complete.');