From 4d13235ea083acfc7e899a1bca11ae8e02fa36ac Mon Sep 17 00:00:00 2001 From: joost Date: Tue, 15 Feb 2011 15:56:21 +0000 Subject: [PATCH] * Store the location of the original source when installing a package * Store the used options to install a package in fpunits.conf * When a package is re-installed because of broken dependencies, use the stored source-path and options if possible * When installing a package from the current directory, make sure the right directory is used. It could be changed while installing dependencies. git-svn-id: trunk@16918 - --- packages/fpmkunit/src/fpmkunit.pp | 15 ++++++++-- utils/fppkg/fprepos.pp | 10 +++++++ utils/fppkg/pkgcommands.pp | 33 ++++++++++++++++++---- utils/fppkg/pkgfpmake.pp | 46 +++++++++++++++++++------------ utils/fppkg/pkghandler.pp | 16 ++++++++++- utils/fppkg/pkgrepos.pp | 38 +++++++++++++++++++++---- 6 files changed, 126 insertions(+), 32 deletions(-) diff --git a/packages/fpmkunit/src/fpmkunit.pp b/packages/fpmkunit/src/fpmkunit.pp index bdb7173f42..64485893e8 100644 --- a/packages/fpmkunit/src/fpmkunit.pp +++ b/packages/fpmkunit/src/fpmkunit.pp @@ -869,6 +869,7 @@ Type FRunMode: TRunMode; FListMode : Boolean; FLogLevels : TVerboseLevels; + FFPMakeOptionsString: string; Protected Procedure Log(Level : TVerboseLevel; Const Msg : String); Procedure CreatePackages; virtual; @@ -891,6 +892,7 @@ Type Destructor destroy; override; Function AddPackage(Const AName : String) : TPackage; Function Run : Boolean; + Property FPMakeOptionsString: string read FFPMakeOptionsString; //files in package Property Packages : TPackages Read GetPackages; Property RunMode : TRunMode Read FRunMode; @@ -1145,6 +1147,8 @@ Const KeyNeedLibC = 'NeedLibC'; KeyDepends = 'Depends'; KeyAddIn = 'FPMakeAddIn'; + KeySourcePath = 'SourcePath'; + KeyFPMakeOptions = 'FPMakeOptions'; {**************************************************************************** Helpers @@ -2553,6 +2557,9 @@ begin Values[KeyChecksum]:=IntToStr(DateTimeToFileDate(Now)); Values[KeyCPU]:=CPUToString(ACPU); Values[KeyOS]:=OSToString(AOS); + //Installer; + Values[KeySourcePath]:=IncludeTrailingPathDelimiter(IncludeTrailingPathDelimiter(Installer.BuildEngine.FStartDir)+Directory); + Values[KeyFPMakeOptions]:=trim(Installer.FPMakeOptionsString); Deps:=''; for i:=0 to Dependencies.Count-1 do begin @@ -3130,12 +3137,13 @@ end; procedure TCustomInstaller.AnalyzeOptions; - Function CheckOption(Index : Integer;const Short,Long : String): Boolean; + Function CheckOption(Index : Integer;const Short,Long : String; AddToOptionString: boolean = true): Boolean; var O : String; begin O:=Paramstr(Index); Result:=(O='-'+short) or (O='--'+long) or (copy(O,1,Length(Long)+3)=('--'+long+'=')); + if AddToOptionString and Result then FFPMakeOptionsString := FFPMakeOptionsString+' '+O; end; Function CheckCustomOption(Index : Integer; out CustOptName: string): Boolean; @@ -3154,6 +3162,7 @@ procedure TCustomInstaller.AnalyzeOptions; O:=copy(O,3,i-3); CustOptName:=O; Result:=CustomFpmakeCommandlineOptions.IndexOfName(O)>-1; + if Result then FFPMakeOptionsString := FFPMakeOptionsString+' '+Paramstr(Index); end; @@ -3220,9 +3229,9 @@ begin While (I'' then begin @@ -245,7 +247,12 @@ begin else begin ExecuteAction(PackageName,'installdependencies'); - ExecuteAction(PackageName,'unzip'); + // Check if the package is not installed but being recompiled because of changed + // dependencies while the original source is still available. + P := AvailableRepository.FindPackage(PackageName); + if not (assigned(P) and P.RecompileBroken and (P.SourcePath<>'')) then + // The package is not available locally, download and unzip it. + ExecuteAction(PackageName,'unzip'); end; end; ExecuteAction(PackageName,'fpmakebuild'); @@ -275,10 +282,26 @@ begin P:=InstalledRepository.FindPackage(S); if not assigned(P) then P:=InstalledRepository.AddPackage(S); - if IsSuperUser or GlobalOptions.InstallGlobal then - UFN:=CompilerOptions.GlobalUnitDir + if P.RecompileBroken then + begin + // If the package is recompiled, the installation-location is dependent on where + // the package was installed originally. + if P.InstalledLocally then + UFN:=CompilerOptions.LocalUnitDir + else + UFN:=CompilerOptions.GlobalUnitDir; + // Setting RecompileBroken to false is in a strict sense not needed. But it is better + // to clean this temporary flag, to avoid problems with changes in the future + P.RecompileBroken := false; + AvailableRepository.FindPackage(P.Name).RecompileBroken:=false; + end else - UFN:=CompilerOptions.LocalUnitDir; + begin + if (IsSuperUser or GlobalOptions.InstallGlobal) then + UFN:=CompilerOptions.GlobalUnitDir + else + UFN:=CompilerOptions.LocalUnitDir; + end; UFN:=IncludeTrailingPathDelimiter(UFN)+S+PathDelim+UnitConfigFileName; LoadUnitConfigFromFile(P,UFN); end @@ -352,7 +375,7 @@ begin end else begin - if PackageIsBroken(InstalledP) then + if PackageIsBroken(InstalledP, True) then begin status:='Broken, recompiling'; L.Add(D.PackageName); diff --git a/utils/fppkg/pkgfpmake.pp b/utils/fppkg/pkgfpmake.pp index c0382c5a61..453e21ebe5 100644 --- a/utils/fppkg/pkgfpmake.pp +++ b/utils/fppkg/pkgfpmake.pp @@ -295,32 +295,42 @@ begin { Maybe compile fpmake executable? } ExecuteAction(PackageName,'compilefpmake'); { Create options } - AddOption('--nofpccfg'); if vlDebug in LogLevels then AddOption('--debug') else if vlInfo in LogLevels then AddOption('--verbose'); - AddOption('--compiler='+CompilerOptions.Compiler); - AddOption('--cpu='+CPUToString(CompilerOptions.CompilerCPU)); - AddOption('--os='+OSToString(CompilerOptions.CompilerOS)); - if CompilerOptions.HasOptions then - AddOption('--options='+CompilerOptions.Options.DelimitedText); - if IsSuperUser or GlobalOptions.InstallGlobal then + if P.RecompileBroken and + (P.FPMakeOptionsString<>'') then // Check for a empty FPMakeOptionString for packages being installed with an old fpmkunit begin - CondAddOption('--prefix',CompilerOptions.GlobalPrefix); - CondAddOption('--baseinstalldir',CompilerOptions.GlobalInstallDir); + // When the package is being reinstalled because of broken dependencies, use the same fpmake-options + // as were used to compile the package in the first place. + OOptions:=P.FPMakeOptionsString; end else begin - CondAddOption('--prefix',CompilerOptions.LocalPrefix); - CondAddOption('--baseinstalldir',CompilerOptions.LocalInstallDir); - end; - CondAddOption('--localunitdir',CompilerOptions.LocalUnitDir); - CondAddOption('--globalunitdir',CompilerOptions.GlobalUnitDir); - if GlobalOptions.CustomFPMakeOptions<>'' then - begin - AddOption('--ignoreinvalidoption'); - AddOption(GlobalOptions.CustomFPMakeOptions); + AddOption('--nofpccfg'); + AddOption('--compiler='+CompilerOptions.Compiler); + AddOption('--cpu='+CPUToString(CompilerOptions.CompilerCPU)); + AddOption('--os='+OSToString(CompilerOptions.CompilerOS)); + if CompilerOptions.HasOptions then + AddOption('--options='+CompilerOptions.Options.DelimitedText); + if IsSuperUser or GlobalOptions.InstallGlobal then + begin + CondAddOption('--prefix',CompilerOptions.GlobalPrefix); + CondAddOption('--baseinstalldir',CompilerOptions.GlobalInstallDir); + end + else + begin + CondAddOption('--prefix',CompilerOptions.LocalPrefix); + CondAddOption('--baseinstalldir',CompilerOptions.LocalInstallDir); + end; + CondAddOption('--localunitdir',CompilerOptions.LocalUnitDir); + CondAddOption('--globalunitdir',CompilerOptions.GlobalUnitDir); + if GlobalOptions.CustomFPMakeOptions<>'' then + begin + AddOption('--ignoreinvalidoption'); + AddOption(GlobalOptions.CustomFPMakeOptions); + end; end; { Run FPMake } FPMakeBin:='fpmake'+ExeExt; diff --git a/utils/fppkg/pkghandler.pp b/utils/fppkg/pkghandler.pp index faca158489..0a15ac9687 100644 --- a/utils/fppkg/pkghandler.pp +++ b/utils/fppkg/pkghandler.pp @@ -57,6 +57,7 @@ uses var PkgHandlerList : TFPHashList; ExecutedActions : TFPHashList; + CurrentDir : string; procedure RegisterPkgHandler(const AAction:string;pkghandlerclass:TPackageHandlerClass); begin @@ -106,9 +107,22 @@ end; function PackageBuildPath(APackage:TFPPackage):String; begin if APackage.Name=CurrentDirPackageName then - Result:='.' + begin + // It could be that to resolve some dependencies, the current directory changes. The first time + // PackageBuildPath is called the dependencies are not resolved yet, so store the current directory + // for later calls. + if CurrentDir='' then + begin + Result:='.'; + CurrentDir := SysUtils.GetCurrentDir; + end + else + Result:=CurrentDir; + end else if APackage.Name=CmdLinePackageName then Result:=GlobalOptions.BuildDir+ChangeFileExt(ExtractFileName(APackage.LocalFileName),'') + else if (APackage.RecompileBroken) and (APackage.SourcePath<>'') then + Result:=APackage.SourcePath else Result:=GlobalOptions.BuildDir+APackage.Name; end; diff --git a/utils/fppkg/pkgrepos.pp b/utils/fppkg/pkgrepos.pp index bdc2c8765f..7e9562c29c 100644 --- a/utils/fppkg/pkgrepos.pp +++ b/utils/fppkg/pkgrepos.pp @@ -15,7 +15,7 @@ procedure LoadLocalAvailableRepository; procedure LoadUnitConfigFromFile(APackage:TFPPackage;const AFileName: String); function LoadManifestFromFile(const AManifestFN:string):TFPPackage; procedure FindInstalledPackages(ACompilerOptions:TCompilerOptions;showdups:boolean=true); -function PackageIsBroken(APackage:TFPPackage):boolean; +function PackageIsBroken(APackage:TFPPackage; MarkForReInstall: boolean):boolean; function FindBrokenPackages(SL:TStrings):Boolean; procedure CheckFPMakeDependencies; function PackageInstalledVersionStr(const AName:String;const ShowUsed: boolean = false;const Local: boolean = false):string; @@ -216,6 +216,8 @@ begin V:=L.Values['version']; APackage.Version.AsString:=V; APackage.IsFPMakeAddIn:=Upcase(L.Values['FPMakeAddIn'])='Y'; + APackage.SourcePath:=L.Values['SourcePath']; + APackage.FPMakeOptionsString:=L.Values['FPMakeOptions']; V:=L.Values['checksum']; if V<>'' then APackage.Checksum:=StrToInt(V) @@ -347,11 +349,12 @@ begin end; -function PackageIsBroken(APackage:TFPPackage):boolean; +function PackageIsBroken(APackage:TFPPackage; MarkForReInstall: boolean):boolean; var j : integer; D : TFPDependency; DepPackage : TFPPackage; + AvailP: TFPPackage; begin result:=false; for j:=0 to APackage.Dependencies.Count-1 do @@ -368,6 +371,29 @@ begin begin Log(vlInfo,SLogPackageChecksumChanged,[APackage.Name,D.PackageName]); result:=true; + if MarkForReInstall then + begin + // When the package is re-installed, use the same fpmake-options and sourcepath + // as used during the initial installation. (The AvailableRepository is used to install + // the package so make sure all properties are set there) + AvailP:=AvailableRepository.FindPackage(APackage.Name); + if not assigned(AvailP) then + begin + AvailP := AvailableRepository.AddPackage(APackage.Name); + AvailP.Assign(APackage); + end + else + begin + AvailP.SourcePath := APackage.SourcePath; + AvailP.FPMakeOptionsString := APackage.FPMakeOptionsString; + end; + AvailP.RecompileBroken:=true; + APackage.RecompileBroken:=true; + // If the fpmake.pp of the original installation is not available anymore, do not + // try to use it. + if (AvailP.SourcePath<>'') and not FileExists(IncludeTrailingPathDelimiter(APackage.SourcePath)+'fpmake.pp') then + AvailP.SourcePath:=''; + end; exit; end; end @@ -387,8 +413,10 @@ begin for i:=0 to InstalledRepository.PackageCount-1 do begin P:=InstalledRepository.Packages[i]; - if PackageIsBroken(P) then - SL.Add(P.Name); + if PackageIsBroken(P,True) then + begin + SL.Add(P.Name); + end; end; Result:=(SL.Count>0); end; @@ -507,7 +535,7 @@ var begin result := ''; P:=InstalledRepository.FindPackage(AName); - if (P<>nil) and PackageIsBroken(P) then + if (P<>nil) and PackageIsBroken(P,false) then result:='B'; end;