IDE: started setup for fpc src

git-svn-id: trunk@29904 -
This commit is contained in:
mattias 2011-03-19 10:28:38 +00:00
parent ac3743630d
commit c2071ea3cb
5 changed files with 369 additions and 159 deletions

View File

@ -701,7 +701,9 @@ 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 GetFPCVer(out FPCVersion, FPCRelease, FPCPatch: integer): boolean; function GetFPCVerNumbers(out FPCVersion, FPCRelease, FPCPatch: integer): boolean;
function GetFPCVer: string;
function IndexOfUsedCfgFile: integer;
procedure IncreaseChangeStamp; procedure IncreaseChangeStamp;
property ChangeStamp: integer read FChangeStamp; property ChangeStamp: integer read FChangeStamp;
end; end;
@ -7663,17 +7665,15 @@ begin
end else end else
debugln(['TFPCTargetConfigCache.Update WARNING: compiler is broken: '+Compiler+' '+ExtraOptions]); debugln(['TFPCTargetConfigCache.Update WARNING: compiler is broken: '+Compiler+' '+ExtraOptions]);
// store the list of tried and read cfg files // store the list of tried and read cfg files
if CfgFiles<>nil then begin for i:=0 to CfgFiles.Count-1 do begin
for i:=0 to CfgFiles.Count-1 do begin Filename:=CfgFiles[i];
Filename:=CfgFiles[i]; if Filename='' then continue;
if Filename='' then continue; CfgFileExists:=Filename[1]='+';
CfgFileExists:=Filename[1]='+'; Filename:=copy(Filename,2,length(Filename));
Filename:=copy(Filename,2,length(Filename)); CfgFileDate:=0;
CfgFileDate:=0; if CfgFileExists then
if CfgFileExists then CfgFileDate:=FileAgeCached(Filename);
CfgFileDate:=FileAgeCached(Filename); ConfigFiles.Add(Filename,CfgFileExists,CfgFileDate);
ConfigFiles.Add(Filename,CfgFileExists,CfgFileDate);
end;
end; end;
// gather all units in all unit search paths // gather all units in all unit search paths
if (UnitPaths<>nil) and (UnitPaths.Count>0) then if (UnitPaths<>nil) and (UnitPaths.Count>0) then
@ -7722,7 +7722,7 @@ begin
Result:=TryReadAllLinks(Result); Result:=TryReadAllLinks(Result);
end; end;
function TFPCTargetConfigCache.GetFPCVer(out FPCVersion, FPCRelease, function TFPCTargetConfigCache.GetFPCVerNumbers(out FPCVersion, FPCRelease,
FPCPatch: integer): boolean; FPCPatch: integer): boolean;
var var
v: string; v: string;
@ -7736,6 +7736,27 @@ begin
end; end;
end; end;
function TFPCTargetConfigCache.GetFPCVer: string;
var
FPCVersion: integer;
FPCRelease: integer;
FPCPatch: integer;
begin
if GetFPCVerNumbers(FPCVersion,FPCRelease,FPCPatch) then
Result:=IntToStr(FPCVersion)+'.'+IntToStr(FPCRelease)+'.'+IntToStr(FPCPatch)
else
Result:='';
end;
function TFPCTargetConfigCache.IndexOfUsedCfgFile: integer;
begin
if ConfigFiles=nil then exit(-1);
Result:=0;
while (Result<ConfigFiles.Count) and (not ConfigFiles[Result].FileExists) do
inc(Result);
if Result=ConfigFiles.Count then Result:=-1;
end;
{ TFPCTargetConfigCaches } { TFPCTargetConfigCaches }
constructor TFPCTargetConfigCaches.Create(AOwner: TComponent); constructor TFPCTargetConfigCaches.Create(AOwner: TComponent);

View File

@ -285,39 +285,39 @@ begin
GlobalMacroList.Add(TTransferMacro.Create('Project','', GlobalMacroList.Add(TTransferMacro.Create('Project','',
lisProjectMacroProperties,@MacroFuncProject,[])); lisProjectMacroProperties,@MacroFuncProject,[]));
GlobalMacroList.Add(TTransferMacro.Create('LCLWidgetType','', GlobalMacroList.Add(TTransferMacro.Create('LCLWidgetType','',
lisLCLWidgetType,@MacroFuncLCLWidgetType,[])); lisLCLWidgetType,@MacroFuncLCLWidgetType,[]));
GlobalMacroList.Add(TTransferMacro.Create('TargetCPU','', GlobalMacroList.Add(TTransferMacro.Create('TargetCPU','',
lisTargetCPU,@MacroFuncTargetCPU,[])); lisTargetCPU,@MacroFuncTargetCPU,[]));
GlobalMacroList.Add(TTransferMacro.Create('TargetOS','', GlobalMacroList.Add(TTransferMacro.Create('TargetOS','',
lisTargetOS,@MacroFuncTargetOS,[])); lisTargetOS,@MacroFuncTargetOS,[]));
GlobalMacroList.Add(TTransferMacro.Create('SrcOS','', GlobalMacroList.Add(TTransferMacro.Create('SrcOS','',
lisSrcOS,@MacroFuncSrcOS,[])); lisSrcOS,@MacroFuncSrcOS,[]));
GlobalMacroList.Add(TTransferMacro.Create('FPCVer','', GlobalMacroList.Add(TTransferMacro.Create('FPCVer','',
lisFPCVersionEG222, @MacroFuncFPCVer, [])); lisFPCVersionEG222, @MacroFuncFPCVer, []));
GlobalMacroList.Add(TTransferMacro.Create('Params','', GlobalMacroList.Add(TTransferMacro.Create('Params','',
lisCommandLineParamsOfProgram,@MacroFuncParams,[])); lisCommandLineParamsOfProgram,@MacroFuncParams,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjFile','', GlobalMacroList.Add(TTransferMacro.Create('ProjFile','',
lisProjectFilename,@MacroFuncProjFile,[])); lisProjectFilename,@MacroFuncProjFile,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjPath','', GlobalMacroList.Add(TTransferMacro.Create('ProjPath','',
lisProjectDirectory,@MacroFuncProjPath,[])); lisProjectDirectory,@MacroFuncProjPath,[]));
GlobalMacroList.Add(TTransferMacro.Create('TargetFile','', GlobalMacroList.Add(TTransferMacro.Create('TargetFile','',
lisTargetFilenameOfProject,@MacroFuncTargetFile,[])); lisTargetFilenameOfProject,@MacroFuncTargetFile,[]));
GlobalMacroList.Add(TTransferMacro.Create('TargetCmdLine','', GlobalMacroList.Add(TTransferMacro.Create('TargetCmdLine','',
lisTargetFilenamePlusParams,@MacroFuncTargetCmdLine,[])); lisTargetFilenamePlusParams,@MacroFuncTargetCmdLine,[]));
GlobalMacroList.Add(TTransferMacro.Create('RunCmdLine','', GlobalMacroList.Add(TTransferMacro.Create('RunCmdLine','',
lisLaunchingCmdLine,@MacroFuncRunCmdLine,[])); lisLaunchingCmdLine,@MacroFuncRunCmdLine,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjPublishDir','', GlobalMacroList.Add(TTransferMacro.Create('ProjPublishDir','',
lisPublishProjDir,@MacroFuncProjPublishDir,[])); lisPublishProjDir,@MacroFuncProjPublishDir,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjUnitPath','', GlobalMacroList.Add(TTransferMacro.Create('ProjUnitPath','',
lisProjectUnitPath,@MacroFuncProjUnitPath,[])); lisProjectUnitPath,@MacroFuncProjUnitPath,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjIncPath','', GlobalMacroList.Add(TTransferMacro.Create('ProjIncPath','',
lisProjectIncPath,@MacroFuncProjIncPath,[])); lisProjectIncPath,@MacroFuncProjIncPath,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjSrcPath','', GlobalMacroList.Add(TTransferMacro.Create('ProjSrcPath','',
lisProjectSrcPath,@MacroFuncProjSrcPath,[])); lisProjectSrcPath,@MacroFuncProjSrcPath,[]));
GlobalMacroList.Add(TTransferMacro.Create('ProjOutDir','', GlobalMacroList.Add(TTransferMacro.Create('ProjOutDir','',
lisProjectOutDir,@MacroFuncProjOutDir,[])); lisProjectOutDir,@MacroFuncProjOutDir,[]));
GlobalMacroList.Add(TTransferMacro.Create('Env','', GlobalMacroList.Add(TTransferMacro.Create('Env','',
lisEnvironmentVariableNameAsParameter, @MacroFuncEnv, [])); lisEnvironmentVariableNameAsParameter, @MacroFuncEnv, []));
GlobalMacroList.Add(TTransferMacro.Create('MakeExe','', GlobalMacroList.Add(TTransferMacro.Create('MakeExe','',
lisMakeExe,@MacroFuncMakeExe,[])); lisMakeExe,@MacroFuncMakeExe,[]));
GlobalMacroList.Add(TTransferMacro.Create('MakeLib','', GlobalMacroList.Add(TTransferMacro.Create('MakeLib','',
@ -325,13 +325,13 @@ begin
GlobalMacroList.Add(TTransferMacro.Create('Make','', GlobalMacroList.Add(TTransferMacro.Create('Make','',
lisPathOfTheMakeUtility, @MacroFuncMake, [])); lisPathOfTheMakeUtility, @MacroFuncMake, []));
GlobalMacroList.Add(TTransferMacro.Create('IDEBuildOptions','', GlobalMacroList.Add(TTransferMacro.Create('IDEBuildOptions','',
lisIDEBuildOptions, @MacroFuncIDEBuildOptions, [])); lisIDEBuildOptions, @MacroFuncIDEBuildOptions, []));
GlobalMacroList.Add(TTransferMacro.Create('PrimaryConfiPath','', GlobalMacroList.Add(TTransferMacro.Create('PrimaryConfiPath','',
lisPrimaryConfigPath, @MacroFuncPrimaryConfigPath, [])); lisPrimaryConfigPath, @MacroFuncPrimaryConfigPath, []));
GlobalMacroList.Add(TTransferMacro.Create('SecondaryConfigPath','', GlobalMacroList.Add(TTransferMacro.Create('SecondaryConfigPath','',
lisSecondaryConfigPath, @MacroFuncSecondaryConfigPath, [])); lisSecondaryConfigPath, @MacroFuncSecondaryConfigPath, []));
GlobalMacroList.Add(TTransferMacro.Create('FallbackOutputRoot','', GlobalMacroList.Add(TTransferMacro.Create('FallbackOutputRoot','',
lisSecondaryConfigPath, @MacroFuncFallbackOutputRoot, [])); lisSecondaryConfigPath, @MacroFuncFallbackOutputRoot, []));
// codetools macro functions // codetools macro functions
CodeToolBoss.DefineTree.MacroFunctions.AddExtended( CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
@ -1507,8 +1507,7 @@ function TBuildManager.MacroFuncFPCVer(const Param: string; const Data: PtrInt;
then then
exit; exit;
end; end;
ConfigCache.GetFPCVer(FPCVersion,FPCRelease,FPCPatch); Result:=ConfigCache.GetFPCVer;
Result:=IntToStr(FPCVersion)+'.'+IntToStr(FPCRelease)+'.'+IntToStr(FPCPatch);
end; end;
end; end;

View File

@ -57,29 +57,6 @@ object InitialSetupDialog: TInitialSetupDialog
ClientHeight = 27 ClientHeight = 27
ClientWidth = 600 ClientWidth = 600
TabOrder = 2 TabOrder = 2
object PrevIssueBitBtn: TBitBtn
Left = 0
Height = 27
Top = 0
Width = 127
Align = alLeft
AutoSize = True
Caption = 'PrevIssueBitBtn'
Constraints.MinWidth = 100
TabOrder = 0
end
object NextIssueBitBtn: TBitBtn
Left = 133
Height = 27
Top = 0
Width = 130
Align = alLeft
AutoSize = True
BorderSpacing.Left = 6
Caption = 'NextIssueBitBtn'
Constraints.MinWidth = 100
TabOrder = 1
end
object StartIDEBitBtn: TBitBtn object StartIDEBitBtn: TBitBtn
Left = 480 Left = 480
Height = 27 Height = 27
@ -89,7 +66,7 @@ object InitialSetupDialog: TInitialSetupDialog
AutoSize = True AutoSize = True
Caption = 'StartIDEBitBtn' Caption = 'StartIDEBitBtn'
Constraints.MinWidth = 100 Constraints.MinWidth = 100
TabOrder = 2 TabOrder = 0
end end
end end
object PropertiesPageControl: TPageControl object PropertiesPageControl: TPageControl
@ -158,6 +135,7 @@ object InitialSetupDialog: TInitialSetupDialog
'LazDirMemo' 'LazDirMemo'
'' ''
'' ''
''
) )
ReadOnly = True ReadOnly = True
TabOrder = 1 TabOrder = 1
@ -240,6 +218,7 @@ object InitialSetupDialog: TInitialSetupDialog
Lines.Strings = ( Lines.Strings = (
'CompilerMemo' 'CompilerMemo'
'' ''
''
) )
TabOrder = 2 TabOrder = 2
end end
@ -298,39 +277,11 @@ object InitialSetupDialog: TInitialSetupDialog
Lines.Strings = ( Lines.Strings = (
'FPCSrcDirMemo' 'FPCSrcDirMemo'
'' ''
''
) )
TabOrder = 2 TabOrder = 2
end end
end end
object LanguageTabSheet: TTabSheet
Caption = 'LanguageTabSheet'
ChildSizing.LeftRightSpacing = 6
ChildSizing.TopBottomSpacing = 6
ChildSizing.HorizontalSpacing = 6
ChildSizing.VerticalSpacing = 6
ClientHeight = 251
ClientWidth = 440
object LangLabel: TLabel
Left = 6
Height = 18
Top = 6
Width = 428
Align = alTop
Caption = 'LangLabel'
ParentColor = False
WordWrap = True
end
object LangComboBox: TComboBox
Left = 6
Height = 27
Top = 30
Width = 428
Align = alTop
ItemHeight = 0
TabOrder = 0
Text = 'LangComboBox'
end
end
end end
object WelcomePaintBox: TPaintBox object WelcomePaintBox: TPaintBox
Left = 0 Left = 0

View File

@ -41,14 +41,18 @@ interface
uses uses
Classes, SysUtils, contnrs, LCLProc, Forms, Controls, Buttons, Dialogs, Classes, SysUtils, contnrs, LCLProc, Forms, Controls, Buttons, Dialogs,
FileUtil, Graphics, ComCtrls, Laz_XMLCfg, ExtCtrls, StdCtrls, TransferMacros, FileUtil, Graphics, ComCtrls, ExtCtrls, StdCtrls,
LazarusIDEStrConsts, LazConf, EnvironmentOpts, IDEProcs, AboutFrm, Laz_XMLCfg,
DefineTemplates; DefineTemplates, CodeToolManager,
TextTools,
TransferMacros, LazarusIDEStrConsts, LazConf, EnvironmentOpts, IDEProcs,
AboutFrm;
type type
TSDFilenameQuality = ( TSDFilenameQuality = (
sddqInvalid, sddqInvalid,
sddqWrongVersion, sddqWrongVersion,
sddqIncomplete,
sddqCompatible sddqCompatible
); );
@ -79,19 +83,14 @@ type
FPCSrcDirLabel: TLabel; FPCSrcDirLabel: TLabel;
FPCSrcDirMemo: TMemo; FPCSrcDirMemo: TMemo;
ImageList1: TImageList; ImageList1: TImageList;
LangComboBox: TComboBox;
LangLabel: TLabel;
LazDirBrowseButton: TButton; LazDirBrowseButton: TButton;
LazDirLabel: TLabel; LazDirLabel: TLabel;
LazDirComboBox: TComboBox; LazDirComboBox: TComboBox;
LazDirMemo: TMemo; LazDirMemo: TMemo;
PropertiesPageControl: TPageControl; PropertiesPageControl: TPageControl;
NextIssueBitBtn: TBitBtn;
PrevIssueBitBtn: TBitBtn;
PropertiesTreeView: TTreeView; PropertiesTreeView: TTreeView;
Splitter1: TSplitter; Splitter1: TSplitter;
StartIDEBitBtn: TBitBtn; StartIDEBitBtn: TBitBtn;
LanguageTabSheet: TTabSheet;
LazarusTabSheet: TTabSheet; LazarusTabSheet: TTabSheet;
CompilerTabSheet: TTabSheet; CompilerTabSheet: TTabSheet;
FPCSourcesTabSheet: TTabSheet; FPCSourcesTabSheet: TTabSheet;
@ -107,7 +106,13 @@ type
procedure PropertiesPageControlChange(Sender: TObject); procedure PropertiesPageControlChange(Sender: TObject);
procedure PropertiesTreeViewSelectionChanged(Sender: TObject); procedure PropertiesTreeViewSelectionChanged(Sender: TObject);
procedure WelcomePaintBoxPaint(Sender: TObject); procedure WelcomePaintBoxPaint(Sender: TObject);
procedure OnIdle(Sender: TObject; var Done: Boolean);
private private
FFPCSrcNeedsUpdate: boolean;
FCompilerNeedsUpdate: boolean;
FFPCVer: string;
FIdleConnected: boolean;
FLazarusDir: string;
ImgIDError: LongInt; ImgIDError: LongInt;
FHeadGraphic: TPortableNetworkGraphic; FHeadGraphic: TPortableNetworkGraphic;
FSelectingPage: boolean; FSelectingPage: boolean;
@ -119,6 +124,9 @@ type
procedure InitFPCSrcDir; procedure InitFPCSrcDir;
procedure FillComboboxWithFileInfoList(ABox: TComboBox; List: TObjectList; procedure FillComboboxWithFileInfoList(ABox: TComboBox; List: TObjectList;
ItemIndex: integer = 0); ItemIndex: integer = 0);
procedure SetFPCVer(const AValue: string);
procedure SetIdleConnected(const AValue: boolean);
procedure SetLazarusDir(const AValue: string);
procedure UpdateLazDirNote; procedure UpdateLazDirNote;
procedure UpdateCompilerNote; procedure UpdateCompilerNote;
procedure UpdateFPCSrcDirNote; procedure UpdateFPCSrcDirNote;
@ -126,8 +134,10 @@ type
TVNodeLazarus: TTreeNode; TVNodeLazarus: TTreeNode;
TVNodeCompiler: TTreeNode; TVNodeCompiler: TTreeNode;
TVNodeFPCSources: TTreeNode; TVNodeFPCSources: TTreeNode;
TVNodeLanguage: TTreeNode;
procedure Init; procedure Init;
property LazarusDir: string read FLazarusDir write SetLazarusDir; // expanded
property FPCVer: string read FFPCVer write SetFPCVer;
property IdleConnected: boolean read FIdleConnected write SetIdleConnected;
end; end;
procedure ShowInitialSetupDialog; procedure ShowInitialSetupDialog;
@ -141,12 +151,14 @@ function CheckLazarusDirectoryQuality(ADirectory: string;
function SearchLazarusDirectoryCandidates(StopIfFits: boolean): TObjectList; function SearchLazarusDirectoryCandidates(StopIfFits: boolean): TObjectList;
function CheckCompilerQuality(AFilename: string; function CheckCompilerQuality(AFilename: string;
out Note: string): TSDFilenameQuality; out Note: string; TestSrcFilename: string): TSDFilenameQuality;
function SearchCompilerCandidates(StopIfFits: boolean): TObjectList; function SearchCompilerCandidates(StopIfFits: boolean;
const LazarusDir, TestSrcFilename: string): TObjectList;
function CheckFPCSrcDirQuality(ADirectory: string; function CheckFPCSrcDirQuality(ADirectory: string;
out Note: string): TSDFilenameQuality; out Note: string; FPCVer: string): TSDFilenameQuality;
function SearchFPCSrcDirCandidates(StopIfFits: boolean): TObjectList; function SearchFPCSrcDirCandidates(StopIfFits: boolean;
const LazarusDir, FPCVer: string): TObjectList;
function GetValueFromPrimaryConfig(OptionFilename, Path: string): string; function GetValueFromPrimaryConfig(OptionFilename, Path: string): string;
function GetValueFromSecondaryConfig(OptionFilename, Path: string): string; function GetValueFromSecondaryConfig(OptionFilename, Path: string): string;
@ -163,6 +175,9 @@ type
procedure DoSubstitution(TheMacro: TTransferMacro; const MacroName: string; procedure DoSubstitution(TheMacro: TTransferMacro; const MacroName: string;
var s: string; const Data: PtrInt; var Handled, Abort: boolean; var s: string; const Data: PtrInt; var Handled, Abort: boolean;
Depth: integer); override; Depth: integer); override;
public
FPCVer: string;
LazarusDir: string;
end; end;
procedure SetupCompilerFilename(var InteractiveSetup: boolean); procedure SetupCompilerFilename(var InteractiveSetup: boolean);
@ -324,7 +339,8 @@ var
begin begin
Result:=sddqInvalid; Result:=sddqInvalid;
ADirectory:=TrimFilename(ADirectory); ADirectory:=TrimFilename(ADirectory);
if not DirPathExistsCached(ADirectory) then begin if not DirPathExistsCached(ADirectory) then
begin
Note:='Directory not found'; Note:='Directory not found';
exit; exit;
end; end;
@ -341,12 +357,14 @@ begin
try try
try try
sl.LoadFromFile(ADirectory+VersionIncFile); sl.LoadFromFile(ADirectory+VersionIncFile);
if (sl.Count=0) or (sl[0]='') or (sl[0][1]<>'''') then begin if (sl.Count=0) or (sl[0]='') or (sl[0][1]<>'''') then
begin
Note:='invalid version in '+VersionIncFile; Note:='invalid version in '+VersionIncFile;
exit; exit;
end; end;
Version:=copy(sl[0],2,length(sl[0])-2); Version:=copy(sl[0],2,length(sl[0])-2);
if Version<>LazarusVersionStr then begin if Version<>LazarusVersionStr then
begin
Note:='wrong version in '+VersionIncFile+': '+Version; Note:='wrong version in '+VersionIncFile+': '+Version;
Result:=sddqWrongVersion; Result:=sddqWrongVersion;
exit; exit;
@ -436,26 +454,56 @@ begin
if CheckDir(Dirs[i],Result) then exit; if CheckDir(Dirs[i],Result) then exit;
end; end;
function CheckCompilerQuality(AFilename: string; out Note: string function CheckCompilerQuality(AFilename: string; out Note: string;
): TSDFilenameQuality; TestSrcFilename: string): TSDFilenameQuality;
var
CfgCache: TFPCTargetConfigCache;
i: LongInt;
begin begin
Result:=sddqInvalid; Result:=sddqInvalid;
AFilename:=TrimFilename(AFilename); AFilename:=TrimFilename(AFilename);
if not FileExistsCached(AFilename) then begin if not FileExistsCached(AFilename) then
begin
Note:='File not found'; Note:='File not found';
exit; exit;
end; end;
if not FileIsExecutableCached(AFilename) then begin if not FileIsExecutableCached(AFilename) then
begin
Note:='File is not executable'; Note:='File is not executable';
exit; exit;
end; end;
if TestSrcFilename<>'' then
begin
CfgCache:=CodeToolBoss.FPCDefinesCache.ConfigCaches.Find(
AFilename,'','','',true);
if CfgCache.NeedsUpdate then
CfgCache.Update(TestSrcFilename);
i:=CfgCache.IndexOfUsedCfgFile;
if i<0 then
begin
Note:='fpc.cfg is missing.';
exit;
end;
if not CfgCache.HasPPUs then
begin
Note:='system.ppu not found. Check your fpc.cfg.';
exit;
end;
if CompareFileExt(CfgCache.Units['classes'],'ppu',false)<>0 then
begin
Note:='classes.ppu not found. Check your fpc.cfg.';
exit;
end;
end;
Note:='ok'; Note:='ok';
Result:=sddqCompatible; Result:=sddqCompatible;
end; end;
function SearchCompilerCandidates(StopIfFits: boolean): TObjectList; function SearchCompilerCandidates(StopIfFits: boolean;
const LazarusDir, TestSrcFilename: string): TObjectList;
var var
Macros: TTransferMacroList; Macros: TSetupMacros;
function CheckFile(AFilename: string; var List: TObjectList): boolean; function CheckFile(AFilename: string; var List: TObjectList): boolean;
var var
@ -467,14 +515,20 @@ var
AFilename:=TrimFilename(AFilename); AFilename:=TrimFilename(AFilename);
if AFilename='' then exit; if AFilename='' then exit;
// check if already checked // check if already checked
if List<>nil then begin if List<>nil then
begin
for i:=0 to List.Count-1 do for i:=0 to List.Count-1 do
if CompareFilenames(AFilename,TSDFileInfo(List[i]).Filename)=0 then exit; if CompareFilenames(AFilename,TSDFileInfo(List[i]).Filename)=0 then exit;
end; end;
// replace macros // replace macros
ResolvedFilename:=AFilename; ResolvedFilename:=AFilename;
if TTransferMacroList.StrHasMacros(ResolvedFilename) then begin if TSetupMacros.StrHasMacros(ResolvedFilename) then
Macros:=TSetupMacros.Create; begin
if Macros=nil then
begin
Macros:=TSetupMacros.Create;
Macros.LazarusDir:=LazarusDir;
end;
if not Macros.SubstituteStr(ResolvedFilename) then exit; if not Macros.SubstituteStr(ResolvedFilename) then exit;
ResolvedFilename:=TrimFilename(ResolvedFilename); ResolvedFilename:=TrimFilename(ResolvedFilename);
if ResolvedFilename='' then exit; if ResolvedFilename='' then exit;
@ -486,7 +540,7 @@ var
// add to list and check quality // add to list and check quality
Item:=TSDFileInfo.Create; Item:=TSDFileInfo.Create;
Item.Filename:=AFilename; Item.Filename:=AFilename;
Item.Quality:=CheckCompilerQuality(ResolvedFilename,Item.Note); Item.Quality:=CheckCompilerQuality(ResolvedFilename,Item.Note,TestSrcFilename);
Item.Caption:=AFilename; Item.Caption:=AFilename;
if List=nil then if List=nil then
List:=TObjectList.create(true); List:=TObjectList.create(true);
@ -540,8 +594,8 @@ begin
end; end;
end; end;
function CheckFPCSrcDirQuality(ADirectory: string; out Note: string function CheckFPCSrcDirQuality(ADirectory: string; out Note: string;
): TSDFilenameQuality; FPCVer: string): TSDFilenameQuality;
function SubDirExists(SubDir: string; var q: TSDFilenameQuality): boolean; function SubDirExists(SubDir: string; var q: TSDFilenameQuality): boolean;
begin begin
@ -551,23 +605,82 @@ function CheckFPCSrcDirQuality(ADirectory: string; out Note: string
Note:='directory '+SubDir+' not found'; Note:='directory '+SubDir+' not found';
end; end;
function SubFileExists(SubFile: string; var q: TSDFilenameQuality): boolean;
begin
SubFile:=SetDirSeparators(SubFile);
if FileExistsCached(ADirectory+SubFile) then exit(true);
Result:=false;
Note:='file '+SubFile+' not found';
end;
var
VersionFile: String;
sl: TStringList;
i: Integer;
VersionNr: String;
ReleaseNr: String;
PatchNr: String;
SrcVer: String;
begin begin
Result:=sddqInvalid; Result:=sddqInvalid;
ADirectory:=TrimFilename(ADirectory); ADirectory:=TrimFilename(ADirectory);
if not DirPathExistsCached(ADirectory) then begin if not DirPathExistsCached(ADirectory) then
begin
Note:='Directory not found'; Note:='Directory not found';
exit; exit;
end; end;
ADirectory:=AppendPathDelim(ADirectory); ADirectory:=AppendPathDelim(ADirectory);
if not SubDirExists('rtl',Result) then exit; if not SubDirExists('rtl',Result) then exit;
if not SubDirExists('packages',Result) then exit; if not SubDirExists('packages',Result) then exit;
if not SubFileExists('rtl/linux/system.pp',Result) then
begin
Note:='missing file ';
Result:=sddqIncomplete;
exit;
end;
// check version
if (FPCVer<>'') then
begin
VersionFile:=ADirectory+'compiler'+PathDelim+'version.pas';
if FileExistsCached(VersionFile) then
begin
sl:=TStringList.Create;
try
try
sl.LoadFromFile(VersionFile);
for i:=0 to sl.Count-1 do
begin
if REMatches(sl[i],' version_nr *= *''([0-9]+)''','I') then
VersionNr:=REVar(1)
else if REMatches(sl[i],' release_nr *= *''([0-9]+)''','I') then
ReleaseNr:=REVar(1)
else if REMatches(sl[i],' patch_nr *= *''([0-9]+)''','I') then begin
PatchNr:=REVar(1);
break;
end;
end;
SrcVer:=VersionNr+'.'+ReleaseNr+'.'+PatchNr;
if SrcVer<>FPCVer then
begin
Note:='Found version '+SrcVer+', expected '+FPCVer;
Result:=sddqWrongVersion;
exit;
end;
except
end;
finally
sl.Free;
end;
end;
end;
Note:='ok'; Note:='ok';
Result:=sddqCompatible; Result:=sddqCompatible;
end; end;
function SearchFPCSrcDirCandidates(StopIfFits: boolean): TObjectList; function SearchFPCSrcDirCandidates(StopIfFits: boolean;
const LazarusDir, FPCVer: string): TObjectList;
var var
Macros: TTransferMacroList; Macros: TSetupMacros;
function InList(AFilename: string; List: TObjectList): boolean; function InList(AFilename: string; List: TObjectList): boolean;
var var
@ -581,12 +694,9 @@ var
end; end;
function Check(AFilename: string; var List: TObjectList): boolean; function Check(AFilename: string; var List: TObjectList): boolean;
const
FPCVerMark = '- FPCVER -';
var var
Item: TSDFileInfo; Item: TSDFileInfo;
ResolvedFilename: String; ResolvedFilename: String;
p: Int64;
begin begin
Result:=false; Result:=false;
AFilename:=TrimFilename(AFilename); AFilename:=TrimFilename(AFilename);
@ -594,33 +704,27 @@ var
// check if already checked // check if already checked
if InList(AFilename,List) then exit; if InList(AFilename,List) then exit;
ResolvedFilename:=AFilename; ResolvedFilename:=AFilename;
p:=system.Pos('$(fpcver)',lowercase(ResolvedFilename));
if p>0 then begin
ResolvedFilename:=copy(ResolvedFilename,1,p-1)+FPCVerMark
+copy(ResolvedFilename,p+length('$(fpcver)'),length(ResolvedFilename));
end;
// replace macros // replace macros
if TTransferMacroList.StrHasMacros(ResolvedFilename) then begin if TSetupMacros.StrHasMacros(ResolvedFilename) then
Macros:=TSetupMacros.Create; begin
if Macros=nil then
begin
Macros:=TSetupMacros.Create;
Macros.LazarusDir:=LazarusDir;
Macros.FPCVer:=FPCVer;
end;
if not Macros.SubstituteStr(ResolvedFilename) then exit; if not Macros.SubstituteStr(ResolvedFilename) then exit;
ResolvedFilename:=TrimFilename(ResolvedFilename); ResolvedFilename:=TrimFilename(ResolvedFilename);
if ResolvedFilename='' then exit; if ResolvedFilename='' then exit;
end; end;
// expand file name // expand file name
ResolvedFilename:=ChompPathDelim(ExpandFileNameUTF8(ResolvedFilename)); ResolvedFilename:=ChompPathDelim(ExpandFileNameUTF8(ResolvedFilename));
p:=System.Pos(FPCVerMark,ResolvedFilename);
if p>0 then begin
end else begin
end;
// check if exists // check if exists
if not DirPathExistsCached(ResolvedFilename) then exit; if not DirPathExistsCached(ResolvedFilename) then exit;
// add to list and check quality // add to list and check quality
Item:=TSDFileInfo.Create; Item:=TSDFileInfo.Create;
Item.Filename:=AFilename; Item.Filename:=AFilename;
Item.Quality:=CheckFPCSrcDirQuality(ResolvedFilename,Item.Note); Item.Quality:=CheckFPCSrcDirQuality(ResolvedFilename,Item.Note,FPCVer);
Item.Caption:=AFilename; Item.Caption:=AFilename;
if List=nil then if List=nil then
List:=TObjectList.create(true); List:=TObjectList.create(true);
@ -732,8 +836,25 @@ begin
s:=GetPrimaryConfigPath s:=GetPrimaryConfigPath
else if CompareText(MacroName,'SecondaryConfiPath')=0 then else if CompareText(MacroName,'SecondaryConfiPath')=0 then
s:=GetSecondaryConfigPath s:=GetSecondaryConfigPath
else if CompareText(MacroName,'FPCVer')=0 then begin
if FPCVer<>'' then
s:=FPCVer
else
s:={$I %FPCVERSION%};
end else if CompareText(MacroName,'LazarusDir')=0 then begin
if LazarusDir<>'' then
s:=LazarusDir
else
s:='<LazarusDirNotSet>';
end else if CompareText(MacroName,'TargetOS')=0 then
s:=GetCompiledTargetOS
else if CompareText(MacroName,'TargetCPU')=0 then
s:=GetCompiledTargetCPU
else if CompareText(MacroName,'SrcOS')=0 then
s:=GetDefaultSrcOSForTargetOS(GetCompiledTargetOS)
else else
Handled:=false; Handled:=false;
//debugln(['TSetupMacros.DoSubstitution MacroName=',MacroName,' Value="',s,'"']);
end; end;
{$R *.lfm} {$R *.lfm}
@ -741,17 +862,17 @@ end;
{ TInitialSetupDialog } { TInitialSetupDialog }
procedure TInitialSetupDialog.FormCreate(Sender: TObject); procedure TInitialSetupDialog.FormCreate(Sender: TObject);
var
i: Integer;
Node: TTreeNode;
begin begin
Caption:='Welcome to Lazarus IDE '+GetLazarusVersionString; Caption:='Welcome to Lazarus IDE '+GetLazarusVersionString;
PrevIssueBitBtn.Caption:='Previous problem';
NextIssueBitBtn.Caption:='Next problem';
StartIDEBitBtn.Caption:='Start IDE'; StartIDEBitBtn.Caption:='Start IDE';
LazarusTabSheet.Caption:='Lazarus'; LazarusTabSheet.Caption:='Lazarus';
CompilerTabSheet.Caption:='Compiler'; CompilerTabSheet.Caption:='Compiler';
FPCSourcesTabSheet.Caption:='FPC sources'; FPCSourcesTabSheet.Caption:='FPC sources';
LanguageTabSheet.Caption:='Language';
FHeadGraphic:=TPortableNetworkGraphic.Create; FHeadGraphic:=TPortableNetworkGraphic.Create;
FHeadGraphic.LoadFromLazarusResource('ide_icon48x48'); FHeadGraphic.LoadFromLazarusResource('ide_icon48x48');
@ -759,16 +880,28 @@ begin
TVNodeLazarus:=PropertiesTreeView.Items.Add(nil,LazarusTabSheet.Caption); TVNodeLazarus:=PropertiesTreeView.Items.Add(nil,LazarusTabSheet.Caption);
TVNodeCompiler:=PropertiesTreeView.Items.Add(nil,CompilerTabSheet.Caption); TVNodeCompiler:=PropertiesTreeView.Items.Add(nil,CompilerTabSheet.Caption);
TVNodeFPCSources:=PropertiesTreeView.Items.Add(nil,FPCSourcesTabSheet.Caption); TVNodeFPCSources:=PropertiesTreeView.Items.Add(nil,FPCSourcesTabSheet.Caption);
TVNodeLanguage:=PropertiesTreeView.Items.Add(nil,LanguageTabSheet.Caption);
ImgIDError := ImageList1.AddLazarusResource('state_error'); ImgIDError := ImageList1.AddLazarusResource('state_error');
LazDirBrowseButton.Caption:='Browse'; LazDirBrowseButton.Caption:='Browse';
LazDirLabel.Caption:='Please set the Lazarus directory, which contains the sources of the IDE and the package files of LCL and many standard packages. For example it contains the file ide'+PathDelim+'lazarus.lpi. You can change this setting later in the environment options.'; LazDirLabel.Caption:='The Lazarus directory contains the sources of the IDE and the package files of LCL and many standard packages. For example it contains the file ide'+PathDelim+'lazarus.lpi. The translation files are located there too.';
CompilerBrowseButton.Caption:='Browse'; CompilerBrowseButton.Caption:='Browse';
CompilerLabel.Caption:='Please set the Free Pascal compiler executable, which typically has the name "'+GetDefaultCompilerFilename+'". You can also use the target specific compiler like "'+GetDefaultCompilerFilename(GetCompiledTargetCPU)+'". Please give the file name with full path. You can change this setting later in the environment options.'; CompilerLabel.Caption:='The Free Pascal compiler executable typically has the name "'+DefineTemplates.GetDefaultCompilerFilename+'". You can also use the target specific compiler like "'+DefineTemplates.GetDefaultCompilerFilename(GetCompiledTargetCPU)+'". Please give the full file path.';
FPCSrcDirBrowseButton.Caption:='Browse'; FPCSrcDirBrowseButton.Caption:='Browse';
FPCSrcDirLabel.Caption:='The sources of the Free Pascal packages are required for browsing and code completion. For example it has the file "'+SetDirSeparators('rtl/linux/system.pp')+'".';
// select first error
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
begin
Node:=PropertiesTreeView.Items.TopLvlItems[i];
if Node.ImageIndex=ImgIDError then begin
SelectPage(Node.Text);
break;
end;
end;
if PropertiesTreeView.Selected=nil then
PropertiesTreeView.Selected:=TVNodeLazarus;
end; end;
procedure TInitialSetupDialog.CompilerComboBoxChange(Sender: TObject); procedure TInitialSetupDialog.CompilerComboBoxChange(Sender: TObject);
@ -790,6 +923,7 @@ procedure TInitialSetupDialog.FormDestroy(Sender: TObject);
var var
d: TSDFilenameType; d: TSDFilenameType;
begin begin
IdleConnected:=false;
for d:=low(FDirs) to high(FDirs) do for d:=low(FDirs) to high(FDirs) do
FreeAndNil(FDirs); FreeAndNil(FDirs);
FreeAndNil(FHeadGraphic); FreeAndNil(FHeadGraphic);
@ -826,8 +960,15 @@ begin
end; end;
procedure TInitialSetupDialog.PropertiesPageControlChange(Sender: TObject); procedure TInitialSetupDialog.PropertiesPageControlChange(Sender: TObject);
var
s: String;
i: Integer;
begin begin
if PropertiesPageControl.ActivePage=nil then exit;
s:=PropertiesPageControl.ActivePage.Caption;
for i:=0 to PropertiesTreeView.Items.TopLvlCount-1 do
if PropertiesTreeView.Items.TopLvlItems[i].Text=s then
PropertiesTreeView.Selected:=PropertiesTreeView.Items.TopLvlItems[i];
end; end;
procedure TInitialSetupDialog.PropertiesTreeViewSelectionChanged(Sender: TObject procedure TInitialSetupDialog.PropertiesTreeViewSelectionChanged(Sender: TObject
@ -851,6 +992,16 @@ begin
end; end;
end; end;
procedure TInitialSetupDialog.OnIdle(Sender: TObject; var Done: Boolean);
begin
if FCompilerNeedsUpdate then
InitCompilerFilename
else if FFPCSrcNeedsUpdate then
InitFPCSrcDir
else
IdleConnected:=false;
end;
procedure TInitialSetupDialog.SelectPage(const NodeText: string); procedure TInitialSetupDialog.SelectPage(const NodeText: string);
var var
i: Integer; i: Integer;
@ -903,8 +1054,10 @@ procedure TInitialSetupDialog.InitCompilerFilename;
var var
Files: TObjectList; Files: TObjectList;
begin begin
FCompilerNeedsUpdate:=false;
FreeAndNil(FDirs[sddtCompilerFilename]); FreeAndNil(FDirs[sddtCompilerFilename]);
Files:=SearchCompilerCandidates(false); Files:=SearchCompilerCandidates(false,LazDirComboBox.Text,
CodeToolBoss.FPCDefinesCache.TestFilename);
FDirs[sddtCompilerFilename]:=Files; FDirs[sddtCompilerFilename]:=Files;
FillComboboxWithFileInfoList(CompilerComboBox,Files); FillComboboxWithFileInfoList(CompilerComboBox,Files);
UpdateCompilerNote; UpdateCompilerNote;
@ -914,8 +1067,9 @@ procedure TInitialSetupDialog.InitFPCSrcDir;
var var
Dirs: TObjectList; Dirs: TObjectList;
begin begin
FFPCSrcNeedsUpdate:=false;
FreeAndNil(FDirs[sddtFPCSrcDir]); FreeAndNil(FDirs[sddtFPCSrcDir]);
Dirs:=SearchFPCSrcDirCandidates(false);; Dirs:=SearchFPCSrcDirCandidates(false,LazDirComboBox.Text,FPCVer);
FDirs[sddtFPCSrcDir]:=Dirs; FDirs[sddtFPCSrcDir]:=Dirs;
FillComboboxWithFileInfoList(FPCSrcDirComboBox,Dirs); FillComboboxWithFileInfoList(FPCSrcDirComboBox,Dirs);
UpdateFPCSrcDirNote; UpdateFPCSrcDirNote;
@ -940,7 +1094,39 @@ begin
end; end;
end; end;
procedure TInitialSetupDialog.SetFPCVer(const AValue: string);
begin
if FFPCVer=AValue then exit;
FFPCVer:=AValue;
FFPCSrcNeedsUpdate:=true;
end;
procedure TInitialSetupDialog.SetIdleConnected(const AValue: boolean);
begin
if FIdleConnected=AValue then exit;
FIdleConnected:=AValue;
if IdleConnected then
Application.AddOnIdleHandler(@OnIdle)
else
Application.RemoveOnIdleHandler(@OnIdle);
end;
procedure TInitialSetupDialog.SetLazarusDir(const AValue: string);
begin
if FLazarusDir=AValue then exit;
FLazarusDir:=AValue;
FCompilerNeedsUpdate:=true;
end;
procedure TInitialSetupDialog.UpdateLazDirNote; procedure TInitialSetupDialog.UpdateLazDirNote;
function NormDir(const Dir: string): string;
begin
Result:=ChompPathDelim(TrimFilename(Dir));
if Result<>'' then
Result:=ChompPathDelim(TrimFilename(ExpandFileNameUTF8(Result)));
end;
var var
i: Integer; i: Integer;
Dirs: TObjectList; Dirs: TObjectList;
@ -960,13 +1146,15 @@ begin
if i>=0 then begin if i>=0 then begin
Quality:=TSDFileInfo(Dirs[i]).Quality; Quality:=TSDFileInfo(Dirs[i]).Quality;
Note:=TSDFileInfo(Dirs[i]).Note; Note:=TSDFileInfo(Dirs[i]).Note;
LazarusDir:=NormDir(TSDFileInfo(Dirs[i]).Filename);
end else begin end else begin
LazarusDir:=NormDir(CurCaption);
Quality:=CheckLazarusDirectoryQuality(CurCaption,Note); Quality:=CheckLazarusDirectoryQuality(CurCaption,Note);
end; end;
case Quality of case Quality of
sddqInvalid: s:='Error: '; sddqInvalid: s:='Error: ';
sddqWrongVersion: s:='Warning: ';
sddqCompatible: s:=''; sddqCompatible: s:='';
else s:='Warning: ';
end; end;
LazDirMemo.Text:=s+Note; LazDirMemo.Text:=s+Note;
@ -979,6 +1167,25 @@ begin
end; end;
procedure TInitialSetupDialog.UpdateCompilerNote; procedure TInitialSetupDialog.UpdateCompilerNote;
function NormFile(const AFilename: string): string;
var
Macros: TSetupMacros;
begin
Result:=TrimFilename(AFilename);
if TSetupMacros.StrHasMacros(Result) then begin
Macros:=TSetupMacros.Create;
try
Macros.LazarusDir:=LazarusDir;
Macros.SubstituteStr(Result);
finally
Macros.Free;
end;
end;
if Result<>'' then
Result:=TrimFilename(ExpandFileNameUTF8(Result));
end;
var var
i: Integer; i: Integer;
Files: TObjectList; Files: TObjectList;
@ -987,6 +1194,8 @@ var
Quality: TSDFilenameQuality; Quality: TSDFilenameQuality;
s: String; s: String;
ImageIndex: Integer; ImageIndex: Integer;
CompilerFile: String;
CfgCache: TFPCTargetConfigCache;
begin begin
i:=-1; i:=-1;
Files:=FDirs[sddtCompilerFilename]; Files:=FDirs[sddtCompilerFilename];
@ -998,13 +1207,24 @@ begin
if i>=0 then begin if i>=0 then begin
Quality:=TSDFileInfo(Files[i]).Quality; Quality:=TSDFileInfo(Files[i]).Quality;
Note:=TSDFileInfo(Files[i]).Note; Note:=TSDFileInfo(Files[i]).Note;
CompilerFile:=NormFile(TSDFileInfo(Files[i]).Filename);
end else begin end else begin
Quality:=CheckCompilerQuality(CurCaption,Note); CompilerFile:=NormFile(CurCaption);
Quality:=CheckCompilerQuality(CurCaption,Note,
CodeToolBoss.FPCDefinesCache.TestFilename);
end; end;
if Quality=sddqInvalid then
FPCVer:=''
else begin
CfgCache:=CodeToolBoss.FPCDefinesCache.ConfigCaches.Find(
CompilerFile,'','','',true);
FPCVer:=CfgCache.GetFPCVer;
end;
case Quality of case Quality of
sddqInvalid: s:='Error: '; sddqInvalid: s:='Error: ';
sddqWrongVersion: s:='Warning: ';
sddqCompatible: s:=''; sddqCompatible: s:='';
else s:='Warning: ';
end; end;
CompilerMemo.Text:=s+Note; CompilerMemo.Text:=s+Note;
@ -1017,6 +1237,27 @@ begin
end; end;
procedure TInitialSetupDialog.UpdateFPCSrcDirNote; procedure TInitialSetupDialog.UpdateFPCSrcDirNote;
function NormDir(const AFilename: string): string;
var
Macros: TSetupMacros;
begin
Result:=TrimFilename(AFilename);
if TSetupMacros.StrHasMacros(Result) then begin
Macros:=TSetupMacros.Create;
try
Macros.LazarusDir:=LazarusDir;
Macros.FPCVer:=FPCVer;
Macros.SubstituteStr(Result);
finally
Macros.Free;
end;
end;
Result:=ChompPathDelim(Result);
if Result<>'' then
Result:=ChompPathDelim(TrimFilename(ExpandFileNameUTF8(Result)));
end;
var var
i: Integer; i: Integer;
Dirs: TObjectList; Dirs: TObjectList;
@ -1037,12 +1278,12 @@ begin
Quality:=TSDFileInfo(Dirs[i]).Quality; Quality:=TSDFileInfo(Dirs[i]).Quality;
Note:=TSDFileInfo(Dirs[i]).Note; Note:=TSDFileInfo(Dirs[i]).Note;
end else begin end else begin
Quality:=CheckFPCSrcDirQuality(CurCaption,Note); Quality:=CheckFPCSrcDirQuality(CurCaption,Note,FPCVer);
end; end;
case Quality of case Quality of
sddqInvalid: s:='Error: '; sddqInvalid: s:='Error: ';
sddqWrongVersion: s:='Warning: ';
sddqCompatible: s:=''; sddqCompatible: s:='';
else s:='Warning: ';
end; end;
FPCSrcDirMemo.Text:=s+Note; FPCSrcDirMemo.Text:=s+Note;

View File

@ -405,14 +405,12 @@ begin
// Macro variable // Macro variable
MacroName:=copy(s,MacroStart+2,OldMacroLen-3); MacroName:=copy(s,MacroStart+2,OldMacroLen-3);
AMacro:=FindByName(MacroName); AMacro:=FindByName(MacroName);
if Assigned(fOnSubstitution) then begin DoSubstitution(AMacro,MacroName,MacroName,Data,Handled,Abort,Depth+LoopDepth);
fOnSubstitution(AMacro,MacroName,MacroName,Data,Handled,Abort,Depth+LoopDepth); if Handled then
if Handled then MacroStr:=MacroName
MacroStr:=MacroName else if Abort then begin
else if Abort then begin Result:=false;
Result:=false; exit;
exit;
end;
end; end;
if (not Handled) and (AMacro<>nil) then begin if (not Handled) and (AMacro<>nil) then begin
// standard macro // standard macro