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(''); 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.