mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-30 11:00:28 +02:00
* 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 -
This commit is contained in:
parent
d3afac1736
commit
4d13235ea0
@ -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<ParamCount) do
|
||||
begin
|
||||
Inc(I);
|
||||
if CheckOption(I,'v','verbose') then
|
||||
if CheckOption(I,'v','verbose',false) then
|
||||
FLogLevels:=AllMessages
|
||||
else if CheckOption(I,'d','debug') then
|
||||
else if CheckOption(I,'d','debug',false) then
|
||||
FLogLevels:=AllMessages+[vlDebug]
|
||||
else if CheckCommand(I,'m','compile') then
|
||||
FRunMode:=rmCompile
|
||||
|
@ -113,6 +113,9 @@ type
|
||||
FAuthor: String;
|
||||
FDescription: String;
|
||||
FEmail: String;
|
||||
FFPMakeOptionsString: string;
|
||||
FRecompileBroken: boolean;
|
||||
FSourcePath: string;
|
||||
FInstalledLocally: boolean;
|
||||
FIsFPMakeAddIn: boolean;
|
||||
FLicense: String;
|
||||
@ -143,6 +146,7 @@ type
|
||||
// Only for installed packages: (is false for packages which are installed globally)
|
||||
Property InstalledLocally : boolean read FInstalledLocally write FInstalledLocally;
|
||||
Property UnusedVersion : TFPVersion Read FUnusedVersion Write SetUnusedVersion;
|
||||
Property RecompileBroken : boolean read FRecompileBroken write FRecompileBroken;
|
||||
Published
|
||||
Property Name : String Read FName Write SetName;
|
||||
Property Author : String Read FAuthor Write FAuthor;
|
||||
@ -157,6 +161,9 @@ type
|
||||
Property CPUs : TCPUs Read FCPUs Write FCPUs;
|
||||
Property Checksum : Cardinal Read FChecksum Write FChecksum;
|
||||
Property IsFPMakeAddIn : boolean read FIsFPMakeAddIn write FIsFPMakeAddIn;
|
||||
// These properties are used to re-compile the package, when it's dependencies are changed.
|
||||
Property SourcePath : string read FSourcePath write FSourcePath;
|
||||
Property FPMakeOptionsString : string read FFPMakeOptionsString write FFPMakeOptionsString;
|
||||
// Manual package from commandline not in official repository
|
||||
Property LocalFileName : String Read FLocalFileName Write FLocalFileName;
|
||||
end;
|
||||
@ -661,6 +668,9 @@ begin
|
||||
Description:=P.Description;
|
||||
HomepageURL:=P.HomepageURL;
|
||||
DownloadURL:=P.DownloadURL;
|
||||
SourcePath:=P.SourcePath;
|
||||
FPMakeOptionsString:=P.FPMakeOptionsString;
|
||||
InstalledLocally:=P.InstalledLocally;
|
||||
OSes:=P.OSes;
|
||||
CPUs:=P.CPUs;
|
||||
FileName:=P.FileName;
|
||||
|
@ -227,6 +227,8 @@ end;
|
||||
|
||||
|
||||
procedure TCommandBuild.Execute;
|
||||
var
|
||||
P: TFPPackage;
|
||||
begin
|
||||
if PackageName<>'' 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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user