From 0f252ce4238f0c3b786a902584493327bde14799 Mon Sep 17 00:00:00 2001 From: mattias Date: Fri, 28 Feb 2014 13:38:12 +0000 Subject: [PATCH] IDE: using -Xp and -V as keys for cache of fpc settings git-svn-id: trunk@44289 - --- components/codetools/definetemplates.pas | 52 +++++++---- ide/buildmanager.pas | 114 ++++++++++++++++------- 2 files changed, 116 insertions(+), 50 deletions(-) diff --git a/components/codetools/definetemplates.pas b/components/codetools/definetemplates.pas index 8e295ab649..8809445098 100644 --- a/components/codetools/definetemplates.pas +++ b/components/codetools/definetemplates.pas @@ -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 + fpcpP, // -P + fpcpV, // -V + fpcpXp // -Xp + ); + 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) diff --git a/ide/buildmanager.pas b/ide/buildmanager.pas index 2d5da1a3b0..d2386dff20 100644 --- a/ide/buildmanager.pas +++ b/ide/buildmanager.pas @@ -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.