dexed/src/u_compilers.pas

940 lines
27 KiB
Plaintext

unit u_compilers;
{$I u_defines.inc}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, EditBtn,
StdCtrls,
u_dcd, u_common, u_interfaces, u_observer, u_writableComponent,
u_dialogs;
type
TCompilersPaths = class(TWritableLfmTextComponent)
strict private
fPathsForCompletion: DCompiler;
fDmdExeName: string;
fDmdRuntimePath: string;
fDmdPhobosPath: string;
fGdcExeName: string;
fGdcRuntimePath: string;
fGdcPhobosPath: string;
fLdcExeName: string;
fLdcRuntimePath: string;
fLdcPhobosPath: string;
fUser1ExeName: string;
fUser1RuntimePath: string;
fUser1PhobosPath: string;
fUser2ExeName: string;
fUser2RuntimePath: string;
fUser2PhobosPath: string;
fModified: boolean;
fWouldNeedRestart: boolean;
fDefinedAsGlobal: DCompiler;
procedure setDefinedAsGlobal(value: DCompiler);
procedure setPathsForCompletion(value: DCompiler);
procedure setDmdExeName(const value: string);
procedure setDmdRuntimePath(const value: string);
procedure setDmdPhobosPath(const value: string);
procedure setGdcExeName(const value: string);
procedure setGdcRuntimePath(const value: string);
procedure setGdcPhobosPath(const value: string);
procedure setLdcExeName(const value: string);
procedure setLdcRuntimePath(const value: string);
procedure setLdcPhobosPath(const value: string);
procedure setUser1ExeName(const value: string);
procedure setUser1RuntimePath(const value: string);
procedure setUser1PhobosPath(const value: string);
procedure setUser2ExeName(const value: string);
procedure setUser2RuntimePath(const value: string);
procedure setUser2PhobosPath(const value: string);
private
procedure checkIfGlobalIsGlobal;
protected
procedure afterLoad; override;
published
property definedAsGlobal: DCompiler read fDefinedAsGlobal write setDefinedAsGlobal;
property pathsForCompletion: DCompiler read fPathsForCompletion write setPathsForCompletion;
property DmdExeName: string read fDmdExeName write setDmdExeName;
property DmdRuntimePath: string read fDmdRuntimePath write setDmdRuntimePath;
property DmdPhobosPath: string read fDmdPhobosPath write setDmdPhobosPath;
property GdcExeName: string read fGdcExeName write setGdcExeName;
property GdcRuntimePath: string read fGdcRuntimePath write setGdcRuntimePath;
property GdcPhobosPath: string read fGdcPhobosPath write setGdcPhobosPath;
property LdcExeName: string read fLdcExeName write setLdcExeName;
property LdcRuntimePath: string read fLdcRuntimePath write setLdcRuntimePath;
property LdcPhobosPath: string read fLdcPhobosPath write setLdcPhobosPath;
property User1ExeName: string read fUser1ExeName write setUser1ExeName;
property User1RuntimePath: string read fUser1RuntimePath write setUser1RuntimePath;
property User1PhobosPath: string read fUser1PhobosPath write setUser1PhobosPath;
property User2ExeName: string read fUser2ExeName write setUser2ExeName;
property User2RuntimePath: string read fUser2RuntimePath write setUser2RuntimePath;
property User2PhobosPath: string read fUser2PhobosPath write setUser2PhobosPath;
public
procedure assign(source: TPersistent); override;
property wouldNeedRestart: boolean read fWouldNeedRestart write fWouldNeedRestart;
property modified: boolean read fModified write fModified;
end;
{ TCompilersPathsEditor }
TCompilersPathsEditor = class(TForm, IEditableOptions, ICompilerSelector, IProjectObserver)
GroupBox7: TGroupBox;
selDefault: TComboBox;
selGlobal: TComboBox;
selDMDrt: TDirectoryEdit;
selUSER2std: TDirectoryEdit;
selDMDstd: TDirectoryEdit;
selGDCrt: TDirectoryEdit;
selGDCstd: TDirectoryEdit;
selLDCrt: TDirectoryEdit;
selLDCstd: TDirectoryEdit;
selUSER1rt: TDirectoryEdit;
selUSER1std: TDirectoryEdit;
selUSER2rt: TDirectoryEdit;
selDMDexe: TFileNameEdit;
selGDCexe: TFileNameEdit;
selLDCexe: TFileNameEdit;
selUSER1exe: TFileNameEdit;
selUSER2exe: TFileNameEdit;
grpDMD: TGroupBox;
grpGDC: TGroupBox;
grpLDC: TGroupBox;
grpUSER1: TGroupBox;
grpUSER2: TGroupBox;
GroupBox6: TGroupBox;
ScrollBox1: TScrollBox;
StaticText1: TStaticText;
StaticText10: TStaticText;
StaticText11: TStaticText;
StaticText12: TStaticText;
StaticText13: TStaticText;
StaticText14: TStaticText;
StaticText15: TStaticText;
StaticText2: TStaticText;
StaticText3: TStaticText;
StaticText4: TStaticText;
StaticText5: TStaticText;
StaticText6: TStaticText;
StaticText7: TStaticText;
StaticText8: TStaticText;
StaticText9: TStaticText;
procedure dialogOpen(sender: TObject);
strict private
fPaths: TCompilersPaths;
fPathsBackup: TCompilersPaths;
fProj: ICommonProject;
procedure editedExe(sender: TObject);
procedure editedRt(sender: TObject);
procedure editedStd(sender: TObject);
procedure selectedExe(sender: TObject; var value: string);
procedure selectedRt(sender: TObject; var value: string);
procedure selectedStd(sender: TObject; var value: string);
procedure selectedDefault(sender: TObject);
procedure selectedGlobal(sender: TObject);
procedure autoDetectDMD;
procedure autoDetectGDC;
procedure autoDetectLDC;
procedure dataToGui;
//
function optionedWantCategory(): string;
function optionedWantEditorKind: TOptionEditorKind;
function optionedWantContainer: TPersistent;
procedure optionedEvent(event: TOptionEditorEvent);
function optionedOptionsModified: boolean;
//
function singleServiceName: string;
function isCompilerValid(value: DCompiler): boolean;
function getCompilerPath(value: DCompiler): string;
procedure getCompilerImports(value: DCompiler; paths: TStrings);
//
procedure projNew(project: ICommonProject);
procedure projChanged(project: ICommonProject);
procedure projClosing(project: ICommonProject);
procedure projFocused(project: ICommonProject);
procedure projCompiling(project: ICommonProject);
procedure projCompiled(project: ICommonProject; success: boolean);
procedure updateDCD;
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
end;
//var
// globalCompiler: DCompiler;
implementation
{$R *.lfm}
uses
u_libman;
var
CompilersPathsEditor: TCompilersPathsEditor;
const
optFname = 'compilerspaths.txt';
{$REGION Standard Object/Components things -------------------------------------}
constructor TCompilersPathsEditor.create(aOwner: TComponent);
var
fname: string;
dcomp: DCompiler;
begin
inherited;
selDefault.Items.BeginUpdate;
selGlobal.Items.BeginUpdate;
try for dcomp in DCompiler do
begin
case dcomp of
dmd:
begin
selDefault.Items.Add('DMD');
selGlobal.Items.Add('DMD');
end;
gdc:
begin
selDefault.Items.Add('GDC');
selGlobal.Items.Add('GDC');
end;
gdmd:
begin
selDefault.Items.Add('GDMD (same paths as GDC)');
selGlobal.Items.Add('GDMD (same paths as GDC)');
end;
ldc:
begin
selDefault.Items.Add('LDC');
selGlobal.Items.Add('LDC');
end;
ldmd:
begin
selDefault.Items.Add('LDMD (same paths as LDC)');
selGlobal.Items.Add('LDMD (same paths as LDC)');
end;
user1:
begin
selDefault.Items.Add('USER1');
selGlobal.Items.Add('USER1');
end;
user2:
begin
selDefault.Items.Add('USER2');
selGlobal.Items.Add('USER2');
end;
global:
begin
selDefault.Items.Add('GLOBAL (as defined in the options)');
// 'global' must be everything but 'global'
selGlobal.Items.Add('<N/A>');
end;
else raise Exception.create('missing DCompiler value in a case of');
end;
end;
finally
selDefault.Items.EndUpdate;
selGlobal.Items.EndUpdate;
end;
fPaths:= TCompilersPaths.Create(self);
fPathsBackup:= TCompilersPaths.Create(self);
fname := getDocPath + optFname;
if fname.fileExists then
fPaths.loadFromFile(fname);
if not isCompilerValid(dmd) then
autoDetectDMD;
if not isCompilerValid(gdc) then
autoDetectGDC;
// #148 / #210
// if not isCompilerValid(ldc) then
// autoDetectLDC;
fPathsBackup.Assign(fPaths);
dataToGui;
updateDCD;
selDMDexe.OnAcceptFileName:= @selectedExe;
selGDCexe.OnAcceptFileName:= @selectedExe;
selLDCexe.OnAcceptFileName:= @selectedExe;
selUSER1exe.OnAcceptFileName:= @selectedExe;
selUSER2exe.OnAcceptFileName:= @selectedExe;
selDMDexe.OnEditingDone:= @editedExe;
selGDCexe.OnEditingDone:= @editedExe;
selLDCexe.OnEditingDone:= @editedExe;
selUSER1exe.OnEditingDone:= @editedExe;
selUSER2exe.OnEditingDone:= @editedExe;
selDMDrt.OnAcceptDirectory:= @selectedRt;
selGDCrt.OnAcceptDirectory:= @selectedRt;
selLDCrt.OnAcceptDirectory:= @selectedRt;
selUSER1rt.OnAcceptDirectory:= @selectedRt;
selUSER2rt.OnAcceptDirectory:= @selectedRt;
selDMDrt.OnEditingDone:= @editedRt;
selGDCrt.OnEditingDone:= @editedRt;
selLDCrt.OnEditingDone:= @editedRt;
selUSER1rt.OnEditingDone:= @editedRt;
selUSER2rt.OnEditingDone:= @editedRt;
selDMDstd.OnAcceptDirectory:= @selectedStd;
selGDCstd.OnAcceptDirectory:= @selectedStd;
selLDCstd.OnAcceptDirectory:= @selectedStd;
selUSER1std.OnAcceptDirectory:= @selectedStd;
selUSER2std.OnAcceptDirectory:= @selectedStd;
selDMDstd.OnEditingDone:= @editedStd;
selGDCstd.OnEditingDone:= @editedStd;
selLDCstd.OnEditingDone:= @editedStd;
selUSER1std.OnEditingDone:= @editedStd;
selUSER2std.OnEditingDone:= @editedStd;
selDefault.OnSelect:= @selectedDefault;
selGlobal.OnSelect:= @selectedGlobal;
EntitiesConnector.addSingleService(self);
EntitiesConnector.addObserver(self);
end;
destructor TCompilersPathsEditor.destroy;
begin
fPaths.saveToFile(getDocPath + optFname);
EntitiesConnector.removeObserver(self);
inherited;
end;
procedure TCompilersPaths.checkIfGlobalIsGlobal;
begin
if fDefinedAsGlobal = DCompiler.global then
begin
fDefinedAsGlobal := low(DCompiler);
raise Exception.Create('global compiler should not be set to DCompiler.global');
end;
end;
procedure TCompilersPaths.assign(source: TPersistent);
var
src: TCompilersPaths;
begin
if source is TCompilersPaths then
begin
src := TCompilersPaths(source);
pathsForCompletion := src.fPathsForCompletion;
DmdExeName := src.fDmdExeName;
DmdRuntimePath := src.fDmdRuntimePath;
DmdPhobosPath := src.fDmdPhobosPath;
GdcExeName := src.fGdcExeName;
GdcRuntimePath := src.fGdcRuntimePath;
GdcPhobosPath := src.fGdcPhobosPath;
LdcExeName := src.fLdcExeName;
LdcRuntimePath := src.fLdcRuntimePath;
LdcPhobosPath := src.fLdcPhobosPath;
User1ExeName := src.fUser1ExeName;
User1RuntimePath := src.fUser1RuntimePath;
User1PhobosPath := src.fUser1PhobosPath;
User2ExeName := src.fUser2ExeName;
User2RuntimePath := src.fUser2RuntimePath;
User2PhobosPath := src.fUser2PhobosPath;
end
else inherited;
end;
procedure TCompilersPaths.setPathsForCompletion(value: Dcompiler);
begin
if fPathsForCompletion = value then
exit;
fPathsForCompletion:=value;
fWouldNeedRestart := true;
fModified:=true;
end;
procedure TCompilersPaths.setDefinedAsGlobal(value: DCompiler);
begin
if value = DCompiler.global then
value := low(DCompiler);
fDefinedAsGlobal := value;
end;
procedure TCompilersPaths.setDmdExeName(const value: string);
begin
if fDmdExeName = value then
exit;
fDmdExeName:=value;
fModified:=true;
end;
procedure TCompilersPaths.setDmdRuntimePath(const value: string);
begin
if fDmdRuntimePath = value then
exit;
fDmdRuntimePath:=value;
fModified:=true;
if fPathsForCompletion = dmd then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setDmdPhobosPath(const value: string);
begin
if fDmdPhobosPath = value then
exit;
fDmdPhobosPath:=value;
fModified:=true;
if fPathsForCompletion = dmd then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setGdcExeName(const value: string);
begin
if fGdcExeName = value then
exit;
fGdcExeName:=value;
fModified:=true;
end;
procedure TCompilersPaths.setGdcRuntimePath(const value: string);
begin
if fGdcRuntimePath = value then
exit;
fGdcRuntimePath:=value;
fModified:=true;
if fPathsForCompletion in [gdc,gdmd] then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setGdcPhobosPath(const value: string);
begin
if fGdcPhobosPath = value then
exit;
fGdcPhobosPath:=value;
fModified:=true;
if fPathsForCompletion in [gdc,gdmd] then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setLdcExeName(const value: string);
begin
if fLdcExeName = value then
exit;
fLdcExeName:=value;
fModified:=true;
end;
procedure TCompilersPaths.setLdcRuntimePath(const value: string);
begin
if fLdcRuntimePath = value then
exit;
fLdcRuntimePath:=value;
fModified:=true;
if fPathsForCompletion in [ldc,ldmd] then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setLdcPhobosPath(const value: string);
begin
if fLdcPhobosPath = value then
exit;
fLdcPhobosPath:=value;
fModified:=true;
if fPathsForCompletion in [ldc,ldmd] then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setUser1ExeName(const value: string);
begin
if fUser1ExeName = value then
exit;
fUser1ExeName:=value;
fModified:=true;
end;
procedure TCompilersPaths.setUser1RuntimePath(const value: string);
begin
if fUser1RuntimePath = value then
exit;
fUser1RuntimePath:=value;
fModified:=true;
if fPathsForCompletion = user1 then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setUser1PhobosPath(const value: string);
begin
if fUser1PhobosPath = value then
exit;
fUser1PhobosPath:=value;
fModified:=true;
if fPathsForCompletion = user1 then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setUser2ExeName(const value: string);
begin
if fUser2ExeName = value then
exit;
fUser2ExeName:=value;
fModified:=true;
end;
procedure TCompilersPaths.setUser2RuntimePath(const value: string);
begin
if fUser2RuntimePath = value then
exit;
fUser2RuntimePath:=value;
fModified:=true;
if fPathsForCompletion = user2 then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.setUser2PhobosPath(const value: string);
begin
if fUser2PhobosPath = value then
exit;
fUser2PhobosPath:=value;
fModified:=true;
if fPathsForCompletion = user2 then
fWouldNeedRestart := true;
end;
procedure TCompilersPaths.afterLoad;
begin
inherited;
fModified:=false;
fWouldNeedRestart:=false;
end;
{$ENDREGION}
{$REGION IProjectObserver ----------------------------------------------------}
procedure TCompilersPathsEditor.projNew(project: ICommonProject);
begin
end;
procedure TCompilersPathsEditor.projChanged(project: ICommonProject);
begin
end;
procedure TCompilersPathsEditor.projClosing(project: ICommonProject);
begin
if fProj = project then
fProj := nil;
end;
procedure TCompilersPathsEditor.projFocused(project: ICommonProject);
begin
fProj := project;
end;
procedure TCompilersPathsEditor.projCompiling(project: ICommonProject);
begin
end;
procedure TCompilersPathsEditor.projCompiled(project: ICommonProject; success: boolean);
begin
end;
{$ENDREGION}
{$REGION IEditableOptions ----------------------------------------------------}
function TCompilersPathsEditor.optionedWantCategory(): string;
begin
exit('Compilers paths');
end;
function TCompilersPathsEditor.optionedWantEditorKind: TOptionEditorKind;
begin
exit(oekForm);
end;
function TCompilersPathsEditor.optionedWantContainer: TPersistent;
begin
fPathsBackup.assign(fPaths);
exit(self);
end;
procedure TCompilersPathsEditor.optionedEvent(event: TOptionEditorEvent);
begin
case event of
oeeAccept:
begin
fPathsBackup.assign(fPaths);
if fPaths.wouldNeedRestart and fPaths.modified then
begin
if not DCDWrapper.launchedByCe then
dlgOkInfo('Dexed and DCD must be restarted manually in order to cache'
+ ' the right runtime and the standard library versions.')
else
begin
DCDWrapper.relaunch;
updateDCD;
LibMan.updateDCD;
if assigned(fProj) then
fProj.activate;
end;
end;
fPaths.modified:=false;
fPaths.wouldNeedRestart:=false;
end;
oeeCancel:
begin
fPaths.assign(fPathsBackup);
fPaths.modified:=false;
fPaths.wouldNeedRestart:=false;
end;
end;
end;
function TCompilersPathsEditor.optionedOptionsModified: boolean;
begin
exit(fPaths.modified);
end;
{$ENDREGION}
{$REGION ICompilerSelector ---------------------------------------------------}
function TCompilersPathsEditor.singleServiceName: string;
begin
exit('ICompilerSelector');
end;
function TCompilersPathsEditor.isCompilerValid(value: DCompiler): boolean;
begin
result := false;
with fPaths do case value of
DCompiler.dmd: exit(DmdExeName.fileExists);
DCompiler.gdc: exit(GdcExeName.fileExists);
DCompiler.gdmd: exit(exeFullName('gdmd' + exeExt).fileExists);
DCompiler.ldc: exit(LdcExeName.fileExists);
DCompiler.ldmd: exit(exeFullName('ldmd2' + exeExt).fileExists);
DCompiler.user1: exit(User1ExeName.fileExists);
DCompiler.user2: exit(User2ExeName.fileExists);
DCompiler.global:
begin
fPaths.checkIfGlobalIsGlobal;
exit(isCompilerValid(fPaths.definedAsGlobal));
end;
end;
end;
function TCompilersPathsEditor.getCompilerPath(value: DCompiler): string;
begin
result := '';
with fPaths do case value of
DCompiler.dmd: exit(DmdExeName);
DCompiler.gdc: exit(GdcExeName);
DCompiler.gdmd: exit(exeFullName('gdmd' + exeExt));
DCompiler.ldc: exit(LdcExeName);
DCompiler.ldmd: exit(exeFullName('ldmd2' + exeExt));
DCompiler.user1: exit(User1ExeName);
DCompiler.user2: exit(User2ExeName);
DCompiler.global:
begin
checkIfGlobalIsGlobal;
exit(getCompilerPath(fPaths.definedAsGlobal));
end;
end;
end;
procedure TCompilersPathsEditor.getCompilerImports(value: DCompiler; paths: TStrings);
procedure tryAdd(const pth: string);
begin
if pth.isNotEmpty then
paths.Add(pth);
end;
begin
with fPaths do case value of
DCompiler.dmd: begin tryAdd(DmdRuntimePath); tryAdd(DmdPhobosPath); end;
DCompiler.gdc, DCompiler.gdmd:
begin tryAdd(GdcRuntimePath); tryAdd(GdcPhobosPath); end;
DCompiler.ldc, DCompiler.ldmd:
begin tryAdd(LdcRuntimePath); tryAdd(LdcPhobosPath); end;
DCompiler.user1:
begin tryAdd(User1RuntimePath); tryAdd(User1PhobosPath); end;
DCompiler.user2:
begin tryAdd(User2RuntimePath); tryAdd(User2PhobosPath); end;
DCompiler.global:
begin checkIfGlobalIsGlobal; getCompilerImports(fPaths.definedAsGlobal, paths); end;
end;
end;
{$ENDREGION}
{$REGION Compilers paths things ------------------------------------------------}
procedure TCompilersPathsEditor.updateDCD;
var
imprt: TStringList;
begin
imprt := TStringList.Create;
try
getCompilerImports(fPaths.pathsForCompletion, imprt);
DcdWrapper.addImportFolders(imprt);
finally
imprt.free;
end;
end;
procedure TCompilersPathsEditor.dataToGui;
begin
with fPaths do
begin
selDMDexe.FileName := DmdExeName;
selDMDrt.Directory := DmdRuntimePath;
selDMDstd.Directory := DmdPhobosPath;
selGDCexe.FileName := GdcExeName;
selGDCrt.Directory := GdcRuntimePath;
selGDCstd.Directory := GdcPhobosPath;
selLDCexe.FileName := LdcExeName;
selLDCrt.Directory := LdcRuntimePath;
selLDCstd.Directory := LdcPhobosPath;
selUSER1exe.FileName := User1ExeName;
selUSER1rt.Directory := User1RuntimePath;
selUSER1std.Directory := User1PhobosPath;
selUSER2exe.FileName := User2ExeName;
selUSER2rt.Directory := User2RuntimePath;
selUSER2std.Directory := User2PhobosPath;
selDefault.ItemIndex := integer(pathsForCompletion);
selGlobal.ItemIndex := integer(definedAsGlobal);
end;
end;
procedure TCompilersPathsEditor.dialogOpen(sender: TObject);
var
fne: TFileNameEdit;
dre: TDirectoryEdit;
begin
if sender is TFileNameEdit then
begin
fne := TFileNameEdit(sender);
fne.InitialDir:=fne.FileName.extractFileDir;
fne.DialogTitle:='Select a D compiler';
end
else
begin
dre := TDirectoryEdit(sender);
dre.RootDir:=dre.Directory;
dre.ShowHidden:=true;
dre.DialogTitle:='Select a library path';
end;
end;
procedure TCompilersPathsEditor.selectedExe(sender: TObject; var value: string);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdExeName:=value
else if ctrl.Parent = grpGDC then
fPaths.GDCExeName:=value
else if ctrl.Parent = grpLDC then
fPaths.LdcExeName:=value
else if ctrl.Parent = grpUSER1 then
fPaths.User1ExeName:=value
else if ctrl.Parent = grpUSER2 then
fPaths.User2ExeName:=value;
end;
procedure TCompilersPathsEditor.editedExe(sender: TObject);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdExeName:=selDMDexe.FileName
else if ctrl.Parent = grpGDC then
fPaths.GDCExeName:=selGDCexe.FileName
else if ctrl.Parent = grpLDC then
fPaths.LdcExeName:=selLDCexe.FileName
else if ctrl.Parent = grpUSER1 then
fPaths.User1ExeName:=selUSER1exe.FileName
else if ctrl.Parent = grpUSER2 then
fPaths.User2ExeName:=selUSER2exe.FileName;
end;
procedure TCompilersPathsEditor.selectedRt(sender: TObject; var value: string);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdRuntimePath:=value
else if ctrl.Parent = grpGDC then
fPaths.GDCRuntimePath:=value
else if ctrl.Parent = grpLDC then
fPaths.LdcRuntimePath:=value
else if ctrl.Parent = grpUSER1 then
fPaths.User1RuntimePath:=value
else if ctrl.Parent = grpUSER2 then
fPaths.User2RuntimePath:=value;
end;
procedure TCompilersPathsEditor.editedRt(sender: TObject);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdRuntimePath:=selDMDrt.Directory
else if ctrl.Parent = grpGDC then
fPaths.GDCRuntimePath:=selGDCrt.Directory
else if ctrl.Parent = grpLDC then
fPaths.LdcRuntimePath:=selLDCrt.Directory
else if ctrl.Parent = grpUSER1 then
fPaths.User1RuntimePath:=selUSER1rt.Directory
else if ctrl.Parent = grpUSER2 then
fPaths.User2RuntimePath:=selUSER2rt.Directory;
end;
procedure TCompilersPathsEditor.selectedStd(sender: TObject; var value: string);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdPhobosPath:=value
else if ctrl.Parent = grpGDC then
fPaths.GDCPhobosPath:=value
else if ctrl.Parent = grpLDC then
fPaths.LdcPhobosPath:=value
else if ctrl.Parent = grpUSER1 then
fPaths.User1PhobosPath:=value
else if ctrl.Parent = grpUSER2 then
fPaths.User2PhobosPath:=value;
end;
procedure TCompilersPathsEditor.editedStd(sender: TObject);
var
ctrl: TWinControl;
begin
ctrl := TWinControl(sender);
if ctrl.Parent = grpDMD then
fPaths.DmdPhobosPath:=selDMDstd.Directory
else if ctrl.Parent = grpGDC then
fPaths.GDCPhobosPath:=selGDCstd.Directory
else if ctrl.Parent = grpLDC then
fPaths.LdcPhobosPath:=selLDCstd.Directory
else if ctrl.Parent = grpUSER1 then
fPaths.User1PhobosPath:=selUSER1std.Directory
else if ctrl.Parent = grpUSER2 then
fPaths.User2PhobosPath:=selUSER2std.Directory;
end;
procedure TCompilersPathsEditor.selectedDefault(sender: TObject);
begin
fPaths.pathsForCompletion:= DCompiler(selDefault.ItemIndex);
end;
procedure TCompilersPathsEditor.selectedGlobal(sender: TObject);
var
v: DCompiler;
begin
v := DCompiler(selGlobal.ItemIndex);
if v = DCompiler.global then
v := DCompiler.dmd;
fPaths.definedAsGlobal := v;
end;
procedure TCompilersPathsEditor.autoDetectDMD;
{$IFDEF WINDOWS}
var
path: string;
{$ENDIF}
begin
{$IFDEF WINDOWS}
path := exeFullName('dmd' + exeExt);
if path.fileExists then
begin
fPaths.DmdExeName:= path;
path := path.extractFileDir.extractFileDir.extractFileDir;
if (path + '\src\druntime\import').dirExists then
fPaths.DmdRuntimePath := path + '\src\druntime\import';
if (path + '\src\phobos').dirExists then
fPaths.DmdPhobosPath := path + '\src\phobos';
end;
{$ENDIF}
{$IFDEF LINUX}
if '/usr/bin/dmd'.fileExists then
fPaths.DmdExeName:='/usr/bin/dmd';
if '/usr/include/dmd/druntime/import'.dirExists then
fPaths.DmdRuntimePath:='/usr/include/dmd/druntime/import';
if '/usr/include/dmd/phobos'.dirExists then
fPaths.DmdPhobosPath:='/usr/include/dmd/phobos';
{$ENDIF}
{$IFDEF BSD}
if '%%LOCALBASE%%/bin/dmd'.fileExists then
fPaths.DmdExeName:='%%LOCALBASE%%/bin/dmd';
if '%%LOCALBASE%%/include/dmd/druntime/import'.dirExists then
fPaths.DmdRuntimePath:='%%LOCALBASE%%/include/dmd/druntime/import';
if '%%LOCALBASE%%/include/dmd/phobos'.dirExists then
fPaths.DmdPhobosPath:='%%LOCALBASE%%/include/dmd/phobos';
{$ENDIF}
{$IFDEF DARWIN}
if '/usr/local/bin/dmd'.fileExists then
fPaths.DmdExeName:='/usr/local/bin/dmd';
if '/Library/D/dmd/src/druntime/import'.dirExists then
fPaths.DmdRuntimePath:='/Library/D/dmd/src/druntime/import';
if '/Library/D/dmd/src/phobos'.dirExists then
fPaths.DmdPhobosPath:='/Library/D/dmd/src/phobos';
{$ENDIF}
end;
procedure TCompilersPathsEditor.autoDetectGDC;
begin
{$IFDEF LINUX}
if '/usr/bin/gdc'.fileExists then
fPaths.GdcExeName:='/usr/bin/dmd';
// redhat
if '/usr/lib/gcc/x86_64-redhat-linux/9/include/d'.dirExists then
fPaths.GdcRuntimePath:='/usr/lib/gcc/x86_64-redhat-linux/9/include/d'
else if '/usr/lib/gcc/x86_64-redhat-linux/10/include/d'.dirExists then
fPaths.GdcRuntimePath:='/usr/lib/gcc/x86_64-redhat-linux/10/include/d'
// debian
else if '/usr/lib/gcc/x86_64-linux-gnu/9/include/d'.dirExists then
fPaths.GdcRuntimePath:='/usr/lib/gcc/x86_64-linux-gnu/9/include/d'
else if '/usr/lib/gcc/x86_64-linux-gnu/10/include/d'.dirExists then
fPaths.GdcRuntimePath:='/usr/lib/gcc/x86_64-linux-gnu/10/include/d'
// arch
else if 'usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/d'.dirExists then
fPaths.GdcRuntimePath:='usr/lib/gcc/x86_64-pc-linux-gnu/9.2.0/include/d';
{$ENDIF}
end;
procedure TCompilersPathsEditor.autoDetectLDC;
var
i: integer;
path: string;
str: TStringList;
begin
path := exeFullName('ldc2' + exeExt);
if path.fileExists then
begin
fPaths.LdcExeName:= path;
str := TStringList.Create;
try
path := path.extractFileDir.extractFilePath;
FindAllDirectories(str, path, true);
for path in str do
begin
i := pos('import' + DirectorySeparator + 'ldc', path);
if i > 0 then
begin
fPaths.LdcRuntimePath:= path[1..i + 5];
break;
end;
end;
finally
str.Free;
end;
end;
end;
{$ENDREGION}
initialization
CompilersPathsEditor := TCompilersPathsEditor.create(nil);
finalization
CompilersPathsEditor.free;
end.