IDE: using -Xp and -V as keys for cache of fpc settings

git-svn-id: trunk@44289 -
This commit is contained in:
mattias 2014-02-28 13:38:12 +00:00
parent 4b4d589d8c
commit 0f252ce423
2 changed files with 116 additions and 50 deletions

View File

@ -946,11 +946,24 @@ function RunTool(const Filename: string; Params: TStrings;
function RunTool(const Filename, Params: string;
WorkingDirectory: string = ''): TStringList;
type
// fpc parameter effecting search for compiler
TFPCFrontEndParam = (
fpcpT, // -T<targetos>
fpcpP, // -P<targetprocessor>
fpcpV, // -V<postfix>
fpcpXp // -Xp<directory>
);
TFPCFrontEndParams = set of TFPCFrontEndParam;
const
AllFPCFrontEndParams = [low(TFPCFrontEndParam)..high(TFPCFrontEndParam)];
function ParseFPCInfo(FPCInfo: string; InfoTypes: TFPCInfoTypes;
out Infos: TFPCInfoStrings): boolean;
function RunFPCInfo(const CompilerFilename: string;
InfoTypes: TFPCInfoTypes; const Options: string =''): string;
function ExtractFPCFrontEndParameters(const CmdLine: string): string;
function ExtractFPCFrontEndParameters(const CmdLineParams: string;
const Kinds: TFPCFrontEndParams = AllFPCFrontEndParams): string;
function SplitFPCVersion(const FPCVersionString: string;
out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
function ParseFPCVerbose(List: TStrings; // fpc -va output
@ -1359,7 +1372,8 @@ begin
end;
end;
function ExtractFPCFrontEndParameters(const CmdLine: string): string;
function ExtractFPCFrontEndParameters(const CmdLineParams: string;
const Kinds: TFPCFrontEndParams): string;
// extract the parameters for the FPC frontend tool fpc.exe
// The result is normalized:
// - only the last value
@ -1384,26 +1398,26 @@ begin
ParamV:='';
ParamXp:='';
Position:=1;
while ReadNextFPCParameter(CmdLine,Position,StartPos) do begin
Param:=ExtractFPCParameter(CmdLine,StartPos);
while ReadNextFPCParameter(CmdLineParams,Position,StartPos) do begin
Param:=ExtractFPCParameter(CmdLineParams,StartPos);
if Param='' then continue;
p:=PChar(Param);
if p^<>'-' then continue;
case p[1] of
'T': ParamT:=copy(Param,3,255);
'P': ParamP:=copy(Param,3,255);
'V': ParamV:=copy(Param,3,length(Param));
'T': if fpcpT in Kinds then ParamT:=copy(Param,3,255);
'P': if fpcpP in Kinds then ParamP:=copy(Param,3,255);
'V': if fpcpV in Kinds then ParamV:=copy(Param,3,length(Param));
'X':
case p[2] of
'p': ParamXp:=copy(Param,4,length(Param));
'p': if fpcpXp in Kinds then ParamXp:=copy(Param,4,length(Param));
end;
end;
end;
// add parameters
Add('Xp',ParamXp);
Add('T',ParamT);
Add('P',ParamP);
Add('V',ParamV);
Add('Xp',ParamXp);
end;
function SplitFPCVersion(const FPCVersionString: string; out FPCVersion,
@ -2584,6 +2598,8 @@ begin
Result:=CompareStr(Item1.TargetCPU,Item2.TargetCPU);
if Result<>0 then exit;
Result:=CompareFilenames(Item1.Compiler,Item2.Compiler);
if Result<>0 then exit;
Result:=CompareFilenames(Item1.CompilerOptions,Item2.CompilerOptions);
end;
function CompareFPCSourceCacheItems(CacheItem1, CacheItem2: Pointer): integer;
@ -7114,8 +7130,8 @@ end;
procedure TFPCTargetConfigCache.Clear;
begin
// keep keys
CompilerDate:=0;
CompilerOptions:='';
RealCompiler:='';
RealCompilerDate:=0;
RealTargetCPU:='';
@ -7499,37 +7515,38 @@ var
begin
Result:=true;
if (not FileExistsCached(Compiler)) then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" compiler file missing "',Compiler,'"']);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" compiler file missing "',Compiler,'"']);
exit;
end;
if (FileAgeCached(Compiler)<>CompilerDate) then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" compiler file changed "',Compiler,'" FileAge=',FileAgeCached(Compiler),' StoredAge=',CompilerDate]);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" compiler file changed "',Compiler,'" FileAge=',FileAgeCached(Compiler),' StoredAge=',CompilerDate]);
exit;
end;
if (RealCompiler<>'') and (CompareFilenames(RealCompiler,Compiler)<>0)
then begin
if (not FileExistsCached(RealCompiler))
or (FileAgeCached(RealCompiler)<>RealCompilerDate) then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" real compiler file changed "',RealCompiler,'"']);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" real compiler file changed "',RealCompiler,'"']);
exit;
end;
end;
// fpc searches via PATH for the real compiler, resolves any symlink
// and that is the RealCompiler
// ToDo: -Xp -V
AFilename:=FindRealCompilerInPath(TargetCPU,true);
if RealCompilerInPath<>AFilename then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" real compiler in PATH changed from "',RealCompilerInPath,'" to "',AFilename,'"']);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" real compiler in PATH changed from "',RealCompilerInPath,'" to "',AFilename,'"']);
exit;
end;
for i:=0 to ConfigFiles.Count-1 do begin
Cfg:=ConfigFiles[i];
if (Cfg.Filename='') or (not FilenameIsAbsolute(Cfg.Filename)) then continue;
if FileExistsCached(Cfg.Filename)<>Cfg.FileExists then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" config fileexists changed "',Cfg.Filename,'"']);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" config fileexists changed "',Cfg.Filename,'"']);
exit;
end;
if Cfg.FileExists and (FileAgeCached(Cfg.Filename)<>Cfg.FileDate) then begin
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" config file changed "',Cfg.Filename,'"']);
debugln(['TFPCTargetConfigCache.NeedsUpdate TargetOS="',TargetOS,'" TargetCPU="',TargetCPU,'" Options="',CompilerOptions,'" config file changed "',Cfg.Filename,'"']);
exit;
end;
end;
@ -8742,6 +8759,7 @@ begin
TargetOS,TargetCPU,true);
FConfigCache.FreeNotification(Self);
end;
//debugln(['TFPCUnitSetCache.GetConfigCache CompilerOptions="',CompilerOptions,'" FConfigCache.CompilerOptions="',FConfigCache.CompilerOptions,'"']);
if AutoUpdate and FConfigCache.NeedsUpdate then
FConfigCache.Update(Caches.TestFilename,Caches.ExtraOptions);
Result:=FConfigCache;
@ -8793,7 +8811,7 @@ var
begin
Src:=GetSourceCache(AutoUpdate);
SrcRules:=GetSourceRules(AutoUpdate);
ConfigCache:=GetConfigCache(false);
ConfigCache:=GetConfigCache(false); // Note: update already done by GetSourceRules(AutoUpdate)
if (fuscfUnitTreeNeedsUpdate in fFlags)
or (fUnitStampOfFPC<>ConfigCache.ChangeStamp)

View File

@ -29,6 +29,8 @@ unit BuildManager;
{$mode objfpc}{$H+}
{off $DEFINE VerboseFPCSrcScan}
interface
uses
@ -138,6 +140,7 @@ type
fTargetOS: string;
fTargetCPU: string;
fLCLWidgetType: string;
fBuildLazExtraOptions: string; // last build lazarus extra options
OverrideTargetOS: string;
OverrideTargetCPU: string;
OverrideLCLWidgetType: string;
@ -718,16 +721,6 @@ end;
procedure TBuildManager.RescanCompilerDefines(ResetBuildTarget,
ClearCaches, WaitTillDone, Quiet: boolean);
var
TargetOS, TargetCPU: string;
CompilerFilename: String;
FPCSrcDir: string;
ADefTempl: TDefineTemplate;
FPCSrcCache: TFPCSourceCache;
NeedUpdateFPCSrcCache: Boolean;
IgnorePath: String;
MsgResult: TModalResult;
AsyncScanFPCSrcDir: String;
procedure AddTemplate(ADefTempl: TDefineTemplate; AddToPool: boolean;
const ErrorMsg: string);
@ -787,6 +780,18 @@ var
Result:=true;
end;
var
TargetOS, TargetCPU, FPCOptions: string;
CompilerFilename: String;
FPCSrcDir: string;
ADefTempl: TDefineTemplate;
FPCSrcCache: TFPCSourceCache;
NeedUpdateFPCSrcCache: Boolean;
IgnorePath: String;
MsgResult: TModalResult;
AsyncScanFPCSrcDir: String;
UnitSetChanged: Boolean;
HasTemplate: Boolean;
begin
if ClearCaches then begin
{$IFDEF VerboseFPCSrcScan}
@ -807,12 +812,22 @@ begin
TargetCPU:=GetTargetCPU;
FPCSrcDir:=EnvironmentOptions.GetParsedFPCSourceDirectory; // needs FPCVer macro
CompilerFilename:=GetFPCompilerFilename;
FPCOptions:='';
if Project1<>nil then
begin
FPCOptions:=ExtractFPCFrontEndParameters(Project1.CompilerOptions.CustomOptions);
if not GlobalMacroList.SubstituteStr(FPCOptions) then begin
debugln(['WARNING: TBuildManager.RescanCompilerDefines ignoring invalid macros in custom options for fpc frontend: "',ExtractFPCFrontEndParameters(Project1.CompilerOptions.CustomOptions),'"']);
FPCOptions:='';
end;
end;
{$IFDEF VerboseFPCSrcScan}
debugln(['TMainIDE.RescanCompilerDefines A ',
debugln(['TMainIDE.RescanCompilerDefines START ',
' CompilerFilename=',CompilerFilename,
' TargetOS=',TargetOS,
' TargetCPU=',TargetCPU,
' FPCOptions="',FPCOptions,'"',
' EnvFPCSrcDir=',EnvironmentOptions.FPCSourceDirectory,
' FPCSrcDir=',FPCSrcDir,
' WaitTillDone=',WaitTillDone,
@ -824,6 +839,9 @@ begin
// first check the default targetos, targetcpu of the default compiler
if FileExistsCached(EnvironmentOptions.GetParsedCompilerFilename) then
begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines reading default compiler settings']);
{$ENDIF}
UnitSetCache:=CodeToolBoss.FPCDefinesCache.FindUnitSet(
EnvironmentOptions.GetParsedCompilerFilename,'','','',FPCSrcDir,true);
UnitSetCache.GetConfigCache(true);
@ -836,8 +854,11 @@ begin
end;
// create a cache for the current project settings
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines reading active compiler settings']);
{$ENDIF}
UnitSetCache:=CodeToolBoss.FPCDefinesCache.FindUnitSet(
CompilerFilename,TargetOS,TargetCPU,'',FPCSrcDir,true);
CompilerFilename,TargetOS,TargetCPU,FPCOptions,FPCSrcDir,true);
NeedUpdateFPCSrcCache:=false;
//debugln(['TBuildManager.RescanCompilerDefines ',DirectoryExistsUTF8(FPCSrcDir),' ',(not WaitTillDone),' ',(not HasGUI)]);
@ -854,7 +875,7 @@ begin
if NeedUpdateFPCSrcCache then
begin
// start background scan of fpc source directory
//debugln(['TBuildManager.RescanCompilerDefines background scan '+FPCSrcCache.Directory]);
//debugln(['TBuildManager.RescanCompilerDefines background scan: '+FPCSrcCache.Directory]);
AsyncScanFPCSrcDir:=FPCSrcDir;
end;
end;
@ -863,47 +884,70 @@ begin
// scan compiler, fpc sources and create indices for quick lookup
UnitSetCache.Init;
if (FUnitSetChangeStamp=TFPCUnitSetCache.GetInvalidChangeStamp)
or (FUnitSetChangeStamp<>UnitSetCache.ChangeStamp) then begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines nothing changed']);
{$ENDIF}
// save caches
SaveFPCDefinesCaches;
end;
FUnitSetChangeStamp:=UnitSetCache.ChangeStamp;
UnitSetChanged:=(FUnitSetChangeStamp=TFPCUnitSetCache.GetInvalidChangeStamp)
or (FUnitSetChangeStamp<>UnitSetCache.ChangeStamp);
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines UnitSet changed => rebuilding defines',
debugln(['TBuildManager.RescanCompilerDefines UnitSet changed=',UnitSetChanged,
' ClearCaches=',ClearCaches,
' CompilerFilename=',CompilerFilename,
' TargetOS=',TargetOS,
' TargetCPU=',TargetCPU,
' FPCOptions="',FPCOptions,'"',
' RealCompiler=',UnitSetCache.GetConfigCache(false).RealCompiler,
' EnvFPCSrcDir=',EnvironmentOptions.FPCSourceDirectory,
' FPCSrcDir=',FPCSrcDir,
'']);
{$ENDIF}
if UnitSetChanged then begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines UnitSet changed => save scan results']);
{$ENDIF}
// save caches
SaveFPCDefinesCaches;
FUnitSetChangeStamp:=UnitSetCache.ChangeStamp;
end;
// rebuild the define templates
// create template for FPC settings
ADefTempl:=CreateFPCTemplate(UnitSetCache,nil);
AddTemplate(ADefTempl,false,
'NOTE: Could not create Define Template for Free Pascal Compiler');
HasTemplate:=CodeToolBoss.DefineTree.FindDefineTemplateByName(StdDefTemplFPC,true)<>nil;
if UnitSetChanged or not HasTemplate then
begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines updating FPC template UnitSetChanged=',UnitSetChanged,' OldTemplateExists=',HasTemplate]);
{$ENDIF}
// create template for FPC settings
ADefTempl:=CreateFPCTemplate(UnitSetCache,nil);
AddTemplate(ADefTempl,false,
'NOTE: Could not create Define Template for Free Pascal Compiler');
end;
// create template for FPC source directory
if HasGUI then
begin
ADefTempl:=CreateFPCSourceTemplate(UnitSetCache,nil);
AddTemplate(ADefTempl,false,lisNOTECouldNotCreateDefineTemplateForFreePascal);
HasTemplate:=CodeToolBoss.DefineTree.FindDefineTemplateByName(StdDefTemplFPCSrc,true)<>nil;
if UnitSetChanged or not HasTemplate then
begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines updating FPC SRC template UnitSetChanged=',UnitSetChanged,' OldTemplateExists=',HasTemplate]);
{$ENDIF}
ADefTempl:=CreateFPCSourceTemplate(UnitSetCache,nil);
AddTemplate(ADefTempl,false,lisNOTECouldNotCreateDefineTemplateForFreePascal);
end;
// create compiler macros for the lazarus sources
if CodeToolBoss.DefineTree.FindDefineTemplateByName(StdDefTemplLazarusSrcDir,
true)=nil
HasTemplate:=CodeToolBoss.DefineTree.FindDefineTemplateByName(StdDefTemplLazarusSources,true)<>nil;
if (not HasTemplate)
or (fBuildLazExtraOptions<>MiscellaneousOptions.BuildLazOpts.ExtraOptions)
then begin
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines updating Lazarus source template OldTemplateExists=',HasTemplate,' OldExtraOptions="',fBuildLazExtraOptions,'" NewExtraOptions="',MiscellaneousOptions.BuildLazOpts.ExtraOptions,'"']);
{$ENDIF}
fBuildLazExtraOptions:=MiscellaneousOptions.BuildLazOpts.ExtraOptions;
ADefTempl:=CreateLazarusSourceTemplate(
'$('+ExternalMacroStart+'LazarusDir)',
'$('+ExternalMacroStart+'LCLWidgetType)',
MiscellaneousOptions.BuildLazOpts.ExtraOptions,nil);
fBuildLazExtraOptions,nil);
AddTemplate(ADefTempl,true,
lisNOTECouldNotCreateDefineTemplateForLazarusSources);
end;
@ -913,6 +957,9 @@ begin
if AsyncScanFPCSrcDir<>'' then begin
// start scanning the fpc source directory in the background
{$IFDEF VerboseFPCSrcScan}
debugln(['TBuildManager.RescanCompilerDefines scanning fpc sources:',AsyncScanFPCSrcDir]);
{$ENDIF}
if FPCSrcScans=nil then
FFPCSrcScans:=TFPCSrcScans.Create(Self);
FPCSrcScans.Scan(AsyncScanFPCSrcDir);
@ -2579,7 +2626,8 @@ begin
//debugln(['TBuildManager.BuildTargetIDEIsDefault NewTargetOS=',NewTargetOS,' Default=',GetDefaultTargetOS,' NewTargetCPU=',NewTargetCPU,' default=',GetDefaultTargetCPU,' ws=',LCLPlatformDisplayNames[NewLCLWidgetSet],' default=',LCLPlatformDisplayNames[GetDefaultLCLWidgetType]]);
Result:=((NewTargetOS='') or (NewTargetOS=GetCompiledTargetOS))
and ((NewTargetCPU='') or (NewTargetCPU=GetCompiledTargetCPU))
and (NewLCLWidgetSet<>lpNoGUI);
and (NewLCLWidgetSet<>lpNoGUI)
and (GetFPCompilerFilename=EnvironmentOptions.GetParsedCompilerFilename);
end;
end.