mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-16 17:49:14 +02:00
IDE: test compiler options: use codetools fpc config cache, bug #17700
git-svn-id: trunk@30457 -
This commit is contained in:
parent
12f497705c
commit
0abcba4a03
@ -128,7 +128,7 @@ type
|
|||||||
procedure Remove(const Name: string);
|
procedure Remove(const Name: string);
|
||||||
property Strings[const s: string]: string read GetStrings write SetStrings; default;
|
property Strings[const s: string]: string read GetStrings write SetStrings; default;
|
||||||
property CaseSensitive: boolean read FCaseSensitive;
|
property CaseSensitive: boolean read FCaseSensitive;
|
||||||
property Tree: TAVLTree read FTree;
|
property Tree: TAVLTree read FTree; // tree of PStringToStringTreeItem
|
||||||
function AsText: string;
|
function AsText: string;
|
||||||
function Equals(OtherTree: TStringToStringTree): boolean; reintroduce;
|
function Equals(OtherTree: TStringToStringTree): boolean; reintroduce;
|
||||||
procedure Assign(Source: TStringToStringTree);
|
procedure Assign(Source: TStringToStringTree);
|
||||||
|
@ -702,6 +702,7 @@ type
|
|||||||
function Update(TestFilename: string; ExtraOptions: string = '';
|
function Update(TestFilename: string; ExtraOptions: string = '';
|
||||||
const OnProgress: TDefinePoolProgress = nil): boolean;
|
const OnProgress: TDefinePoolProgress = nil): boolean;
|
||||||
function FindRealCompilerInPath(aTargetCPU: string; ResolveLinks: boolean): string;
|
function FindRealCompilerInPath(aTargetCPU: string; ResolveLinks: boolean): string;
|
||||||
|
function GetUnitPaths: string;
|
||||||
function GetFPCVerNumbers(out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
|
function GetFPCVerNumbers(out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
|
||||||
function GetFPCVer: string;
|
function GetFPCVer: string;
|
||||||
function IndexOfUsedCfgFile: integer;
|
function IndexOfUsedCfgFile: integer;
|
||||||
@ -7723,6 +7724,13 @@ begin
|
|||||||
Result:=TryReadAllLinks(Result);
|
Result:=TryReadAllLinks(Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TFPCTargetConfigCache.GetUnitPaths: string;
|
||||||
|
begin
|
||||||
|
UnitPaths.Delimiter:=';';
|
||||||
|
UnitPaths.StrictDelimiter:=true;
|
||||||
|
Result:=UnitPaths.DelimitedText;
|
||||||
|
end;
|
||||||
|
|
||||||
function TFPCTargetConfigCache.GetFPCVerNumbers(out FPCVersion, FPCRelease,
|
function TFPCTargetConfigCache.GetFPCVerNumbers(out FPCVersion, FPCRelease,
|
||||||
FPCPatch: integer): boolean;
|
FPCPatch: integer): boolean;
|
||||||
var
|
var
|
||||||
|
@ -17,6 +17,11 @@
|
|||||||
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
* *
|
* *
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
|
|
||||||
|
Abstract:
|
||||||
|
This dialog is typically called by the 'Test' button on the compiler options
|
||||||
|
dialog.
|
||||||
|
A dialog testing for common misconfigurations in some compiler options.
|
||||||
}
|
}
|
||||||
unit CheckCompilerOpts;
|
unit CheckCompilerOpts;
|
||||||
|
|
||||||
@ -25,11 +30,12 @@ unit CheckCompilerOpts;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, LCLProc, Forms, Controls, Graphics, Dialogs,
|
Classes, SysUtils, LCLProc, Forms, Controls, Graphics, Dialogs, FileUtil,
|
||||||
FileUtil, Clipbrd, StdCtrls, Buttons, Process, AsyncProcess, Menus, ExtCtrls,
|
Clipbrd, StdCtrls, Buttons, Process, AVL_Tree, AsyncProcess, Menus, ExtCtrls,
|
||||||
UTF8Process, ButtonPanel,
|
UTF8Process, ButtonPanel,
|
||||||
// codetools
|
// codetools
|
||||||
KeywordFuncLists, CodeToolManager, FileProcs,
|
KeywordFuncLists, CodeToolManager, FileProcs, DefineTemplates,
|
||||||
|
CodeToolsStructs,
|
||||||
// IDEIntf
|
// IDEIntf
|
||||||
ProjectIntf, MacroIntf, IDEExternToolIntf,
|
ProjectIntf, MacroIntf, IDEExternToolIntf,
|
||||||
// IDE
|
// IDE
|
||||||
@ -69,24 +75,23 @@ type
|
|||||||
procedure ApplicationOnIdle(Sender: TObject; var Done: Boolean);
|
procedure ApplicationOnIdle(Sender: TObject; var Done: Boolean);
|
||||||
procedure CopyOutputMenuItemClick(Sender: TObject);
|
procedure CopyOutputMenuItemClick(Sender: TObject);
|
||||||
private
|
private
|
||||||
|
FIdleConnected: boolean;
|
||||||
FMacroList: TTransferMacroList;
|
FMacroList: TTransferMacroList;
|
||||||
FOptions: TCompilerOptions;
|
FOptions: TCompilerOptions;
|
||||||
FTest: TCompilerOptionsTest;
|
FTest: TCompilerOptionsTest;
|
||||||
FLastLineIsProgress: boolean;
|
FLastLineIsProgress: boolean;
|
||||||
FDirectories: TStringList;
|
FDirectories: TStringList;
|
||||||
|
procedure SetIdleConnected(const AValue: boolean);
|
||||||
procedure SetMacroList(const AValue: TTransferMacroList);
|
procedure SetMacroList(const AValue: TTransferMacroList);
|
||||||
procedure SetOptions(const AValue: TCompilerOptions);
|
procedure SetOptions(const AValue: TCompilerOptions);
|
||||||
procedure SetMsgDirectory(Index: integer; const CurDir: string);
|
procedure SetMsgDirectory(Index: integer; const CurDir: string);
|
||||||
function CheckSpecialCharsInPath(const Title, ExpandedPath: string): TModalResult;
|
function CheckSpecialCharsInPath(const Title, ExpandedPath: string): TModalResult;
|
||||||
function CheckNonExistsingSearchPaths(const Title, ExpandedPath: string): TModalResult;
|
function CheckNonExistingSearchPaths(const Title, ExpandedPath: string): TModalResult;
|
||||||
function CheckCompilerExecutable(const CompilerFilename: string): TModalResult;
|
function CheckCompilerExecutable(const CompilerFilename: string): TModalResult;
|
||||||
function CheckAmbiguousFPCCfg(const CompilerFilename: string): TModalResult;
|
function CheckCompilerConfig(CfgCache: TFPCTargetConfigCache): TModalResult;
|
||||||
function CheckCompilerConfig(const CompilerFilename: string;
|
function FindAllPPUFiles(const AnUnitPath: string): TStrings;
|
||||||
out FPCCfgUnitPath: string): TModalResult;
|
function CheckMissingFPCPPUs(CfgCache: TFPCTargetConfigCache): TModalResult;
|
||||||
function FindAllPPUFiles(const FPCCfgUnitPath: string): TStrings;
|
function CheckCompilerDate(CfgCache: TFPCTargetConfigCache): TModalResult;
|
||||||
function CheckMissingFPCPPUs(PPUs: TStrings): TModalResult;
|
|
||||||
function CheckCompilerDate(const CompilerFilename: string;
|
|
||||||
PPUs: TStrings): TModalResult;
|
|
||||||
function CheckForAmbiguousPPUs(SearchForPPUs: TStrings;
|
function CheckForAmbiguousPPUs(SearchForPPUs: TStrings;
|
||||||
SearchInPPUs: TStrings = nil): TModalResult;
|
SearchInPPUs: TStrings = nil): TModalResult;
|
||||||
function CheckFPCUnitPathsContainSources(const FPCCfgUnitPath: string
|
function CheckFPCUnitPathsContainSources(const FPCCfgUnitPath: string
|
||||||
@ -107,6 +112,7 @@ type
|
|||||||
procedure AddHint(const Msg: string);
|
procedure AddHint(const Msg: string);
|
||||||
procedure AddWarning(const Msg: string);
|
procedure AddWarning(const Msg: string);
|
||||||
procedure AddMsg(const Level: TCompilerCheckMsgLvl; const Msg: string);
|
procedure AddMsg(const Level: TCompilerCheckMsgLvl; const Msg: string);
|
||||||
|
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
|
||||||
public
|
public
|
||||||
property Options: TCompilerOptions read FOptions write SetOptions;
|
property Options: TCompilerOptions read FOptions write SetOptions;
|
||||||
property Test: TCompilerOptionsTest read FTest;
|
property Test: TCompilerOptionsTest read FTest;
|
||||||
@ -178,7 +184,7 @@ end;
|
|||||||
procedure TCheckCompilerOptsDlg.ApplicationOnIdle(Sender: TObject;
|
procedure TCheckCompilerOptsDlg.ApplicationOnIdle(Sender: TObject;
|
||||||
var Done: Boolean);
|
var Done: Boolean);
|
||||||
begin
|
begin
|
||||||
Application.RemoveOnIdleHandler(@ApplicationOnIdle);
|
IdleConnected:=false;
|
||||||
DoTestAll;
|
DoTestAll;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -237,7 +243,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckNonExistsingSearchPaths(const Title,
|
function TCheckCompilerOptsDlg.CheckNonExistingSearchPaths(const Title,
|
||||||
ExpandedPath: string): TModalResult;
|
ExpandedPath: string): TModalResult;
|
||||||
var
|
var
|
||||||
p: Integer;
|
p: Integer;
|
||||||
@ -293,71 +299,6 @@ begin
|
|||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckAmbiguousFPCCfg(
|
|
||||||
const CompilerFilename: string): TModalResult;
|
|
||||||
var
|
|
||||||
CfgFiles: TStringList;
|
|
||||||
Dir: String;
|
|
||||||
Filename: String;
|
|
||||||
i: Integer;
|
|
||||||
|
|
||||||
procedure AddFile(const aFilename: string);
|
|
||||||
begin
|
|
||||||
if (CfgFiles.IndexOf(aFilename)<0) and FileExistsUTF8(aFilename) then
|
|
||||||
CfgFiles.Add(aFilename);
|
|
||||||
end;
|
|
||||||
|
|
||||||
begin
|
|
||||||
FTest:=cotCheckAmbiguousFPCCfg;
|
|
||||||
TestGroupbox.Caption:=dlgCCOTestCheckingFPCConfigs;
|
|
||||||
|
|
||||||
CfgFiles:=TStringList.Create;
|
|
||||||
|
|
||||||
// check $HOME/.fpc.cfg
|
|
||||||
Dir:=GetEnvironmentVariableUTF8('HOME');
|
|
||||||
if Dir<>'' then begin
|
|
||||||
Filename:=CleanAndExpandDirectory(Dir)+'.fpc.cfg';
|
|
||||||
AddFile(Filename);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// check compiler path + fpc.cfg
|
|
||||||
Dir:=ExtractFilePath(CompilerFilename);
|
|
||||||
Dir:=ReadAllLinks(Dir,false);
|
|
||||||
if Dir<>'' then begin
|
|
||||||
Filename:=CleanAndExpandDirectory(Dir)+'fpc.cfg';
|
|
||||||
AddFile(Filename);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// check working directory + fpc.cfg
|
|
||||||
Dir:=ExtractFilePath(Options.BaseDirectory);
|
|
||||||
Dir:=ReadAllLinks(Dir,false);
|
|
||||||
if Dir<>'' then begin
|
|
||||||
Filename:=CleanAndExpandDirectory(Dir)+'fpc.cfg';
|
|
||||||
AddFile(Filename);
|
|
||||||
end;
|
|
||||||
|
|
||||||
// check /etc/fpc.cfg
|
|
||||||
{$IFDEF Unix}
|
|
||||||
Dir:=ExtractFilePath(CompilerFilename);
|
|
||||||
Dir:=GetEnvironmentVariableUTF8('HOME');
|
|
||||||
if Dir<>'' then begin
|
|
||||||
Filename:='/etc/fpc.cfg';
|
|
||||||
AddFile(Filename);
|
|
||||||
end;
|
|
||||||
{$ENDIF}
|
|
||||||
|
|
||||||
// warn about missing or too many fpc.cfg
|
|
||||||
if CfgFiles.Count<1 then begin
|
|
||||||
AddWarning(lisCCONoCfgFound);
|
|
||||||
end else if CfgFiles.Count>1 then begin
|
|
||||||
for i:=0 to CfgFiles.Count-1 do
|
|
||||||
AddWarning(lisCCOMultipleCfgFound+CfgFiles[i]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
CfgFiles.Free;
|
|
||||||
Result:=mrOk;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckCompileBogusFile(
|
function TCheckCompilerOptsDlg.CheckCompileBogusFile(
|
||||||
const CompilerFilename: string): TModalResult;
|
const CompilerFilename: string): TModalResult;
|
||||||
var
|
var
|
||||||
@ -475,151 +416,46 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckCompilerConfig(
|
function TCheckCompilerOptsDlg.CheckCompilerConfig(
|
||||||
const CompilerFilename: string; out FPCCfgUnitPath: string): TModalResult;
|
CfgCache: TFPCTargetConfigCache): TModalResult;
|
||||||
var
|
var
|
||||||
TestDir: String;
|
|
||||||
|
|
||||||
procedure ProcessOutputLine(const Line: string);
|
|
||||||
const
|
|
||||||
USING_UNIT_PATH = 'USING UNIT PATH: ';
|
|
||||||
READING_OPTIONS_FROM_FILE = 'READING OPTIONS FROM FILE ';
|
|
||||||
HANDLING_OPTION = 'HANDLING OPTION ';
|
|
||||||
var
|
|
||||||
len, curpos: integer;
|
|
||||||
NewPath: String;
|
|
||||||
UpLine: String;
|
|
||||||
begin
|
|
||||||
len := length(Line);
|
|
||||||
if len <= 6 then Exit; // shortest match
|
|
||||||
|
|
||||||
CurPos := 1;
|
|
||||||
// strip timestamp e.g. [0.306]
|
|
||||||
if Line[CurPos] = '[' then begin
|
|
||||||
repeat
|
|
||||||
inc(CurPos);
|
|
||||||
if CurPos > len then Exit;
|
|
||||||
until line[CurPos] = ']';
|
|
||||||
Inc(CurPos, 2); //skip space also
|
|
||||||
if len - CurPos < 6 then Exit; // shortest match
|
|
||||||
end;
|
|
||||||
|
|
||||||
UpLine:=UpperCaseStr(Line);
|
|
||||||
|
|
||||||
case UpLine[CurPos] of
|
|
||||||
'C':
|
|
||||||
if (StrLComp(@UpLine[CurPos], READING_OPTIONS_FROM_FILE,
|
|
||||||
length(READING_OPTIONS_FROM_FILE)) = 0) then
|
|
||||||
begin
|
|
||||||
// show a hint what cfg file is read by FPC
|
|
||||||
AddHint(Line);
|
|
||||||
end;
|
|
||||||
'U':
|
|
||||||
if (StrLComp(@UpLine[CurPos], USING_UNIT_PATH, length(USING_UNIT_PATH)) = 0)
|
|
||||||
then begin
|
|
||||||
Inc(CurPos, length(USING_UNIT_PATH));
|
|
||||||
NewPath:=copy(Line,CurPos,len);
|
|
||||||
if NewPath<>'' then begin
|
|
||||||
if not FilenameIsAbsolute(NewPath) then begin
|
|
||||||
AddWarning(Format(lisCCORelUnitPathFoundInCfg,[NewPath]));
|
|
||||||
NewPath:=ExpandFileNameUTF8(NewPath);
|
|
||||||
end;
|
|
||||||
NewPath:=AppendPathDelim(TrimFilename(NewPath));
|
|
||||||
if (CompareFilenames(NewPath,Options.BaseDirectory)<>0)
|
|
||||||
and (CompareFilenames(NewPath,TestDir)<>0)
|
|
||||||
then begin
|
|
||||||
//DebugLn(['TCheckCompilerOptsDlg.CheckCompilerConfig: Using unit path: "',NewPath,'"']);
|
|
||||||
FPCCfgUnitPath:=FPCCfgUnitPath+NewPath+';';
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
var
|
|
||||||
ATestPascalFile: String;
|
|
||||||
CurCompilerOptions: String;
|
|
||||||
TargetOS: String;
|
|
||||||
TargetCPU: String;
|
|
||||||
OutputLine: String;
|
|
||||||
TheProcess: TProcessUTF8;
|
|
||||||
OutLen: Integer;
|
|
||||||
LineStart: integer;
|
|
||||||
i: Integer;
|
i: Integer;
|
||||||
CmdLine: string;
|
CfgFile: TFPCConfigFileState;
|
||||||
Buf: string;
|
CfgCount: Integer;
|
||||||
begin
|
begin
|
||||||
FPCCfgUnitPath:='';
|
|
||||||
|
|
||||||
FTest:=cotCheckCompilerConfig;
|
FTest:=cotCheckCompilerConfig;
|
||||||
TestGroupbox.Caption:=dlgCCOTestCheckingCompilerConfig;
|
TestGroupbox.Caption:=dlgCCOTestCheckingCompilerConfig;
|
||||||
|
|
||||||
Result:=CheckAmbiguousFPCCfg(CompilerFilename);
|
CfgCount:=0;
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
for i:=0 to CfgCache.ConfigFiles.Count-1 do begin
|
||||||
|
CfgFile:=CfgCache.ConfigFiles[i];
|
||||||
TestDir:=AppendPathDelim(EnvironmentOptions.TestBuildDirectory);
|
if CfgFile.FileExists then inc(CfgCount);
|
||||||
ATestPascalFile:=CreateNonExistingFilename(TestDir+'testcompileroptions.pas');
|
|
||||||
|
|
||||||
CurCompilerOptions:='';
|
|
||||||
TargetOS:=Options.TargetOS;
|
|
||||||
if TargetOS<>'' then
|
|
||||||
CurCompilerOptions:=AddCmdLineParameter(CurCompilerOptions,'-T'+TargetOS);
|
|
||||||
TargetCPU:=Options.TargetCPU;
|
|
||||||
if TargetCPU<>'' then
|
|
||||||
CurCompilerOptions:=AddCmdLineParameter(CurCompilerOptions,'-P'+TargetCPU);
|
|
||||||
|
|
||||||
CmdLine:=CompilerFilename+' -va ';
|
|
||||||
|
|
||||||
// set english message file to be able to parse the fpc output
|
|
||||||
if FileExistsCached(CodeToolBoss.DefinePool.EnglishErrorMsgFilename) then
|
|
||||||
CmdLine:=CmdLine+'-Fr'+CodeToolBoss.DefinePool.EnglishErrorMsgFilename+' '
|
|
||||||
else
|
|
||||||
AddWarning(lisCCOEnglishMessageFileMissing);
|
|
||||||
|
|
||||||
if CurCompilerOptions<>'' then
|
|
||||||
CmdLine:=CmdLine+CurCompilerOptions+' ';
|
|
||||||
CmdLine:=CmdLine+ATestPascalFile;
|
|
||||||
|
|
||||||
TheProcess := TProcessUTF8.Create(nil);
|
|
||||||
TheProcess.CommandLine := CmdLine;
|
|
||||||
TheProcess.Options:= [poUsePipes, poStdErrToOutPut];
|
|
||||||
TheProcess.ShowWindow := swoHide;
|
|
||||||
TheProcess.CurrentDirectory:=Options.BaseDirectory;
|
|
||||||
//DebugLn(['TCheckCompilerOptsDlg.CheckCompilerConfig Options.BaseDirectory=',Options.BaseDirectory]);
|
|
||||||
try
|
|
||||||
TheProcess.Execute;
|
|
||||||
OutputLine:='';
|
|
||||||
SetLength(Buf,1024);
|
|
||||||
repeat
|
|
||||||
if (TheProcess.Output<>nil) then begin
|
|
||||||
OutLen:=TheProcess.Output.Read(Buf[1],length(Buf));
|
|
||||||
end else
|
|
||||||
OutLen:=0;
|
|
||||||
LineStart:=1;
|
|
||||||
i:=1;
|
|
||||||
while i<=OutLen do begin
|
|
||||||
if Buf[i] in [#10,#13] then begin
|
|
||||||
OutputLine:=OutputLine+copy(Buf,LineStart,i-LineStart);
|
|
||||||
ProcessOutputLine(OutputLine);
|
|
||||||
OutputLine:='';
|
|
||||||
if (i<OutLen) and (Buf[i+1] in [#10,#13]) and (Buf[i]<>Buf[i+1])
|
|
||||||
then
|
|
||||||
inc(i);
|
|
||||||
LineStart:=i+1;
|
|
||||||
end;
|
end;
|
||||||
inc(i);
|
if CfgCount<0 then begin
|
||||||
|
// missing config file => warning
|
||||||
|
AddWarning(lisCCONoCfgFound);
|
||||||
|
end else if CfgCount=1 then begin
|
||||||
|
// exactly one config, sounds good, but might still the be wrong one
|
||||||
|
// => hint
|
||||||
|
for i:=0 to CfgCache.ConfigFiles.Count-1 do begin
|
||||||
|
CfgFile:=CfgCache.ConfigFiles[i];
|
||||||
|
if CfgFile.FileExists then begin
|
||||||
|
AddHint('using config file '+CfgFile.Filename);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end else if CfgCount>1 then begin
|
||||||
|
// multiple config files => warning
|
||||||
|
for i:=0 to CfgCache.ConfigFiles.Count-1 do begin
|
||||||
|
CfgFile:=CfgCache.ConfigFiles[i];
|
||||||
|
if CfgFile.FileExists then
|
||||||
|
AddWarning(lisCCOMultipleCfgFound+CfgFile.Filename);
|
||||||
end;
|
end;
|
||||||
OutputLine:=copy(Buf,LineStart,OutLen-LineStart+1);
|
|
||||||
until OutLen=0;
|
|
||||||
TheProcess.WaitOnExit;
|
|
||||||
finally
|
|
||||||
TheProcess.Free;
|
|
||||||
end;
|
end;
|
||||||
FPCCfgUnitPath:=TrimSearchPath(FPCCfgUnitPath,'');
|
|
||||||
|
|
||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.FindAllPPUFiles(const FPCCfgUnitPath: string
|
function TCheckCompilerOptsDlg.FindAllPPUFiles(const AnUnitPath: string
|
||||||
): TStrings;
|
): TStrings;
|
||||||
var
|
var
|
||||||
Directory: String;
|
Directory: String;
|
||||||
@ -629,8 +465,8 @@ begin
|
|||||||
Result:=TStringList.Create;
|
Result:=TStringList.Create;
|
||||||
|
|
||||||
p:=1;
|
p:=1;
|
||||||
while p<=length(FPCCfgUnitPath) do begin
|
while p<=length(AnUnitPath) do begin
|
||||||
Directory:=TrimAndExpandDirectory(GetNextDirectoryInSearchPath(FPCCfgUnitPath,p));
|
Directory:=TrimAndExpandDirectory(GetNextDirectoryInSearchPath(AnUnitPath,p));
|
||||||
if Directory<>'' then begin
|
if Directory<>'' then begin
|
||||||
if FindFirstUTF8(Directory+GetAllFilesMask,faAnyFile,FileInfo)=0
|
if FindFirstUTF8(Directory+GetAllFilesMask,faAnyFile,FileInfo)=0
|
||||||
then begin
|
then begin
|
||||||
@ -649,17 +485,14 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckMissingFPCPPUs(PPUs: TStrings
|
function TCheckCompilerOptsDlg.CheckMissingFPCPPUs(
|
||||||
): TModalResult;
|
CfgCache: TFPCTargetConfigCache): TModalResult;
|
||||||
|
|
||||||
function Check(const TheUnitname: string; Severity: TCompilerCheckMsgLvl
|
function Check(const TheUnitname: string; Severity: TCompilerCheckMsgLvl
|
||||||
): Boolean;
|
): Boolean;
|
||||||
var
|
|
||||||
i: Integer;
|
|
||||||
begin
|
begin
|
||||||
for i:=0 to PPUs.Count-1 do begin
|
if (CfgCache.Units<>nil)
|
||||||
if ExtractFileNameOnly(PPUs[i])=TheUnitname then exit(true);
|
and (CfgCache.Units.Contains(TheUnitname)) then exit(true);
|
||||||
end;
|
|
||||||
AddMsg(Severity,Format(lisCCOMsgPPUNotFound,[TheUnitname]));
|
AddMsg(Severity,Format(lisCCOMsgPPUNotFound,[TheUnitname]));
|
||||||
Result:=ord(Severity)>=ord(ccmlError);
|
Result:=ord(Severity)>=ord(ccmlError);
|
||||||
if not Result then begin
|
if not Result then begin
|
||||||
@ -686,15 +519,16 @@ begin
|
|||||||
Result:=mrOk;
|
Result:=mrOk;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.CheckCompilerDate(
|
function TCheckCompilerOptsDlg.CheckCompilerDate(CfgCache: TFPCTargetConfigCache
|
||||||
const CompilerFilename: string; PPUs: TStrings): TModalResult;
|
): TModalResult;
|
||||||
var
|
var
|
||||||
MinPPUDate: LongInt;
|
MinPPUDate: LongInt;
|
||||||
MaxPPUDate: LongInt;
|
MaxPPUDate: LongInt;
|
||||||
CompilerDate: LongInt;
|
CompilerDate: LongInt;
|
||||||
MinPPU: String;
|
MinPPU: String;
|
||||||
MaxPPU: String;
|
MaxPPU: String;
|
||||||
i: Integer;
|
Node: TAVLTreeNode;
|
||||||
|
Item: PStringToStringTreeItem;
|
||||||
|
|
||||||
procedure CheckFileAge(const aFilename: string);
|
procedure CheckFileAge(const aFilename: string);
|
||||||
var
|
var
|
||||||
@ -715,31 +549,25 @@ var
|
|||||||
|
|
||||||
procedure CheckFileAgeOfUnit(const aUnitName: string);
|
procedure CheckFileAgeOfUnit(const aUnitName: string);
|
||||||
var
|
var
|
||||||
i: Integer;
|
Filename: string;
|
||||||
begin
|
begin
|
||||||
for i:=0 to PPUs.Count-1 do
|
Filename:=CfgCache.Units[aUnitName];
|
||||||
if ExtractFileNameOnly(PPUs[i])=aUnitName then begin
|
if Filename='' then exit;
|
||||||
CheckFileAge(PPUs[i]);
|
CheckFileAge(Filename);
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
//DebugLn(['CheckFileAgeOfUnit Unit not found: ',aUnitName]);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
if CfgCache.Units=nil then exit(mrOK);
|
||||||
|
|
||||||
FTest:=cotCheckCompilerDate;
|
FTest:=cotCheckCompilerDate;
|
||||||
TestGroupbox.Caption:=dlgCCOTestCompilerDate;
|
TestGroupbox.Caption:=dlgCCOTestCompilerDate;
|
||||||
|
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
|
|
||||||
CompilerDate:=FileAgeCached(CompilerFilename);
|
CompilerDate:=CfgCache.CompilerDate;
|
||||||
if CompilerDate=-1 then begin
|
|
||||||
Result:=MessageDlg(lisCCOErrorCaption,Format(lisCCOUnableToGetFileDate,[CompilerFilename]),
|
|
||||||
mtError,[mbIgnore,mbAbort],0);
|
|
||||||
exit;
|
|
||||||
end;
|
|
||||||
|
|
||||||
// first check some rtl and fcl units
|
// first check some rtl and fcl units
|
||||||
// They are normally installed in one step, so there dates should be nearly
|
// They are normally installed in one step, so the dates should be nearly
|
||||||
// the same. If not, then probably two different installations are mixed up.
|
// the same. If not, then probably two different installations are mixed up.
|
||||||
MinPPUDate:=-1;
|
MinPPUDate:=-1;
|
||||||
MinPPU:='';
|
MinPPU:='';
|
||||||
@ -769,8 +597,13 @@ begin
|
|||||||
// if a .ppu is much older than the compiler itself, then the ppu is probably
|
// if a .ppu is much older than the compiler itself, then the ppu is probably
|
||||||
// a) a leftover from a installation
|
// a) a leftover from a installation
|
||||||
// b) not updated
|
// b) not updated
|
||||||
for i:=0 to PPUs.Count-1 do
|
Node:=CfgCache.Units.Tree.FindLowest;
|
||||||
CheckFileAge(PPUs[i]);
|
while Node<>nil do begin
|
||||||
|
Item:=PStringToStringTreeItem(Node.Data);
|
||||||
|
if Item^.Value<>'' then
|
||||||
|
CheckFileAge(Item^.Value);
|
||||||
|
Node:=CfgCache.Units.Tree.FindSuccessor(Node);
|
||||||
|
end;
|
||||||
|
|
||||||
if MinPPU<>'' then begin
|
if MinPPU<>'' then begin
|
||||||
if CompilerDate-MinPPUDate>300 then begin
|
if CompilerDate-MinPPUDate>300 then begin
|
||||||
@ -993,24 +826,37 @@ begin
|
|||||||
FMacroList:=AValue;
|
FMacroList:=AValue;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TCheckCompilerOptsDlg.SetIdleConnected(const AValue: boolean);
|
||||||
|
begin
|
||||||
|
if FIdleConnected=AValue then exit;
|
||||||
|
FIdleConnected:=AValue;
|
||||||
|
if FIdleConnected then
|
||||||
|
Application.AddOnIdleHandler(@ApplicationOnIdle)
|
||||||
|
else
|
||||||
|
Application.RemoveOnIdleHandler(@ApplicationOnIdle);
|
||||||
|
end;
|
||||||
|
|
||||||
function TCheckCompilerOptsDlg.DoTestAll: TModalResult;
|
function TCheckCompilerOptsDlg.DoTestAll: TModalResult;
|
||||||
var
|
var
|
||||||
CompilerFilename: String;
|
CompilerFilename: String;
|
||||||
CompileTool: TExternalToolOptions;
|
CompileTool: TExternalToolOptions;
|
||||||
CompilerFiles: TStrings;
|
CompilerFiles: TStrings;
|
||||||
FPCCfgUnitPath: string;
|
FPCCfgUnitPath: string;
|
||||||
FPC_PPUs: TStrings;
|
|
||||||
TargetUnitPath: String;
|
TargetUnitPath: String;
|
||||||
Target_PPUs: TStrings;
|
Target_PPUs: TStrings;
|
||||||
cp: TParsedCompilerOptString;
|
cp: TParsedCompilerOptString;
|
||||||
|
TargetCPU: String;
|
||||||
|
TargetOS: String;
|
||||||
|
CfgCache: TFPCTargetConfigCache;
|
||||||
|
FPC_PPUs: TStrings;
|
||||||
begin
|
begin
|
||||||
Result:=mrCancel;
|
Result:=mrCancel;
|
||||||
if Test<>cotNone then exit;
|
if Test<>cotNone then exit;
|
||||||
CompileTool:=nil;
|
CompileTool:=nil;
|
||||||
TestMemo.Lines.Clear;
|
TestMemo.Lines.Clear;
|
||||||
CompilerFiles:=nil;
|
CompilerFiles:=nil;
|
||||||
FPC_PPUs:=nil;
|
|
||||||
Target_PPUs:=nil;
|
Target_PPUs:=nil;
|
||||||
|
FPC_PPUs:=nil;
|
||||||
try
|
try
|
||||||
// do not confuse the user with cached data
|
// do not confuse the user with cached data
|
||||||
InvalidateFileStateCache();
|
InvalidateFileStateCache();
|
||||||
@ -1027,13 +873,13 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
// check for non existing paths
|
// check for non existing paths
|
||||||
CheckNonExistsingSearchPaths('include search path',
|
CheckNonExistingSearchPaths('include search path',
|
||||||
Options.GetIncludePath(false));
|
Options.GetIncludePath(false));
|
||||||
CheckNonExistsingSearchPaths('library search path',
|
CheckNonExistingSearchPaths('library search path',
|
||||||
Options.GetLibraryPath(false));
|
Options.GetLibraryPath(false));
|
||||||
CheckNonExistsingSearchPaths('unit search path',
|
CheckNonExistingSearchPaths('unit search path',
|
||||||
Options.GetUnitPath(false));
|
Options.GetUnitPath(false));
|
||||||
CheckNonExistsingSearchPaths('source search path',
|
CheckNonExistingSearchPaths('source search path',
|
||||||
Options.GetSrcPath(false));
|
Options.GetSrcPath(false));
|
||||||
|
|
||||||
// fetch compiler filename
|
// fetch compiler filename
|
||||||
@ -1043,21 +889,26 @@ begin
|
|||||||
Result:=CheckCompilerExecutable(CompilerFilename);
|
Result:=CheckCompilerExecutable(CompilerFilename);
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
||||||
|
|
||||||
|
TargetOS:=Options.TargetOS;
|
||||||
|
TargetCPU:=Options.TargetCPU;
|
||||||
|
CfgCache:=CodeToolBoss.FPCDefinesCache.ConfigCaches.Find(CompilerFilename,
|
||||||
|
'',TargetOS,TargetCPU,true);
|
||||||
|
|
||||||
// check compiler config
|
// check compiler config
|
||||||
Result:=CheckCompilerConfig(CompilerFilename,FPCCfgUnitPath);
|
Result:=CheckCompilerConfig(CfgCache);
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
||||||
|
|
||||||
FPC_PPUs:=FindAllPPUFiles(FPCCfgUnitPath);
|
|
||||||
|
|
||||||
// check if compiler paths include base units
|
// check if compiler paths include base units
|
||||||
Result:=CheckMissingFPCPPUs(FPC_PPUs);
|
Result:=CheckMissingFPCPPUs(CfgCache);
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
||||||
|
|
||||||
// check if compiler is older than fpc ppu
|
// check if compiler is older than fpc ppu
|
||||||
Result:=CheckCompilerDate(CompilerFilename,FPC_PPUs);
|
Result:=CheckCompilerDate(CfgCache);
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
||||||
|
|
||||||
// check if there are ambiguous fpc ppu
|
// check if there are ambiguous fpc ppu
|
||||||
|
FPCCfgUnitPath:=CfgCache.GetUnitPaths;
|
||||||
|
FPC_PPUs:=FindAllPPUFiles(FPCCfgUnitPath);
|
||||||
Result:=CheckForAmbiguousPPUs(FPC_PPUs);
|
Result:=CheckForAmbiguousPPUs(FPC_PPUs);
|
||||||
if not (Result in [mrOk,mrIgnore]) then exit;
|
if not (Result in [mrOk,mrIgnore]) then exit;
|
||||||
|
|
||||||
@ -1114,7 +965,7 @@ end;
|
|||||||
constructor TCheckCompilerOptsDlg.Create(TheOwner: TComponent);
|
constructor TCheckCompilerOptsDlg.Create(TheOwner: TComponent);
|
||||||
begin
|
begin
|
||||||
inherited Create(TheOwner);
|
inherited Create(TheOwner);
|
||||||
Application.AddOnIdleHandler(@ApplicationOnIdle,true);
|
IdleConnected:=true;
|
||||||
Caption:=dlgCCOCaption;
|
Caption:=dlgCCOCaption;
|
||||||
TestGroupbox.Caption:=dlgCCOTest;
|
TestGroupbox.Caption:=dlgCCOTest;
|
||||||
OutputGroupBox.Caption:=dlgCCOResults;
|
OutputGroupBox.Caption:=dlgCCOResults;
|
||||||
@ -1123,7 +974,7 @@ end;
|
|||||||
|
|
||||||
destructor TCheckCompilerOptsDlg.Destroy;
|
destructor TCheckCompilerOptsDlg.Destroy;
|
||||||
begin
|
begin
|
||||||
Application.RemoveOnIdleHandler(@ApplicationOnIdle);
|
IdleConnected:=false;;
|
||||||
FDirectories.Free;
|
FDirectories.Free;
|
||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user