diff --git a/ide/buildmanager.pas b/ide/buildmanager.pas index e26627aee3..391443c373 100644 --- a/ide/buildmanager.pas +++ b/ide/buildmanager.pas @@ -113,6 +113,9 @@ type var Abort: boolean): string; function MacroFuncSecondaryConfigPath(const Param: string; const Data: PtrInt; var Abort: boolean): string; + function MacroFuncFallbackOutputRoot(const Param: string; const Data: PtrInt; + var Abort: boolean): string; + function CTMacroFuncProjectUnitPath(Data: Pointer): boolean; function CTMacroFuncProjectIncPath(Data: Pointer): boolean; function CTMacroFuncProjectSrcPath(Data: Pointer): boolean; @@ -318,6 +321,8 @@ begin lisPrimaryConfigPath, @MacroFuncPrimaryConfigPath, [])); GlobalMacroList.Add(TTransferMacro.Create('SecondaryConfigPath','', lisSecondaryConfigPath, @MacroFuncSecondaryConfigPath, [])); + GlobalMacroList.Add(TTransferMacro.Create('FallbackOutputRoot','', + lisSecondaryConfigPath, @MacroFuncFallbackOutputRoot, [])); // codetools macro functions CodeToolBoss.DefineTree.MacroFunctions.AddExtended( @@ -1405,6 +1410,12 @@ begin Result:=GetSecondaryConfigPath; end; +function TBuildManager.MacroFuncFallbackOutputRoot(const Param: string; + const Data: PtrInt; var Abort: boolean): string; +begin + Result:=AppendPathDelim(GetPrimaryConfigPath)+'lib'; +end; + function TBuildManager.MacroFuncSrcOS(const Param: string; const Data: PtrInt; var Abort: boolean): string; begin diff --git a/ide/compileroptions.pp b/ide/compileroptions.pp index f72c92ec76..628b6aa6b7 100644 --- a/ide/compileroptions.pp +++ b/ide/compileroptions.pp @@ -246,8 +246,7 @@ const type TLocalSubstitutionEvent = function(const s: string; PlatformIndependent: boolean): string of object; - TGetWritableOutputDirectory = procedure(var s: string) of object; - + TCompilerOptionsParseType = ( coptUnparsed, // no macros resolved coptParsed, // all macros resolved diff --git a/ide/msgquickfixes.pas b/ide/msgquickfixes.pas index 3b9df81332..fea3f4e744 100644 --- a/ide/msgquickfixes.pas +++ b/ide/msgquickfixes.pas @@ -109,6 +109,15 @@ type procedure Execute(const Msg: TIDEMessageLine; Step: TIMQuickFixStep); override; end; + { TQuickFixRecompilingChecksumChanged } + + TQuickFixRecompilingChecksumChanged = class(TIDEMsgQuickFixItem) + public + constructor Create; + function IsApplicable(Line: TIDEMessageLine): boolean; override; + procedure Execute(const Msg: TIDEMessageLine; Step: TIMQuickFixStep); override; + end; + procedure QuickFixParameterNotUsed(Sender: TObject; Step: TIMQuickFixStep; Msg: TIDEMessageLine); procedure QuickFixUnitNotUsed(Sender: TObject; Step: TIMQuickFixStep; @@ -250,6 +259,7 @@ begin RegisterIDEMsgQuickFix(TQuickFixIdentifierNotFoundAddLocal.Create); RegisterIDEMsgQuickFix(TQuickFixLocalVariableNotUsed_Remove.Create); RegisterIDEMsgQuickFix(TQuickFixHint_Hide.Create); + //RegisterIDEMsgQuickFix(TQuickFixRecompilingChecksumChanged.Create); end; procedure FreeStandardIDEQuickFixItems; @@ -257,6 +267,35 @@ begin FreeThenNil(IDEMsgQuickFixes); end; +{ TQuickFixRecompilingChecksumChanged } + +constructor TQuickFixRecompilingChecksumChanged.Create; +begin + Name:='Show dialog for message Recompiling Unit1, checksum changed for Unit1'; + Caption:='Explore message "checksum changed"'; + Steps:=[imqfoMenuItem]; +end; + +function TQuickFixRecompilingChecksumChanged.IsApplicable(Line: TIDEMessageLine + ): boolean; +begin + Result:=false; + if not REMatches(Line.Msg,'Recompiling ([a-z_][a-z_0-9]*), checksum changed for ([a-z_][a-z_0-9]*)','i') + then exit; + Result:=true; +end; + +procedure TQuickFixRecompilingChecksumChanged.Execute( + const Msg: TIDEMessageLine; Step: TIMQuickFixStep); +begin + if Step=imqfoMenuItem then begin + debugln(['TQuickFixRecompilingChecksumChanged.Execute ']); + if not REMatches(Msg.Msg,'Recompiling ([a-z_][a-z_0-9]*), checksum changed for ([a-z_][a-z_0-9]*)','i') + then exit; + debugln(['TQuickFixRecompilingChecksumChanged.Execute Unit1=',REVar(1),', checksum changed for Unit2=',REVar(2)]); + end; +end; + { TQuickFixUnitNotFoundPosition } constructor TQuickFixUnitNotFoundPosition.Create; diff --git a/ide/sourceeditor.pp b/ide/sourceeditor.pp index 6cf99507c6..614e86e967 100644 --- a/ide/sourceeditor.pp +++ b/ide/sourceeditor.pp @@ -5175,7 +5175,7 @@ var procedure MaybeAddPopup(const ASuffix: String; const ANewOnClick: TNotifyEvent); begin - if FileExistsUTF8(ChangeFileExt(CurFilename,ASuffix)) then + if FileExistsCached(ChangeFileExt(CurFilename,ASuffix)) then AddContextPopupMenuItem(Format(lisOpenLfm, [ChangeFileExt(FileName,ASuffix)]), true, ANewOnClick); end; diff --git a/ideintf/texttools.pas b/ideintf/texttools.pas index d7c0c95290..b4e06f3285 100644 --- a/ideintf/texttools.pas +++ b/ideintf/texttools.pas @@ -50,7 +50,7 @@ var of REMatches. The ModifierStr sets the default values of r.e.syntax modifiers. Modifiers in r.e. (?ismx-ismx) will replace this default values. - If you try to set unsupported modifier, Error will be called + If you try to set unsupported modifier, an exception is raised Modifier /i - caseinsensitive, initialized from RegExprModifierI Modifier /s - '.' works as any char (else as [^\n]), @@ -63,7 +63,7 @@ var Examples: if REMatches('Lazarus','aza') then ... - if REMatches('Lazarus','a(.)a') then + if REMatches('Lazarus','a(.)a','i') then s:=REVar(1); // this will be the 'z' } diff --git a/packager/packagedefs.pas b/packager/packagedefs.pas index 1bea374e5a..a790ea2a1f 100644 --- a/packager/packagedefs.pas +++ b/packager/packagedefs.pas @@ -861,7 +861,6 @@ var OnGetAllRequiredPackages: TGetAllRequiredPackagesEvent = nil; OnGetDependencyOwnerDescription: TGetDependencyOwnerDescription = nil; OnGetDependencyOwnerDirectory: TGetDependencyOwnerDirectory = nil; - OnGetWritablePkgOutputDirectory: TGetWritablePkgOutputDirectory = nil; OnPackageFileLoaded: TNotifyEvent = nil; function CompareLazPackageID(Data1, Data2: Pointer): integer; diff --git a/packager/packagesystem.pas b/packager/packagesystem.pas index d4c95dc643..0c8fcb95de 100644 --- a/packager/packagesystem.pas +++ b/packager/packagesystem.pas @@ -285,6 +285,7 @@ type out NeedBuildAllFlag: boolean): TModalResult; function PreparePackageOutputDirectory(APackage: TLazPackage; CleanUp: boolean): TModalResult; + function GetFallbackOutputDir(APackage: TLazPackage): string; function CheckAmbiguousPackageUnits(APackage: TLazPackage): TModalResult; function SavePackageMainSource(APackage: TLazPackage; Flags: TPkgCompileFlags; ShowAbort: boolean): TModalResult; @@ -3043,9 +3044,7 @@ begin end; // the normal output directory is not writable // => try the fallback directory - if not Assigned(OnGetWritablePkgOutputDirectory) then exit; - NewOutputDir:=OutputDir; - OnGetWritablePkgOutputDirectory(APackage,NewOutputDir); + NewOutputDir:=GetFallbackOutputDir(APackage); if (NewOutputDir=OutputDir) or (NewOutputDir='') then exit; APackage.CompilerOptions.ParsedOpts.OutputDirectoryOverride:=NewOutputDir; Result:=CheckIfCurPkgOutDirNeedsCompile(APackage, @@ -3854,9 +3853,7 @@ begin begin // the normal output directory is not writable // => use the fallback directory - if not Assigned(OnGetWritablePkgOutputDirectory) then exit(mrCancel); - NewOutputDir:=OutputDir; - OnGetWritablePkgOutputDirectory(APackage,NewOutputDir); + NewOutputDir:=GetFallbackOutputDir(APackage); if (NewOutputDir=OutputDir) or (NewOutputDir='') then exit(mrCancel); APackage.CompilerOptions.ParsedOpts.OutputDirectoryOverride:=NewOutputDir; end; @@ -3908,6 +3905,25 @@ begin Result:=mrOk; end; +function TLazPackageGraph.GetFallbackOutputDir(APackage: TLazPackage): string; +var + Dir: String; +begin + // use the default output directory, if it is relative + // (this way the fallback creates the same amount of target directories) + Dir:=APackage.CompilerOptions.ParsedOpts.UnparsedValues[pcosOutputDir]; + Dir:=APackage.SubstitutePkgMacros(Dir,false); + GlobalMacroList.SubstituteStr(Dir); + if FilenameIsAbsolute(Dir) then begin + // it is not relative => create a default one + Dir:='$(TargetOS)-$(TargetCPU)'; + end; + Dir:='$(FallbackOutputRoot)'+PathDelim+APackage.Name+PathDelim+Dir; + GlobalMacroList.SubstituteStr(Dir); + debugln(['TLazPackageGraph.GetFallbackOutputDir ',APackage.Name,': ',Dir]); + Result:=Dir; +end; + function TLazPackageGraph.CheckAmbiguousPackageUnits(APackage: TLazPackage ): TModalResult; var diff --git a/packager/pkgmanager.pas b/packager/pkgmanager.pas index b5b35c6889..8684e9b81b 100644 --- a/packager/pkgmanager.pas +++ b/packager/pkgmanager.pas @@ -154,8 +154,6 @@ type out Description: string); procedure GetDependencyOwnerDirectory(Dependency: TPkgDependency; out Directory: string); - procedure GetWritablePkgOutputDirectory(APackage: TLazPackage; - var AnOutDirectory: string); procedure PackageFileLoaded(Sender: TObject); procedure OnCheckInstallPackageList(PkgIDList: TFPList; out Ok: boolean); function LoadDependencyList(FirstDependency: TPkgDependency): TModalResult; @@ -213,7 +211,7 @@ type function GetSourceFilesOfOwners(OwnerList: TFPList): TStrings; override; function GetPossibleOwnersOfUnit(const UnitFilename: string; Flags: TPkgIntfOwnerSearchFlags): TFPList; override; - function GetPackageOfCurrentSourceEditor: TPkgFile; + function GetPackageOfCurrentSourceEditor(out APackage: TLazPackage): TPkgFile; function AddDependencyToOwners(OwnerList: TFPList; APackage: TLazPackage; OnlyTestIfPossible: boolean = false): TModalResult; override; function DoOpenPkgFile(PkgFile: TPkgFile): TModalResult; @@ -469,28 +467,6 @@ begin GetDirectoryOfDependencyOwner(Dependency,Directory); end; -procedure TPkgManager.GetWritablePkgOutputDirectory(APackage: TLazPackage; - var AnOutDirectory: string); -var - NewOutDir: String; -begin - if DirectoryIsWritableCached(AnOutDirectory) then exit; - - ForceDirectory(AnOutDirectory); - InvalidateFileStateCache; - if DirectoryIsWritableCached(AnOutDirectory) then exit; - //debugln('TPkgManager.GetWritablePkgOutputDirectory AnOutDirectory=',AnOutDirectory,' ',dbgs(DirectoryIsWritable(AnOutDirectory))); - - // output directory is not writable - // -> redirect to config directory - NewOutDir:=SetDirSeparators('/$(TargetCPU)-$(TargetOS)'); - IDEMacros.SubstituteMacros(NewOutDir); - NewOutDir:=TrimFilename(GetPrimaryConfigPath+PathDelim+'lib'+PathDelim - +APackage.Name+NewOutDir); - AnOutDirectory:=NewOutDir; - debugln('TPkgManager.GetWritablePkgOutputDirectory APackage=',APackage.IDAsString,' AnOutDirectory="',AnOutDirectory,'"'); -end; - procedure TPkgManager.PackageFileLoaded(Sender: TObject); begin DoCallNotifyHandler(pihtPackageFileLoaded,Sender); @@ -574,11 +550,11 @@ end; procedure TPkgManager.OnOpenPackageForCurrentSrcEditFile(Sender: TObject); var - PkgFile: TPkgFile; + APackage: TLazPackage; begin - PkgFile:=GetPackageOfCurrentSourceEditor; - if PkgFile<>nil then - DoOpenPackage(PkgFile.LazPackage,[],false); + GetPackageOfCurrentSourceEditor(APackage); + if APackage<>nil then + DoOpenPackage(APackage,[],false); end; procedure TPkgManager.CreateIDEWindow(Sender: TObject; aFormName: string; var @@ -1508,7 +1484,6 @@ begin inherited Create(TheOwner); OnGetDependencyOwnerDescription:=@GetDependencyOwnerDescription; OnGetDependencyOwnerDirectory:=@GetDependencyOwnerDirectory; - OnGetWritablePkgOutputDirectory:=@GetWritablePkgOutputDirectory; OnPackageFileLoaded:=@PackageFileLoaded; // componentpalette @@ -1720,11 +1695,11 @@ end; procedure TPkgManager.OnSourceEditorPopupMenu( const AddMenuItemProc: TAddMenuItemProc); var - PkgFile: TPkgFile; + APackage: TLazPackage; begin - PkgFile:=GetPackageOfCurrentSourceEditor; - if PkgFile<>nil then - AddMenuItemProc(Format(lisOpenPackage2, [PkgFile.LazPackage.Name]), true, + GetPackageOfCurrentSourceEditor(APackage); + if APackage<>nil then + AddMenuItemProc(Format(lisOpenPackage2, [APackage.Name]), true, @OnOpenPackageForCurrentSrcEditFile); end; @@ -3138,15 +3113,29 @@ begin FreeThenNil(Result); end; -function TPkgManager.GetPackageOfCurrentSourceEditor: TPkgFile; +function TPkgManager.GetPackageOfCurrentSourceEditor(out APackage: TLazPackage + ): TPkgFile; var SrcEdit: TSourceEditor; + Filename: String; + i: Integer; begin + Result:=nil; + APackage:=nil; SrcEdit:=SourceEditorManager.GetActiveSE; - if SrcEdit<>nil then begin - Result:=SearchFile(SrcEdit.Filename,[],nil); - end else - SrcEdit:=nil; + if SrcEdit=nil then exit; + Filename:=SrcEdit.FileName; + Result:=SearchFile(Filename,[],nil); + if Result<>nil then begin + APackage:=Result.LazPackage; + exit; + end; + for i:=0 to PackageGraph.Count-1 do begin + APackage:=PackageGraph[i]; + if CompareFilenames(APackage.GetSrcFilename,SrcEdit.FileName)=0 then + exit; + end; + APackage:=nil; end; function TPkgManager.AddDependencyToOwners(OwnerList: TFPList;