www.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);