mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-02 00:10:31 +02:00
* Adapted tests for broken dependencies (packages)
* Reload AddIn-state after an AddIn has been compiled * Fixed re-compilation of already installed packages, based on the original sources * Improved the algorithm to determine which package to use when a package is being build based on package-name git-svn-id: trunk@35533 -
This commit is contained in:
parent
a2bd07bfd6
commit
2a01a603d8
@ -365,7 +365,14 @@ end;
|
||||
|
||||
function TFPCustomPackagesStructure.GetBuildPathDirectory(APackage: TFPPackage): string;
|
||||
begin
|
||||
Result := '';
|
||||
if (APackage.Repository.RepositoryType=fprtInstalled) and (APackage.SourcePath<>'') then
|
||||
begin
|
||||
Result := APackage.SourcePath;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Result := '';
|
||||
end;
|
||||
end;
|
||||
|
||||
function TFPCustomPackagesStructure.GetPrefix: string;
|
||||
|
@ -562,7 +562,7 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
if PackageManager.PackageIsBroken(InstalledP, InstalledP.Repository) then
|
||||
if PackageManager.PackageIsBroken(InstalledP, nil) then
|
||||
begin
|
||||
status:='Broken, recompiling';
|
||||
L.Add(D.PackageName);
|
||||
@ -610,10 +610,12 @@ procedure TCommandFixBroken.Execute;
|
||||
var
|
||||
i : integer;
|
||||
SL : TStringList;
|
||||
BreakLoop : Boolean;
|
||||
begin
|
||||
SL:=TStringList.Create;
|
||||
BreakLoop := false;
|
||||
repeat
|
||||
FindBrokenPackages(SL);
|
||||
PackageManager.FindBrokenPackages(SL);
|
||||
if SL.Count=0 then
|
||||
break;
|
||||
pkgglobals.Log(llProgres,SProgrReinstallDependent);
|
||||
@ -621,8 +623,13 @@ begin
|
||||
begin
|
||||
ExecuteAction(SL[i],'build');
|
||||
ExecuteAction(SL[i],'install-req');
|
||||
if PackageManager.PackageIsBroken(PackageManager.PackageByName(SL[i], pkgpkInstalled), nil) then
|
||||
begin
|
||||
BreakLoop := true;
|
||||
pkgglobals.Log(llWarning, SWarnBrokenAfterReinstall, [SL[i]]);
|
||||
end;
|
||||
end;
|
||||
until false;
|
||||
until BreakLoop;
|
||||
FreeAndNil(SL);
|
||||
end;
|
||||
|
||||
|
@ -23,6 +23,8 @@ type
|
||||
{ TFPMakeCompiler }
|
||||
|
||||
TFPMakeCompiler = Class(TPackagehandler)
|
||||
protected
|
||||
function DeterminePackage: TFPPackage;
|
||||
Public
|
||||
Procedure Execute;override;
|
||||
end;
|
||||
@ -30,7 +32,7 @@ type
|
||||
|
||||
{ TFPMakeRunner }
|
||||
|
||||
TFPMakeRunner = Class(TPackagehandler)
|
||||
TFPMakeRunner = Class(TFPMakeCompiler)
|
||||
Protected
|
||||
Function RunFPMake(const Command:string):Integer;
|
||||
end;
|
||||
@ -132,6 +134,28 @@ end;
|
||||
|
||||
{ TFPMakeCompiler }
|
||||
|
||||
function TFPMakeCompiler.DeterminePackage: TFPPackage;
|
||||
var
|
||||
PA, PI: TFPPackage;
|
||||
begin
|
||||
PA:=PackageManager.FindPackage(PackageName, pkgpkAvailable);
|
||||
PI:=PackageManager.FindPackage(PackageName, pkgpkInstalled);
|
||||
if Assigned(PA) and Assigned(PI) then
|
||||
begin
|
||||
if PA.Version.CompareVersion(PI.Version) > 0 then
|
||||
Result := PA
|
||||
else
|
||||
Result := PI;
|
||||
end
|
||||
else if Assigned(PI) then
|
||||
Result := PI
|
||||
else
|
||||
Result := PA;
|
||||
|
||||
if not Assigned(Result) then
|
||||
Raise EPackage.CreateFmt(SErrMissingPackage,[PackageName]);
|
||||
end;
|
||||
|
||||
Procedure TFPMakeCompiler.Execute;
|
||||
var
|
||||
OOptions : string;
|
||||
@ -168,7 +192,7 @@ Var
|
||||
FPMKUnitDepPackage: TFPPackage;
|
||||
P : TFPPackage;
|
||||
begin
|
||||
P:=PackageManager.PackageByName(PackageName, pkgpkAvailable);
|
||||
P:=DeterminePackage;
|
||||
NeedFPMKUnitSource:=false;
|
||||
OOptions:='';
|
||||
SetCurrentDir(PackageManager.PackageBuildPath(P));
|
||||
@ -323,7 +347,7 @@ begin
|
||||
// Does the current package support this CPU-OS?
|
||||
if PackageName<>'' then
|
||||
begin
|
||||
P:=PackageManager.PackageByName(PackageName, pkgpkAvailable);
|
||||
P := DeterminePackage;
|
||||
if (PackageName=CurrentDirPackageName) and (FileExists(ManifestFileName)) then
|
||||
ObtainSupportedTargetsFromManifest(p);
|
||||
end
|
||||
|
@ -21,6 +21,9 @@ type
|
||||
TpkgPackageKind = (pkgpkInstalled, pkgpkAvailable, pkgpkBoth);
|
||||
TpkgFPpkg = class(TComponent)
|
||||
private
|
||||
FInsideFindBrokenPackages: Integer;
|
||||
FBrokenPackagesDictionary: TFPHashList;
|
||||
|
||||
FFPMakeRepositoryList: TComponentList;
|
||||
FRepositoryList: TComponentList;
|
||||
FOptions: TFppkgOptions;
|
||||
@ -35,6 +38,8 @@ type
|
||||
function FindPackage(ARepositoryList: TComponentList; APackageName: string; APackageKind: TpkgPackageKind): TFPPackage;
|
||||
|
||||
function SelectRemoteMirror:string;
|
||||
procedure EnterFindBrokenPackages;
|
||||
procedure LeaveFindBrokenpackages;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -63,6 +68,7 @@ type
|
||||
|
||||
procedure ScanInstalledPackagesForAvailablePackages;
|
||||
procedure CheckFPMakeDependencies;
|
||||
function FindBrokenPackages(SL:TStrings):Boolean;
|
||||
|
||||
property Options: TFppkgOptions read FOptions;
|
||||
property CompilerOptions: TCompilerOptions read FCompilerOptions;
|
||||
@ -90,10 +96,12 @@ begin
|
||||
FFpmakeCompilerOptions := TCompilerOptions.Create;
|
||||
FRepositoryList := TComponentList.Create(False);
|
||||
FFPMakeRepositoryList := TComponentList.Create(False);
|
||||
FBrokenPackagesDictionary := TFPHashList.Create;
|
||||
end;
|
||||
|
||||
destructor TpkgFPpkg.Destroy;
|
||||
begin
|
||||
FBrokenPackagesDictionary.Free;
|
||||
FFPMakeRepositoryList.Free;
|
||||
FRepositoryList.Free;
|
||||
FCompilerOptions.Free;
|
||||
@ -321,57 +329,82 @@ var
|
||||
Dependency: TFPDependency;
|
||||
Repository: TFPRepository;
|
||||
DepPackage: TFPPackage;
|
||||
HashPtr: PtrInt;
|
||||
begin
|
||||
result:=false;
|
||||
|
||||
if not Assigned(ARepository) then
|
||||
begin
|
||||
// Check with all repositories
|
||||
ThisRepositoryIndex := RepositoryList.Count -1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// We should only check for dependencies in this repository, or repositories
|
||||
// with a lower priority.
|
||||
ThisRepositoryIndex := -1;
|
||||
for i := RepositoryList.Count -1 downto 0 do
|
||||
EnterFindBrokenPackages;
|
||||
try
|
||||
HashPtr := PtrInt(FBrokenPackagesDictionary.Find(APackage.Name));
|
||||
if HashPtr<>0 then
|
||||
begin
|
||||
if RepositoryList.Items[i] = ARepository then
|
||||
ThisRepositoryIndex := i;
|
||||
// Package is already evaluated
|
||||
Result := (HashPtr = 1);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
for j:=0 to APackage.Dependencies.Count-1 do
|
||||
begin
|
||||
Dependency:=APackage.Dependencies[j];
|
||||
if (CompilerOptions.CompilerOS in Dependency.OSes) and
|
||||
(CompilerOptions.CompilerCPU in Dependency.CPUs) then
|
||||
if not Assigned(ARepository) then
|
||||
begin
|
||||
// Check with all repositories
|
||||
ThisRepositoryIndex := RepositoryList.Count -1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// We should only check for dependencies in this repository, or repositories
|
||||
// with a lower priority.
|
||||
ThisRepositoryIndex := -1;
|
||||
for i := RepositoryList.Count -1 downto 0 do
|
||||
begin
|
||||
for i := ThisRepositoryIndex downto 0 do
|
||||
begin
|
||||
Repository := RepositoryList.Items[i] as TFPRepository;
|
||||
DepPackage := Repository.FindPackage(Dependency.PackageName);
|
||||
if Assigned(DepPackage) then
|
||||
Break;
|
||||
end;
|
||||
|
||||
if assigned(DepPackage) then
|
||||
begin
|
||||
if (Dependency.RequireChecksum<>$ffffffff) and (DepPackage.Checksum<>Dependency.RequireChecksum) then
|
||||
begin
|
||||
log(llInfo,SLogPackageChecksumChanged,[APackage.Name,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
log(llDebug,SDbgObsoleteDependency,[APackage.Name,Dependency.PackageName]);
|
||||
result:=true;
|
||||
exit;
|
||||
end;
|
||||
if RepositoryList.Items[i] = ARepository then
|
||||
ThisRepositoryIndex := i;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
for j:=0 to APackage.Dependencies.Count-1 do
|
||||
begin
|
||||
Dependency:=APackage.Dependencies[j];
|
||||
if (CompilerOptions.CompilerOS in Dependency.OSes) and
|
||||
(CompilerOptions.CompilerCPU in Dependency.CPUs) then
|
||||
begin
|
||||
DepPackage := nil;
|
||||
for i := ThisRepositoryIndex downto 0 do
|
||||
begin
|
||||
Repository := RepositoryList.Items[i] as TFPRepository;
|
||||
if Repository.RepositoryType=fprtInstalled then
|
||||
DepPackage := Repository.FindPackage(Dependency.PackageName);
|
||||
if Assigned(DepPackage) then
|
||||
Break;
|
||||
end;
|
||||
|
||||
if assigned(DepPackage) then
|
||||
begin
|
||||
if PackageIsBroken(DepPackage, ARepository) then
|
||||
begin
|
||||
log(llInfo,SLogPackageDepBroken,[APackage.Name,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
|
||||
result:=true;
|
||||
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
|
||||
exit;
|
||||
end;
|
||||
if (Dependency.RequireChecksum<>$ffffffff) and (DepPackage.Checksum<>Dependency.RequireChecksum) then
|
||||
begin
|
||||
log(llInfo,SLogPackageChecksumChanged,[APackage.Name,APackage.Repository.RepositoryName,Dependency.PackageName,Repository.RepositoryName]);
|
||||
result:=true;
|
||||
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
|
||||
exit;
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
log(llInfo,SDbgObsoleteDependency,[APackage.Name,Dependency.PackageName]);
|
||||
result:=true;
|
||||
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(1));
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
FBrokenPackagesDictionary.Add(APackage.Name, Pointer(2));
|
||||
finally
|
||||
LeaveFindBrokenpackages;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TpkgFPpkg.FPMakeRepoFindPackage(APackageName: string;
|
||||
@ -446,6 +479,20 @@ begin
|
||||
Error(SErrFailedToSelectMirror);
|
||||
end;
|
||||
|
||||
procedure TpkgFPpkg.EnterFindBrokenPackages;
|
||||
begin
|
||||
Assert((FInsideFindBrokenPackages>0) or (FBrokenPackagesDictionary.Count=0));
|
||||
Inc(FInsideFindBrokenPackages)
|
||||
end;
|
||||
|
||||
procedure TpkgFPpkg.LeaveFindBrokenpackages;
|
||||
begin
|
||||
Assert(FInsideFindBrokenPackages>0);
|
||||
Dec(FInsideFindBrokenPackages);
|
||||
if FInsideFindBrokenPackages=0 then
|
||||
FBrokenPackagesDictionary.Clear;
|
||||
end;
|
||||
|
||||
function TpkgFPpkg.PackageByName(APackageName: string; APackageKind: TpkgPackageKind): TFPPackage;
|
||||
var
|
||||
ErrStr: string;
|
||||
@ -578,6 +625,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TpkgFPpkg.FindBrokenPackages(SL: TStrings): Boolean;
|
||||
var
|
||||
i,j,k : integer;
|
||||
P : TFPPackage;
|
||||
Repo: TFPRepository;
|
||||
begin
|
||||
SL.Clear;
|
||||
EnterFindBrokenPackages;
|
||||
try
|
||||
for i:=0 to RepositoryList.Count-1 do
|
||||
begin
|
||||
Repo := TFPRepository(RepositoryList[i]);
|
||||
if Repo.RepositoryType = fprtInstalled then
|
||||
begin
|
||||
for j := 0 to Repo.PackageCount-1 do
|
||||
begin
|
||||
P := Repo.Packages[j];
|
||||
if (P = FindPackage(P.Name, pkgpkInstalled)) and PackageIsBroken(P, nil) then
|
||||
SL.Add(P.Name);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
LeaveFindBrokenpackages;
|
||||
end;
|
||||
Result:=(SL.Count>0);
|
||||
end;
|
||||
|
||||
function TpkgFPpkg.PackageBuildPath(APackage: TFPPackage): String;
|
||||
begin
|
||||
if (APackage.Name=CmdLinePackageName) or (APackage.Name=URLPackageName) then
|
||||
|
@ -20,7 +20,7 @@ Resourcestring
|
||||
SErrMissingCompilerConfig = 'Could not find compiler configuration "%s"';
|
||||
SErrMissingInstallPackage = 'Package "%s" is not installed';
|
||||
SErrMissingAvailablePackage= 'Package "%s" is not available';
|
||||
SErrMissingPackage = 'Could not fin package "%s"';
|
||||
SErrMissingPackage = 'Could not find package "%s"';
|
||||
SErrMissingInstallRepo = 'Could not find repository "%s"';
|
||||
SErrNoPackageSpecified = 'No package specified';
|
||||
SErrNoPackageAvailable = 'Package %s %s is not available';
|
||||
@ -80,6 +80,7 @@ Resourcestring
|
||||
SLogLoadingMirrorsFile = 'Loading available mirrors from "%s"';
|
||||
SLogFindInstalledPackages = 'Searching for installed packages in "%s"';
|
||||
SLogFoundFPMakeAddin = 'Found FPMake-AddIn "%s"';
|
||||
SLogUpdateFPMakeAddin = 'FPMake-AddIn "%s" updated';
|
||||
SLogSavingStatusFile = 'Saving local status to "%s"';
|
||||
SLogFPMKUnitDepVersion = 'Checking for %s %s, installed %s, available %s';
|
||||
SLogFPMKUnitDepTooOld = 'Minimum version of %s is not installed, using internal fpmkunit with limited functionality';
|
||||
@ -89,6 +90,7 @@ Resourcestring
|
||||
SLogOldConfigFileFormat = 'Configuration file is in an old format';
|
||||
SLogPackageDependency = 'Dependency on package %s %s, installed %s, available %s (%s)';
|
||||
SLogPackageChecksumChanged = 'Package %s (%s) needs to be rebuild, dependency %s (%s) is modified';
|
||||
SLogPackageDepBroken = 'Package %s (%s) needs to be rebuild, dependency %s (%s) is broken';
|
||||
SLogCheckBrokenDependenvies= 'Checking for broken dependencies';
|
||||
SLogFailedToCreateManifest = 'Failed to create manifest from fpmake.pp-file (%s) while scanning for available packages: %s';
|
||||
SLogUseInternalFpmkunit = 'Fpmkunit not available, fallback to internal version.';
|
||||
@ -146,6 +148,8 @@ Resourcestring
|
||||
SDbgPackageDependencyOtherTarget = 'Dependency on package %s is not for %s';
|
||||
SDbgObsoleteDependency = 'Package %s depends on package %s which is not installed anymore';
|
||||
|
||||
SWarnBrokenAfterReinstall = 'Package %s is still broken, even after re-installation.';
|
||||
|
||||
SProgrReinstallDependent = 'Re-install packages which are dependent on just installed packages';
|
||||
SProgrInstallDependencies = 'Install dependencies';
|
||||
SProgrDependenciesInstalled= 'Dependencies installed';
|
||||
|
@ -145,47 +145,37 @@ end;
|
||||
|
||||
|
||||
Procedure AddFPMakeAddIn(APackage: TFPPackage);
|
||||
var
|
||||
SelectedDep, i: Integer;
|
||||
begin
|
||||
log(llDebug,SLogFoundFPMakeAddin,[APackage.Name]);
|
||||
setlength(FPMKUnitDeps,length(FPMKUnitDeps)+1);
|
||||
FPMKUnitDeps[high(FPMKUnitDeps)].package:=APackage.Name;
|
||||
FPMKUnitDeps[high(FPMKUnitDeps)].reqver:=APackage.Version.AsString;
|
||||
FPMKUnitDeps[high(FPMKUnitDeps)].def:='HAS_PACKAGE_'+APackage.Name;
|
||||
FPMKUnitDeps[high(FPMKUnitDeps)].PluginUnit:=APackage.FPMakePluginUnits;
|
||||
FPMKUnitDeps[high(FPMKUnitDeps)].available:=true;
|
||||
SelectedDep := -1;
|
||||
for i := 0 to high(FPMKUnitDeps) do
|
||||
begin
|
||||
if FPMKUnitDeps[i].package = APackage.Name then
|
||||
begin
|
||||
log(llDebug,SLogUpdateFPMakeAddin,[APackage.Name]);
|
||||
SelectedDep := i;
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
|
||||
if SelectedDep = -1 then
|
||||
begin
|
||||
log(llDebug,SLogFoundFPMakeAddin,[APackage.Name]);
|
||||
setlength(FPMKUnitDeps,length(FPMKUnitDeps)+1);
|
||||
SelectedDep := high(FPMKUnitDeps);
|
||||
end;
|
||||
FPMKUnitDeps[SelectedDep].package:=APackage.Name;
|
||||
FPMKUnitDeps[SelectedDep].reqver:=APackage.Version.AsString;
|
||||
FPMKUnitDeps[SelectedDep].def:='HAS_PACKAGE_'+APackage.Name;
|
||||
FPMKUnitDeps[SelectedDep].PluginUnit:=APackage.FPMakePluginUnits;
|
||||
FPMKUnitDeps[SelectedDep].available:=true;
|
||||
end;
|
||||
|
||||
|
||||
function FindBrokenPackages(SL:TStrings):Boolean;
|
||||
var
|
||||
i,j,k : integer;
|
||||
P : TFPPackage;
|
||||
Repo: TFPRepository;
|
||||
begin
|
||||
SL.Clear;
|
||||
for i:=0 to GFPpkg.RepositoryList.Count-1 do
|
||||
begin
|
||||
Repo := TFPRepository(GFPpkg.RepositoryList[i]);
|
||||
if Repo.RepositoryType = fprtInstalled then
|
||||
begin
|
||||
for j := 0 to Repo.PackageCount-1 do
|
||||
begin
|
||||
P := Repo.Packages[j];
|
||||
if P.IsPackageBroken then
|
||||
SL.Add(P.Name)
|
||||
else
|
||||
begin
|
||||
// It could be that a package is broken in one repository,
|
||||
// but that this problem is 'fixed' in a repository with an higher
|
||||
// priority
|
||||
k := SL.IndexOf(P.Name);
|
||||
if k > -1 then
|
||||
SL.Delete(k);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Result:=(SL.Count>0);
|
||||
Result := GFPpkg.FindBrokenPackages(SL);
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user