IDE: added warning when auto compile package has dependencies and output dir is in default fpc unit path

git-svn-id: trunk@31109 -
This commit is contained in:
mattias 2011-06-05 23:34:31 +00:00
parent 7ca74f8ce1
commit 23176970f9
4 changed files with 109 additions and 1 deletions

View File

@ -303,8 +303,9 @@ type
function FindUnitInUnitSet(const Directory, AUnitName: string): string;
function GetUnitSetIDForDirectory(const Directory: string;
UseCache: boolean = true): string;
function GetUnitSetForDirectory(const Directory: string): TFPCUnitSetCache;
function GetFPCUnitPathForDirectory(const Directory: string;
UseCache: boolean = true): string;// unit paths reported by FPC
UseCache: boolean = true): string;// value of macro #FPCUnitPath
procedure GetFPCVersionForDirectory(const Directory: string;
out FPCVersion, FPCRelease, FPCPatch: integer);
@ -1509,6 +1510,20 @@ begin
end;
end;
function TCodeToolManager.GetUnitSetForDirectory(const Directory: string
): TFPCUnitSetCache;
var
ID: String;
Changed: boolean;
begin
Result:=nil;
ID:=GetUnitSetIDForDirectory(Directory,true);
if ID='' then exit;
Changed:=false;
Result:=FPCDefinesCache.FindUnitSetWithID(ID,Changed,false);
if Changed then Result:=nil;
end;
function TCodeToolManager.GetFPCUnitPathForDirectory(const Directory: string;
UseCache: boolean): string;
var

View File

@ -3572,6 +3572,13 @@ resourcestring
lisPkgMangARequiredPackagesWasNotFound = 'A required packages was not '
+'found. See package graph.';
lisPkgMangCircleInPackageDependencies = 'Circle in package dependencies';
lisPkgMangThePackageIsCompiledAutomaticallyAndItsOutputDirec = 'The package '
+'%s is compiled automatically and its output directory is "%s", which is '
+'in the default unit search path of the compiler. The package uses other '
+'packages which also uses the default unit search of the compiler. This '
+'creates a circle.%sYou can fix this issue%sby removing the path from '
+'your compiler config (e.g. fpc.cfg)%sor by disabling the auto update of '
+'this package%sor by removing dependencies.';
lisPkgMangThereIsACircleInTheRequiredPackages = 'There is a circle in the '
+'required packages. See package graph.';
lisPkgMangThereAreTwoUnitsWithTheSameName1From2From = 'There are two units '

View File

@ -201,6 +201,8 @@ type
FirstDependency: TPkgDependency): TFPList;
function FindCircleDependencyPath(APackage: TLazPackage;
FirstDependency: TPkgDependency): TFPList;
function FindPkgOutputInFPCSearchPath(APackage: TLazPackage;
FirstDependency: TPkgDependency): TFPList; // find a package with auto compile and output dir is in FPC default search path
function FindUnsavedDependencyPath(APackage: TLazPackage;
FirstDependency: TPkgDependency): TFPList;
function FindNotInstalledRegisterUnits(APackage: TLazPackage;
@ -2500,6 +2502,77 @@ begin
Result.Insert(0,APackage);
end;
function TLazPackageGraph.FindPkgOutputInFPCSearchPath(APackage: TLazPackage;
FirstDependency: TPkgDependency): TFPList;
var
CfgCache: TFPCTargetConfigCache;
function CheckPkg(Pkg: TLazPackage; var PathList: TFPList): boolean;
var
OutputDir: String;
i: Integer;
Dir: String;
begin
Result:=true;
if (Pkg=nil) then exit;
Pkg.Flags:=Pkg.Flags+[lpfVisited];
if (Pkg.FirstRequiredDependency=nil)
or Pkg.IsVirtual or (Pkg.AutoUpdate<>pupAsNeeded) then exit;
// this package is compiled automatically and has dependencies
OutputDir:=ChompPathDelim(Pkg.GetOutputDirectory);
if OutputDir='' then exit;
for i:=0 to CfgCache.UnitPaths.Count-1 do begin
Dir:=ChompPathDelim(CfgCache.UnitPaths[i]);
if CompareFilenames(Dir,OutputDir)=0 then begin
// this package changes the units in the default FPC search path
// => a circle, because the dependencies use FPC search path too
Result:=false;
PathList:=TFPList.Create;
PathList.Add(Pkg);
exit;
end;
end;
end;
procedure CheckDependencyList(Dependency: TPkgDependency; var PathList: TFPList);
var
RequiredPackage: TLazPackage;
begin
while Dependency<>nil do begin
if Dependency.LoadPackageResult=lprSuccess then begin
RequiredPackage:=Dependency.RequiredPackage;
if not (lpfVisited in RequiredPackage.Flags) then begin
if CheckPkg(RequiredPackage,PathList) then exit;
CheckDependencyList(RequiredPackage.FirstRequiredDependency,PathList);
if PathList<>nil then begin
// circle detected
// -> add current package to list
PathList.Insert(0,RequiredPackage);
exit;
end;
end;
end;
Dependency:=Dependency.NextRequiresDependency;
end;
end;
var
UnitSet: TFPCUnitSetCache;
begin
Result:=nil;
MarkAllPackagesAsNotVisited;
UnitSet:=CodeToolBoss.GetUnitSetForDirectory('');
if UnitSet=nil then exit;
CfgCache:=UnitSet.GetConfigCache(false);
if (CfgCache=nil) or (CfgCache.UnitPaths=nil) then exit;
if APackage<>nil then begin
if not CheckPkg(APackage,Result) then exit;
if FirstDependency=nil then
FirstDependency:=APackage.FirstRequiredDependency;
end;
CheckDependencyList(FirstDependency,Result);
end;
function TLazPackageGraph.FindUnsavedDependencyPath(APackage: TLazPackage;
FirstDependency: TPkgDependency): TFPList;

View File

@ -1243,6 +1243,19 @@ begin
exit;
end;
// check for a package that compiles to the default FPC search path
PathList:=PackageGraph.FindPkgOutputInFPCSearchPath(APackage,FirstDependency);
if PathList<>nil then begin
ConflictPkg:=TObject(PathList[PathList.Count-1]) as TLazPackage;
DoShowPackageGraphPathList(PathList);
Result:=IDEMessageDialogAb(lisPkgMangCircleInPackageDependencies,
Format(lisPkgMangThePackageIsCompiledAutomaticallyAndItsOutputDirec, [
ConflictPkg.Name, ConflictPkg.GetOutputDirectory, #13#13, #13, #13,
#13]),
mtError,[mbCancel],ShowAbort);
exit;
end;
// check for ambiguous units between packages
if PackageGraph.FindAmbiguousUnits(APackage,FirstDependency,
PkgFile1,PkgFile2,ConflictPkg)