gusucode.com > private工具箱matlab源码程序 > private/create_file_name_info.m

    function fileNameInfo = create_file_name_info(~)
% FILENAMEINFO = CREATE_FILE_NAME_INFO

%   Copyright 1995-2015 The MathWorks, Inc.
%

global gMachineInfo gTargetInfo

% root directory determination: get the model of the parentTarget
% get the filename property of the model which will give you
% model directory. this dir will be used for constructing abs path
% from relative paths in user source files, user incl dirs etc.

parentTargetMachine = sf('get',gMachineInfo.parentTarget,'target.machine');
modelH = sf('get',parentTargetMachine,'machine.simulinkModel');
machineFullName = get_param(modelH,'filename');
currentDirPath = pwd;
rootDirectory = get_root_directory(modelH, machineFullName, currentDirPath);

[projectDirPath,projectDirArray, projectDirRelPath, projectDirReverseRelPath] = sfprivate('get_sf_proj',pwd,gMachineInfo.mainMachineName,gMachineInfo.machineName,gMachineInfo.targetName,'src');
fileNameInfo.targetDirName = projectDirPath;
fileNameInfo.targetDirRelPath = projectDirRelPath;
baseName = [gMachineInfo.machineName,'_',gMachineInfo.targetName];
if gTargetInfo.codingRTW || gTargetInfo.codingSFunction
    fileNameInfo.mexFunctionName = baseName;
    fileNameInfo.dllDirFromMakeDir = projectDirReverseRelPath;
    fileNameInfo.projectDirArray = projectDirArray;
    if(sf('feature','Sim Through JIT'))
        % we will call create_directory_path just in time rather than here
        % this is needed for the LLVM-JIT mode where we do not want to pollute the current dir
    else
        create_project_dir_path_just_in_time(fileNameInfo);
    end
elseif gTargetInfo.codingMEX || gTargetInfo.codingHDL
    fileNameInfo.targetDirName = pwd;
    fileNameInfo.dllDirFromMakeDir = '.\';
else
    codegenDir = sf('get',gMachineInfo.parentTarget,'target.codegenDirectory');

    if(isempty(codegenDir))
        fileNameInfo.targetDirName = projectDirPath;
        [dirName, success, errorCreateMsg] = sfprivate('create_directory_path',projectDirArray{:});
        if(~success)
            construct_dir_path_error(dirName,errorCreateMsg);
        end
        fileNameInfo.dllDirFromMakeDir = projectDirReverseRelPath;
    else
        codegenDirOrig = codegenDir;
        [codegenDir,errorStr] = sfprivate('tokenize',currentDirPath,codegenDir,'Code generation directory string');
        if(~isempty(errorStr))
            construct_coder_error(gMachineInfo.parentTarget,errorStr);
        end

        codegenDir = codegenDir{1};

        if(~isdir(codegenDir))
            [success, errorMessage] = sfprivate('sf_mk_dir', currentDirPath, codegenDirOrig);

            if(~success)
                construct_dir_path_error(codegenDir, errorMessage);
            end
        end

        fileNameInfo.targetDirName = codegenDir;
        fileNameInfo.dllDirFromMakeDir = '.\';
    end
end
if(sfprivate('testing_stateflow_in_bat'))
    % make sure we are generating code in
    % MATLAB directories
    if(~isempty(strfind(lower(fileNameInfo.targetDirName),lower(matlabroot))))
        construct_coder_error([],'Code generation in MATLAB directories during Stateflow testing is prohibited.',1);
    end
end

% Can't generate C++ s-function using lcc
if gTargetInfo.codingSFunction && gTargetInfo.gencpp && gTargetInfo.codingLccMakefile
    construct_coder_error(gMachineInfo.parentTarget,['The current code generation target is configured to ',...
        'generate C++, but the C-only compiler, LCC, is the default compiler.  '...
        'To specify a C++ compiler, enter ''mex -setup'' '...
        'at the command prompt.  To generate C code, '...
        'open the Configuration Parameters dialog and set the target language to C.'...
        ],1);
end

if gTargetInfo.codingRTW
    fileNameInfo.headerExtension = '.tlh';
    fileNameInfo.sourceExtension = '.tlc';
elseif gTargetInfo.codingHDL
    fileNameInfo.headerExtension = '';
    fileNameInfo.sourceExtension = '';
elseif gTargetInfo.codingPLC
    fileNameInfo.headerExtension = ''; % no header file
    fileNameInfo.sourceExtension = gTargetInfo.plc.fileExt;
else
    fileNameInfo.headerExtension = '.h';
    if gTargetInfo.gencpp
        fileNameInfo.sourceExtension = '.cpp';
    else
        fileNameInfo.sourceExtension = '.c';
    end
end
if(gTargetInfo.codingSFunction)
    fileNameInfo.machineRegistryFile = [baseName,'_registry',fileNameInfo.sourceExtension];

    % Extra files for emitting the custom code (created only if required)
    if sf('feature', 'Emit custom code in a separate file')
        fileNameInfo.customCodeHeaderFile = [gMachineInfo.machineName,'_customcode',fileNameInfo.headerExtension];
        fileNameInfo.customCodeSourceFile = [gMachineInfo.machineName,'_customcode',fileNameInfo.sourceExtension];
        if gTargetInfo.codingDebug
            fileNameInfo.customCodeCovHeaderFile = [gMachineInfo.machineName,'_customcode_cov.h'];
        end
    end
end

if(gTargetInfo.codingDebug)
    fileNameInfo.sfDebugMacrosFile = [baseName,'_debug_macros',fileNameInfo.headerExtension];
end

fileNameInfo.machineHeaderFile = [baseName,fileNameInfo.headerExtension];
fileNameInfo.machineSourceFile = [baseName,fileNameInfo.sourceExtension];

numCharts = length(gMachineInfo.charts);
fileNameInfo.chartHeaderFiles = cell(1,numCharts);
fileNameInfo.chartSourceFiles = cell(1,numCharts);
fileNameInfo.chartSpecUniqueNames = cell(1,numCharts);
fileNameInfo.chartTLCFiles = cell(1,numCharts);
fileNameInfo.chartOutputsFcns = cell(1,numCharts);
fileNameInfo.chartInitializeFcns = cell(1,numCharts);

if gTargetInfo.codingRTW
    machineSourceFile = fileNameInfo.machineSourceFile;
    sf('set',gMachineInfo.machineId,'machine.rtwInfo.machineTLCFile',machineSourceFile(1:end-length(fileNameInfo.sourceExtension)));
end

for chart = gMachineInfo.charts
    chartNumber = sf('get',chart,'chart.number');

    %TLTODO: Handle all targets
    numSpecs = length(gMachineInfo.specializations{chartNumber+1});
    for j = 1:numSpecs
        chartSpecUniqueName = sf('CodegenNameOf', chart, gMachineInfo.specializations{chartNumber+1}{j});
        fileNameInfo.chartSpecUniqueNames{chartNumber+1}{j} = chartSpecUniqueName;

        if gTargetInfo.codingSFunction || gTargetInfo.codingRTW
            fileNameInfo.chartHeaderFiles{chartNumber+1}{j} = [chartSpecUniqueName,fileNameInfo.headerExtension];
            fileNameInfo.chartSourceFiles{chartNumber+1}{j} = [chartSpecUniqueName,fileNameInfo.sourceExtension];
            fileName = fullfile(fileNameInfo.targetDirName,fileNameInfo.chartSourceFiles{chartNumber+1}{j});

            % Windows paths are limited to 260 characters. Let's add an extra
            % 20-character margin because of interface and support files that
            % have longer names.
            if (ispc && length(fileName) >= 240)
                sfprivate('construct_error', chart, 'Build', DAStudio.message('Stateflow:sfprivate:LongPathErrorWindows', fileName), 1, []);
                return;
            end
        else
            fileNameInfo.chartHeaderFiles{chartNumber+1} = [chartSpecUniqueName,fileNameInfo.headerExtension];
            fileNameInfo.chartSourceFiles{chartNumber+1} = [chartSpecUniqueName,fileNameInfo.sourceExtension];
        end

        % chartTLCFile, chartOutputsFcn, chartInitializeFcn are only used when coder unification is turned off
        if(gTargetInfo.codingRTW)
            fileNameInfo.chartTLCFiles{chartNumber+1}{j} = chartSpecUniqueName;
            fileNameInfo.chartOutputsFcns{chartNumber+1}{j} = ['sf_',chartSpecUniqueName];
        end

        if gTargetInfo.codingRTW || gTargetInfo.codingMEX
            fileNameInfo.chartInitializeFcns{chartNumber+1}{j} = ['initialize_',chartSpecUniqueName];
        end
    end
end

compilerInfo = sfprivate('compilerman', 'get_compiler_info', true, gTargetInfo.gencpp);

fileNameInfo.mexSetEnv = compilerInfo.mexSetEnv;

fileNameInfo.matlabRoot = matlabroot;
fileNameInfo.stddefIncludeFile = [];
fileNameInfo.openMPIncludeFile = [];

if(gTargetInfo.codingSFunction)
    fileNameInfo.makeBatchFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.bat'];
    fileNameInfo.machineDefFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.def'];
    fileNameInfo.SFunctionName = [gMachineInfo.machineName,'_',gMachineInfo.targetName];
    fileNameInfo.unixMakeFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.mku'];
    fileNameInfo.msvcdspFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.dsp'];
    fileNameInfo.msvcdswFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.dsw'];
    fileNameInfo.msvcvcprojFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.vcproj'];
    fileNameInfo.msvcMakeFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.mak'];
    fileNameInfo.lccMakeFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.lmk'];
    fileNameInfo.objListFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.mol'];
    fileNameInfo.mingwMakeFile = [gMachineInfo.machineName,'_',gMachineInfo.targetName,'.gmk'];

end
if (~gTargetInfo.codingRTW)
    fileNameInfo.rtwHeadersInclude = fullfile(fileNameInfo.matlabRoot,'stateflow','c','mex','include');
    fileNameInfo.archName = computer('arch');
    if gTargetInfo.codingOpenMP
        fileNameInfo.openMPIncludeFile = 'omp.h';
    end
end

fileNameInfo.sfRuntimeIncludeDir =  fullfile(fileNameInfo.matlabRoot, 'simulink', 'include');
if(ispc)
    fileNameInfo.sfRuntimeLib = constructWindowsLibraryPath(compilerInfo, fileNameInfo, 'sf_runtime.lib');
else
    fileNameInfo.sfRuntimeLibDir = '';
    fileNameInfo.sfRuntimeLib = fullfile(fileNameInfo.matlabRoot,'bin',computer('arch'),'mwsf_runtime'); 
end

customCodeSettings = get_custom_code_settings(gMachineInfo.target,gMachineInfo.parentTarget, false);

customCodeIsEmpty = isempty(customCodeSettings.customCode) &&...
                    isempty(customCodeSettings.customSourceCode) &&...
                    isempty(customCodeSettings.userIncludeDirs) &&...
                    isempty(customCodeSettings.userSources) &&...
                    isempty(customCodeSettings.customInitializer) &&...
                    isempty(customCodeSettings.customTerminator) &&...
                    isempty(customCodeSettings.userLibraries);

if(customCodeIsEmpty) 
    fileNameInfo.userIncludeDirs = {};
else
    %%% IMPORTANT: We use include directory paths as search paths for
    %%% source files (G85817). Hence, we must tokenize includeDirs before
    %%% user sources
    [fileNameInfo.userIncludeDirs,errorStr] = ...
        sfprivate('tokenize'...
        ,rootDirectory...
        ,customCodeSettings.userIncludeDirs...
        ,'custom include directory paths string'...
        ,{});
    if(~isempty(errorStr))
        construct_coder_error(customCodeSettings.relevantTargetId,errorStr);
    end

    % Legacy interface function
    modelName = get_param(modelH, 'name');
    if (slfeature('LegacyCodeIntegration') == 1) && ~isempty(modelName)
        subdir = 'sim';
        if strcmpi(gMachineInfo.targetName, 'rtw')
            subdir = 'rtw';
        end
        
        legacyDir = rtwprivate('rtw_create_directory_path', ...
                currentDirPath, 'slprj', 'legacy', modelName, subdir);

        fileNameInfo.userIncludeDirs = [ ...
            {fileNameInfo.targetDirName},{currentDirPath}, {rootDirectory}, ...
            {legacyDir},fileNameInfo.userIncludeDirs];
    else
        fileNameInfo.userIncludeDirs = [ ...
            {fileNameInfo.targetDirName},{currentDirPath}, {rootDirectory}, ...
             fileNameInfo.userIncludeDirs];
    end

    fileNameInfo.userIncludeDirs = ordered_unique_paths(fileNameInfo.userIncludeDirs);

    % G400437. Use regexp to tokenize MATLAB path instead of the home-grown tokenize
    searchDirectories = regexp(matlabpath,pathsep,'split');
    if(ispc)
        filterIndices = strncmpi(searchDirectories,matlabroot,length(matlabroot));
    else
        filterIndices = strncmp(searchDirectories,matlabroot,length(matlabroot));
    end
    searchDirectories(filterIndices) = [];
    searchDirectories = [fileNameInfo.userIncludeDirs,searchDirectories];
    searchDirectories = ordered_unique_paths(searchDirectories);
    customCodeString = customCodeSettings.customCode;
    if(~isempty(customCodeString))
        % If there is custom code, include MATLAB's search path in it
        % as it may be including files in these directories
        customCodeIncDirs = extract_relevant_dirs(rootDirectory,searchDirectories,customCodeString);
    else
        customCodeIncDirs = {};
    end
    fileNameInfo.userIncludeDirs = [fileNameInfo.userIncludeDirs,customCodeIncDirs];
    fileNameInfo.userIncludeDirs = ordered_unique_paths(fileNameInfo.userIncludeDirs);

end


userSourceStr = customCodeSettings.userSources;

if(isempty(userSourceStr))
    fileNameInfo.userSources = {};
else
    [fileNameInfo.userSources,errorStr] = ...
        sfprivate('tokenize'...
        ,rootDirectory...
        ,userSourceStr...
        ,'custom source files string'...
        ,searchDirectories);
    if(~isempty(errorStr))
        construct_coder_error(customCodeSettings.relevantTargetId,errorStr);
    end
end

userLibrariesStr = customCodeSettings.userLibraries;

if(isempty(userLibrariesStr))
    fileNameInfo.userLibraries = {};
else
    [fileNameInfo.userLibraries,errorStr] = ...
        sfprivate('tokenize'...
        ,rootDirectory...
        ,userLibrariesStr...
        ,'custom libraries string'...
        ,searchDirectories);
    if(~isempty(errorStr))
        construct_coder_error(customCodeSettings.relevantTargetId,errorStr);
    end
end

if gTargetInfo.codingSFunction
    fileNameInfo.customCompilerFlags = customCodeSettings.customCompilerFlags;
    fileNameInfo.customLinkerFlags = customCodeSettings.customLinkerFlags;

    ccLIBExt = cgxeprivate('getLibraryExtension','import');
    fileNameInfo.dllDirPath = projectDirArray{1};
    fileNameInfo.customCodeDLL = fullfile(fileNameInfo.dllDirPath, ...
        [gMachineInfo.mainMachineName '_cclib' ccLIBExt]);
end

fileNameInfo.userMakefiles = {};
fileNameInfo.userAbsSources = {};
fileNameInfo.userAbsPaths = {};
for i=1:length(fileNameInfo.userSources)
    [fileNameInfo.userAbsPaths{i}...
        ,fileNameInfo.userAbsSources{i}...
        ,fileNameInfo.userSources{i}] = ...
        sfprivate('strip_path_from_name',fileNameInfo.userSources{i});
end

% get rid of duplicate paths preserving the order
fileNameInfo.userAbsPaths = ordered_unique_paths(fileNameInfo.userAbsPaths);
fileNameInfo.userIncludeDirs = [fileNameInfo.userIncludeDirs ...
    ,fileNameInfo.userAbsPaths];
fileNameInfo.userIncludeDirs = ordered_unique_paths(fileNameInfo.userIncludeDirs);

fileNameInfo.linkMachines = {};
fileNameInfo.linkLibFullPaths	= {};
fileNameInfo.linkObjListFullPaths = {};
fileNameInfo.linkMachinesInlinable = {};
if(~gTargetInfo.codingLibrary)
    [fileNameInfo.linkMachines,fileNameInfo.linkLibFullPaths, ~, fileNameInfo.linkObjListFullPaths] = sfprivate('get_link_machine_list',gMachineInfo.machineName,gMachineInfo.targetName);
    for i=1:length(fileNameInfo.linkMachines)
        infoStruct = sfprivate('infomatman','load','binary',fileNameInfo.linkMachines{i},gMachineInfo.mainMachineId,gMachineInfo.targetName);
        fileNameInfo.linkMachinesInlinable{i} = infoStruct.machineInlinable;
    end
end

fileNameInfo = fix_user_path_for_make_file(fileNameInfo);

function compilerFolderName = getWindowsCompilerFolderName(compilerInfo)
compilerFolderName = compilerInfo.compilerName;
if ~isempty(regexp(compilerFolderName, '^msvc|^mssdk', 'once'))
    compilerFolderName = 'microsoft';
elseif strcmp(computer,'PCWIN64') && strcmp(compilerFolderName,'lcc') 
    % On Windows64, LCC compiler can read Visual Studio DLL symbols.    
    compilerFolderName = 'microsoft';
elseif ~isempty(regexp(compilerFolderName, '^mingw64', 'once'))
    compilerFolderName = 'mingw64';
end

function libPath = constructWindowsLibraryPath(compilerInfo, fileNameInfo, libName)

compilerFolderName = getWindowsCompilerFolderName(compilerInfo);
libPath = fullfile(fileNameInfo.matlabRoot,'extern','lib',computer('arch'),compilerFolderName,libName);

function rootDirectory = get_root_directory(modelH, machineFullName, currentDirPath)
    if(isempty(machineFullName))
        rootDirectory = currentDirPath;
    else
        % extract rootDirectory from machine's full name
        lastFileSep = find(machineFullName==filesep, 1, 'last' );
        if(~isempty(lastFileSep))
            % If the model is a multi-instance mode copy, we want to use
            % the location of the original model as the root directory in
            % case the include paths are relative (g859919).
            if(isequal(get_param(modelH, 'ModelReferenceMultiInstanceNormalModeCopy'), 'on'))
                origModel = get_param(modelH, 'ModelReferenceNormalModeOriginalModelName');
                origModelPath = get_param(origModel, 'FileName');
                rootDirectory = fileparts(origModelPath);
            else
                rootDirectory = machineFullName(1:lastFileSep-1);        
            end
        else
            % machine full name does not have dir info, so it is a new machine
            rootDirectory = currentDirPath;
        end
    end

function orderedList = ordered_unique_paths(orderedList)

orderedList = sfprivate('ordered_unique_paths', orderedList);


function newSearchDirectories = extract_relevant_dirs(rootDirectory, searchDirectories, customCodeString)

newSearchDirectories = sfprivate('extract_relevant_dirs', rootDirectory, searchDirectories, customCodeString);

function fileNameInfo = fix_user_path_for_make_file(fileNameInfo)

fileNameInfo.userIncludeDirs = fix_windows_paths_for_make_file(fileNameInfo.userIncludeDirs);
fileNameInfo.userSources = fix_windows_paths_for_make_file(fileNameInfo.userSources);
fileNameInfo.userLibraries = fix_windows_paths_for_make_file(fileNameInfo.userLibraries);
fileNameInfo.userMakefiles = fix_windows_paths_for_make_file(fileNameInfo.userMakefiles);
fileNameInfo.userAbsSources = fix_windows_paths_for_make_file(fileNameInfo.userAbsSources);
fileNameInfo.userAbsPaths = fix_windows_paths_for_make_file(fileNameInfo.userAbsPaths);