#99, Add option category to edit compilers paths

todo: GDC/LDC detection + warns + polish + test
This commit is contained in:
Basile Burg 2016-11-06 19:43:01 +01:00
parent 1d4c64da23
commit 045ec6d42c
No known key found for this signature in database
GPG Key ID: 1868039F415CB8CF
10 changed files with 1025 additions and 163 deletions

View File

@ -244,7 +244,7 @@
<PackageName Value="LCL"/>
</Item7>
</RequiredPackages>
<Units Count="54">
<Units Count="55">
<Unit0>
<Filename Value="coedit.lpr"/>
<IsPartOfProject Value="True"/>
@ -522,6 +522,12 @@
<Filename Value="..\src\ce_ddemangle.pas"/>
<IsPartOfProject Value="True"/>
</Unit53>
<Unit54>
<Filename Value="..\src\ce_compilers.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="Form1"/>
<ResourceBaseClass Value="Form"/>
</Unit54>
</Units>
</ProjectOptions>
<CompilerOptions>

View File

@ -8,11 +8,11 @@ uses
{$ENDIF}{$ENDIF}
Interfaces, Forms, lazcontrols, runtimetypeinfocontrols, anchordockpkg,
ce_sharedres, ce_observer, ce_libman, ce_symstring, ce_tools, ce_dcd, ce_main,
ce_writableComponent, ce_staticmacro, ce_inspectors, ce_editoroptions,
ce_dockoptions, ce_shortcutseditor, ce_mru, ce_processes, ce_dubproject,
ce_writableComponent, ce_staticmacro, ce_inspectors, ce_editoroptions, ce_compilers,
ce_dockoptions, ce_shortcutseditor, ce_mru, ce_processes,
ce_dialogs, ce_dubprojeditor, ce_controls, ce_dfmt, ce_lcldragdrop,
ce_stringrange, ce_dlangmaps, ce_projgroup, ce_projutils, ce_d2synpresets,
ce_dastworx, ce_dbgitf, ce_ddemangle;
ce_dastworx, ce_dbgitf, ce_ddemangle, ce_dubproject;
{$R *.res}

View File

@ -132,8 +132,8 @@ type
// native project have no ext constraint, this function tells if filename is project
function isValidNativeProject(const filename: string): boolean;
function getCEProjectCompiler: TCECompiler;
procedure setCEProjectCompiler(value: TCECompiler);
function getCEProjectCompiler: DCompiler;
procedure setCEProjectCompiler(value: DCompiler);
implementation
@ -142,7 +142,7 @@ uses
var
CEProjectCompilerFilename: string = 'dmd';
CEProjectCompiler: TCECompiler;
CEProjectCompiler: DCompiler;
constructor TCENativeProject.create(aOwner: TComponent);
begin
@ -788,7 +788,7 @@ begin
fCompilProc.OnTerminate:= @compProcTerminated;
getOpts(fCompilProc.Parameters);
//getUpToDateObjects(fCompilProc.Parameters);
if CEProjectCompiler = TCECompiler.gdc then
if CEProjectCompiler = gdc then
fCompilProc.Parameters.Add('-gdc=gdc');
fCompilProc.Execute;
end;
@ -1074,28 +1074,23 @@ begin
end;
end;
function getCEProjectCompiler: TCECompiler;
function getCEProjectCompiler: DCompiler;
begin
exit(CEProjectCompiler);
end;
procedure setCEProjectCompiler(value: TCECompiler);
procedure setCEProjectCompiler(value: DCompiler);
var
sel: ICECompilerSelector;
begin
case value of
TCECompiler.dmd: CEProjectCompilerFilename := exeFullName('dmd' + exeExt);
TCECompiler.gdc: CEProjectCompilerFilename := exeFullName('gdmd' + exeExt);
TCECompiler.ldc: CEProjectCompilerFilename := exeFullName('ldmd2' + exeExt);
end;
if (not CEProjectCompilerFilename.fileExists)
or CEProjectCompilerFilename.isEmpty then
begin
value := TCECompiler.dmd;
CEProjectCompilerFilename:= 'dmd' + exeExt;
end;
sel := getCompilerSelector;
CEProjectCompiler := value;
if not sel.isCompilerValid(CEProjectCompiler) then
CEProjectCompiler := dmd;
CEProjectCompilerFilename:=sel.getCompilerPath(CEProjectCompiler);
end;
initialization
setCEProjectCompiler(TCECompiler.dmd);
setCEProjectCompiler(dmd);
RegisterClasses([TCENativeProject]);
end.

View File

@ -29,8 +29,6 @@ type
THasMain = (mainNo, mainYes, mainDefaultBehavior);
TCECompiler = (dmd, gdc, ldc);
// function used as string hasher in fcl-stl
TStringHash = class
class function hash(const key: string; maxBucketsPow2: longword): longword;

484
src/ce_compilers.lfm Normal file
View File

@ -0,0 +1,484 @@
object Form1: TForm1
Left = 749
Height = 869
Top = 128
Width = 473
Caption = 'Form1'
ClientHeight = 869
ClientWidth = 473
LCLVersion = '1.6.0.4'
object ScrollBox1: TScrollBox
Left = 0
Height = 869
Top = 0
Width = 473
HorzScrollBar.Page = 111
VertScrollBar.Page = 864
Align = alClient
ClientHeight = 865
ClientWidth = 469
TabOrder = 0
object grpDMD: TGroupBox
Left = 0
Height = 160
Top = 64
Width = 469
Align = alTop
Caption = 'DMD'
ClientHeight = 130
ClientWidth = 465
TabOrder = 0
object selDMDexe: TFileNameEdit
Left = 2
Height = 20
Hint = 'select the compiler'
Top = 19
Width = 461
FilterIndex = 0
HideDirectories = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
end
object selDMDrt: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of druntime sources'
Top = 60
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
end
object selDMDstd: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of phobos sources'
Top = 101
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 2
end
object StaticText1: TStaticText
Left = 0
Height = 17
Top = 0
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'compiler'
TabOrder = 3
end
object StaticText2: TStaticText
Left = 0
Height = 17
Top = 41
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Runtime sources'
TabOrder = 4
end
object StaticText3: TStaticText
Left = 0
Height = 17
Top = 82
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Phobos sources'
TabOrder = 5
end
end
object grpGDC: TGroupBox
Left = 0
Height = 160
Top = 224
Width = 469
Align = alTop
Caption = 'GDC'
ClientHeight = 130
ClientWidth = 465
TabOrder = 1
object selGDCexe: TFileNameEdit
Left = 2
Height = 20
Hint = 'select the compiler'
Top = 19
Width = 461
FilterIndex = 0
HideDirectories = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
end
object selGDCrt: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of LDC runtime & phobos sources (can be a common folder)'
Top = 60
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
end
object selGDCstd: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of LDC runtime & phobos sources (can be a common folder)'
Top = 101
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 2
end
object StaticText4: TStaticText
Left = 0
Height = 17
Top = 0
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'compiler'
TabOrder = 3
end
object StaticText5: TStaticText
Left = 0
Height = 17
Top = 41
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Runtime sources'
TabOrder = 4
end
object StaticText6: TStaticText
Left = 0
Height = 17
Top = 82
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Phobos sources'
TabOrder = 5
end
end
object grpLDC: TGroupBox
Left = 0
Height = 160
Top = 384
Width = 469
Align = alTop
Caption = 'LDC'
ClientHeight = 130
ClientWidth = 465
TabOrder = 2
object selLDCexe: TFileNameEdit
Left = 2
Height = 20
Hint = 'select the compiler'
Top = 19
Width = 461
FilterIndex = 0
HideDirectories = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
end
object selLDCrt: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of druntime sources'
Top = 60
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
end
object selLDCstd: TDirectoryEdit
Left = 2
Height = 20
Hint = 'select the root of phobos sources'
Top = 101
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 2
end
object StaticText7: TStaticText
Left = 0
Height = 17
Top = 0
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'compiler'
TabOrder = 3
end
object StaticText8: TStaticText
Left = 0
Height = 17
Top = 41
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Runtime sources'
TabOrder = 4
end
object StaticText9: TStaticText
Left = 0
Height = 17
Top = 82
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Phobos sources'
TabOrder = 5
end
end
object grpUSER1: TGroupBox
Left = 0
Height = 160
Top = 544
Width = 469
Align = alTop
Caption = 'User 1'
ClientHeight = 130
ClientWidth = 465
TabOrder = 3
object selUSER1exe: TFileNameEdit
Left = 2
Height = 20
Top = 19
Width = 461
FilterIndex = 0
HideDirectories = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
end
object selUSER1rt: TDirectoryEdit
Left = 2
Height = 20
Top = 60
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
end
object selUSER1std: TDirectoryEdit
Left = 2
Height = 20
Top = 101
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 2
end
object StaticText10: TStaticText
Left = 0
Height = 17
Top = 0
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'compiler'
TabOrder = 3
end
object StaticText11: TStaticText
Left = 0
Height = 17
Top = 41
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Runtime sources'
TabOrder = 4
end
object StaticText12: TStaticText
Left = 0
Height = 17
Top = 82
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Phobos sources'
TabOrder = 5
end
end
object grpUSER2: TGroupBox
Left = 0
Height = 160
Top = 704
Width = 469
Align = alTop
Caption = 'User 2'
ClientHeight = 130
ClientWidth = 465
TabOrder = 4
object selUSER2exe: TFileNameEdit
Left = 2
Height = 20
Top = 19
Width = 461
FilterIndex = 0
HideDirectories = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 0
end
object selUSER2rt: TDirectoryEdit
Left = 2
Height = 20
Top = 60
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 1
end
object selUSER2std: TDirectoryEdit
Left = 2
Height = 20
Top = 101
Width = 461
ShowHidden = False
ButtonWidth = 23
NumGlyphs = 1
Flat = True
Align = alTop
BorderSpacing.Around = 2
MaxLength = 0
TabOrder = 2
end
object StaticText13: TStaticText
Left = 0
Height = 17
Top = 0
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'compiler'
TabOrder = 3
end
object StaticText14: TStaticText
Left = 0
Height = 17
Top = 41
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Runtime sources'
TabOrder = 4
end
object StaticText15: TStaticText
Left = 0
Height = 17
Top = 82
Width = 465
Align = alTop
Alignment = taCenter
Caption = 'Phobos sources'
TabOrder = 5
end
end
object GroupBox6: TGroupBox
Left = 0
Height = 64
Top = 0
Width = 469
Align = alTop
Caption = 'Default compiler'
ClientHeight = 34
ClientWidth = 465
TabOrder = 5
object selDefault: TComboBox
Left = 2
Height = 30
Top = 2
Width = 461
Align = alClient
BorderSpacing.Around = 2
ItemHeight = 0
ItemIndex = 0
Items.Strings = (
'DMD'
'GDC'
'GDMD'
'LDC'
'LDMD'
'USER 1'
'USER 2'
)
Style = csDropDownList
TabOrder = 0
Text = 'DMD'
end
end
end
end

446
src/ce_compilers.pas Normal file
View File

@ -0,0 +1,446 @@
unit ce_compilers;
{$I ce_defines.inc}
interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, EditBtn,
StdCtrls,
ce_dcd, ce_common, ce_interfaces, ce_observer, ce_writableComponent,
ce_dialogs;
type
//TODO-cCompilerPaths: add a way to relaunch DCD after compiler change
TCompilersPaths = class(TWritableLfmTextComponent)
strict private
fDefaultCompiler: 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;
published
property defaultCompiler: DCompiler read fDefaultCompiler write fDefaultCompiler;
property DmdExeName: string read fDmdExeName write fDmdExeName;
property DmdRuntimePath: string read fDmdRuntimePath write fDmdRuntimePath;
property DmdPhobosPath: string read fDmdPhobosPath write fDmdPhobosPath;
property GdcExeName: string read fGdcExeName write fGdcExeName;
property GdcRuntimePath: string read fGdcRuntimePath write fGdcRuntimePath;
property GdcPhobosPath: string read fGdcPhobosPath write fGdcPhobosPath;
property LdcExeName: string read fLdcExeName write fLdcExeName;
property LdcRuntimePath: string read fLdcRuntimePath write fLdcRuntimePath;
property LdcPhobosPath: string read fLdcPhobosPath write fLdcPhobosPath;
property User1ExeName: string read fUser1ExeName write fUser1ExeName;
property User1RuntimePath: string read fUser1RuntimePath write fUser1RuntimePath;
property User1PhobosPath: string read fUser1PhobosPath write fUser1PhobosPath;
property User2ExeName: string read fUser2ExeName write fUser2ExeName;
property User2RuntimePath: string read fUser2RuntimePath write fUser2RuntimePath;
property User2PhobosPath: string read fUser2PhobosPath write fUser2PhobosPath;
public
procedure assign(source: TPersistent); override;
end;
TForm1 = class(TForm, ICEEditableOptions, ICECompilerSelector)
selDefault: 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;
strict private
fPaths: TCompilersPaths;
fPathsBackup: TCompilersPaths;
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 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);
public
constructor create(aOwner: TComponent); override;
destructor destroy; override;
end;
implementation
{$R *.lfm}
var
Form1: TForm1;
const
optFname = 'compilerspaths.txt';
{$REGION Standard Object/COmponents things -------------------------------------}
constructor TForm1.create(aOwner: TComponent);
var
fname: string;
imprt: TStringList;
begin
inherited;
fPaths:= TCompilersPaths.Create(self);
fPathsBackup:= TCompilersPaths.Create(self);
fname := getCoeditDocPath + optFname;
if fname.fileExists then
fPaths.loadFromFile(fname)
else
begin
autoDetectDMD;
autoDetectGDC;
autoDetectLDC;
end;
fPathsBackup.Assign(fPaths);
dataToGui;
imprt := TStringList.Create;
try
getCompilerImports(fPaths.defaultCompiler, imprt);
DcdWrapper.addImportFolders(imprt);
finally
imprt.free;
end;
selDMDexe.OnAcceptFileName:= @selectedExe;
selGDCexe.OnAcceptFileName:= @selectedExe;
selLDCexe.OnAcceptFileName:= @selectedExe;
selUSER1exe.OnAcceptFileName:= @selectedExe;
selUSER2exe.OnAcceptFileName:= @selectedExe;
selDMDrt.OnAcceptDirectory:= @selectedRt;
selGDCrt.OnAcceptDirectory:= @selectedRt;
selLDCrt.OnAcceptDirectory:= @selectedRt;
selUSER1rt.OnAcceptDirectory:= @selectedRt;
selUSER2rt.OnAcceptDirectory:= @selectedRt;
selDMDstd.OnAcceptDirectory:= @selectedStd;
selGDCstd.OnAcceptDirectory:= @selectedStd;
selLDCstd.OnAcceptDirectory:= @selectedStd;
selUSER1std.OnAcceptDirectory:= @selectedStd;
selUSER2std.OnAcceptDirectory:= @selectedStd;
selDefault.OnSelect:= @selectedDefault;
EntitiesConnector.addSingleService(self);
EntitiesConnector.addObserver(self);
end;
destructor TForm1.destroy;
begin
fPaths.saveToFile(getCoeditDocPath + optFname);
EntitiesConnector.removeObserver(self);
inherited;
end;
procedure TCompilersPaths.assign(source: TPersistent);
var
src: TCompilersPaths;
begin
if source is TCompilersPaths then
begin
src := TCompilersPaths(source);
fDefaultCompiler := src.fDefaultCompiler;
fDmdExeName := src.fDmdExeName;
fDmdRuntimePath := src.fDmdRuntimePath;
fDmdPhobosPath := src.fDmdPhobosPath;
fGdcExeName := src.fGdcExeName;
fGdcRuntimePath := src.fGdcRuntimePath;
fGdcPhobosPath := src.fGdcPhobosPath;
fLdcExeName := src.fLdcExeName;
fLdcRuntimePath := src.fLdcRuntimePath;
fLdcPhobosPath := src.fLdcPhobosPath;
fUser1ExeName := src.fUser1ExeName;
fUser1RuntimePath := src.fUser1RuntimePath;
fUser1PhobosPath := src.fUser1PhobosPath;
fUser2ExeName := src.fUser2ExeName;
fUser2RuntimePath := src.fUser2RuntimePath;
fUser2PhobosPath := src.fUser2PhobosPath;
end
else inherited;
end;
{$ENDREGION}
{$REGION ICEEditableOptions ----------------------------------------------------}
function TForm1.optionedWantCategory(): string;
begin
exit('Compilers paths');
end;
function TForm1.optionedWantEditorKind: TOptionEditorKind;
begin
exit(oekForm);
end;
function TForm1.optionedWantContainer: TPersistent;
begin
fPathsBackup.assign(fPaths);
exit(self);
end;
procedure TForm1.optionedEvent(event: TOptionEditorEvent);
begin
case event of
oeeAccept: fPathsBackup.assign(fPaths);
oeeCancel: fPaths.assign(fPathsBackup);
end;
end;
function TForm1.optionedOptionsModified: boolean;
begin
//TODO-cCompilerPaths: add setters to detect if a TCompilersPaths is modified
exit(false);
end;
{$ENDREGION}
{$REGION ICECompilerSelector ---------------------------------------------------}
function TForm1.singleServiceName: string;
begin
exit('ICECompilerSelector');
end;
function TForm1.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);
end;
end;
function TForm1.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);
end;
end;
procedure TForm1.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;
end;
end;
{$ENDREGION}
{$REGION Compilers paths things ------------------------------------------------}
procedure TForm1.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(defaultCompiler);
end;
end;
procedure TForm1.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 TForm1.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 TForm1.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 TForm1.selectedDefault(sender: TObject);
begin
fPaths.defaultCompiler:= DCompiler(selDefault.ItemIndex);
dlgOkInfo('A restart might be necessary so that DCD caches a different version'
+ 'of the runtime and the standard library.');
end;
procedure TForm1.autoDetectDMD;
{$IFDEF WINDOWS}
var
path: string;
{$ENDIF}
begin
{$IFDEF WINDOWS}
path := exeFullName('dmd' + exeExt);
if path.dirExists then
begin
fPaths.DmdExeName:= path;
path := path.extractFileDir.extractFileDir.extractFileDir;
if (path + '\src\drunime\import').dirExists then
fPaths.DmdRuntimePath := path + '\src\drunime\import';
if (path + '\src\phobos').dirExists then
fPaths.DmdRuntimePath := path + '\src\phobos';
end;
{$ENDIF}
{$IFDEF LINUX}
if '/usr/bin/dmd'.fileExists then
fPaths.DmdExeName:='/usr/bin/dmd';
if '/usr/include/dmd/phobos'.dirExists then
fPaths.DmdPhobosPath:='/usr/include/dmd/phobos';
if '/usr/include/dmd/druntime/import'.dirExists then
fPaths.DmdRuntimePath:='/usr/include/dmd/druntime/import';
{$ENDIF}
{$IFDEF DARWIN}
if '/usr/local/bin/dmd'.fileExists then
fPaths.DmdExeName:='/usr/local/bin/dmd';
if '/Library/D/dmd/src/phobos'.dirExists then
fPaths.DmdPhobosPath:='/Library/D/dmd/src/phobos';
if '/Library/D/dmd/src/druntime/import' then
fPaths.DmdRuntimePath:='/Library/D/dmd/src/druntime/import';
{$ENDIF}
end;
procedure TForm1.autoDetectGDC;
begin
//TODO-cCompilerPaths: detect GDC
end;
procedure TForm1.autoDetectLDC;
begin
//TODO-cCompilerPaths: detect LDC
end;
{$ENDREGION}
initialization
Form1 := TForm1.create(nil);
finalization
Form1.free;
end.

View File

@ -258,7 +258,7 @@ type
destructor destroy; override;
procedure assign(source: TPersistent); override;
procedure getOpts(list: TStrings; base: TOptsGroup = nil); override;
procedure getCompilerSpecificOpts(list: TStrings; base: TOptsGroup = nil; compiler: TCECompiler = TCECompiler.dmd);
procedure getCompilerSpecificOpts(list: TStrings; base: TOptsGroup = nil; compiler: DCompiler = dmd);
end;
(*****************************************************************************
@ -1209,7 +1209,7 @@ begin
end;
procedure TOtherOpts.getCompilerSpecificOpts(list: TStrings; base:
TOptsGroup = nil; compiler: TCECompiler = TCECompiler.dmd);
TOptsGroup = nil; compiler: DCompiler = dmd);
var
i: integer;
str: string;
@ -1218,10 +1218,11 @@ var
begin
if base.isNil then
begin
// TODO-cCompilers paths: add other options to CE proj format for the other comps
case compiler of
TCECompiler.dmd: lst := fDmdOthers;
TCECompiler.ldc: lst := fLdcOthers;
TCECompiler.gdc: lst := fGdcOthers;
dmd: lst := fDmdOthers;
ldc: lst := fLdcOthers;
gdc: lst := fGdcOthers;
end;
for i := 0 to lst.Count-1 do
begin
@ -1236,17 +1237,17 @@ begin
begin
baseopt := TOtherOpts(base);
case compiler of
TCECompiler.dmd:
dmd:
if fDmdOthers.Count = 0 then
lst := baseopt.fDmdOthers
else
lst := fDmdOthers;
TCECompiler.ldc:
ldc:
if fLdcOthers.Count = 0 then
lst := baseopt.fLdcOthers
else
lst := fLdcOthers;
TCECompiler.gdc:
gdc:
if fGdcOthers.Count = 0 then
lst := baseopt.fGdcOthers
else

View File

@ -8,7 +8,7 @@ uses
Classes, SysUtils, xfpjson, xjsonparser, xjsonscanner, process, strutils,
LazFileUtils, RegExpr,
ce_common, ce_interfaces, ce_observer, ce_dialogs, ce_processes,
ce_writableComponent;
ce_writableComponent, ce_compilers;
type
@ -27,12 +27,12 @@ type
fCombined: boolean;
fDepCheck: TDubDependencyCheck;
fOther: string;
fCompiler: TCECompiler;
fCompiler: DCompiler;
procedure setLinkMode(value: TDubLinkMode);
procedure setCompiler(value: TCECompiler);
function getCompiler: TCECompiler;
procedure setCompiler(value: DCompiler);
function getCompiler: DCompiler;
published
property compiler: TCECOmpiler read getCompiler write setCompiler;
property compiler: DCompiler read getCompiler write setCompiler;
property parallel: boolean read fParallel write fParallel;
property forceRebuild: boolean read fForceRebuild write fForceRebuild;
property linkMode: TDubLinkMode read fLinkMode write setLinkMode;
@ -153,11 +153,11 @@ type
// converts a sdl description to json, returns the json
function sdl2json(const filename: string): TJSONObject;
function getDubCompiler: TCECompiler;
procedure setDubCompiler(value: TCECompiler);
function getDubCompiler: DCompiler;
procedure setDubCompiler(value: DCompiler);
var
DubCompiler: TCECompiler = TCECompiler.dmd;
DubCompiler: DCompiler = dmd;
DubCompilerFilename: string = 'dmd';
const
@ -188,13 +188,13 @@ begin
fLinkMode:=value;
end;
procedure TCEDubBuildOptionsBase.setCompiler(value: TCECompiler);
procedure TCEDubBuildOptionsBase.setCompiler(value: DCompiler);
begin
fCompiler := value;
setDubCompiler(fCompiler);
end;
function TCEDubBuildOptionsBase.getCompiler: TCECompiler;
function TCEDubBuildOptionsBase.getCompiler: DCompiler;
begin
result := fCompiler;
end;
@ -1211,29 +1211,25 @@ begin
end;
end;
function getDubCompiler: TCECompiler;
function getDubCompiler: DCompiler;
begin
exit(DubCompiler);
end;
procedure setDubCompiler(value: TCECompiler);
procedure setDubCompiler(value: DCompiler);
var
sel: ICECompilerSelector;
begin
case value of
TCECompiler.dmd: DubCompilerFilename := exeFullName('dmd' + exeExt);
TCECompiler.gdc: DubCompilerFilename := exeFullName('gdc' + exeExt);
TCECompiler.ldc: DubCompilerFilename := exeFullName('ldc2' + exeExt);
end;
if (not DubCompilerFilename.fileExists) or DubCompilerFilename.isEmpty then
begin
value := TCECompiler.dmd;
DubCompilerFilename:= 'dmd' + exeExt;
end;
sel := getCompilerSelector;
DubCompiler := value;
if not sel.isCompilerValid(DubCompiler) then
DubCompiler := dmd;
DubCompilerFilename:=sel.getCompilerPath(DubCompiler);
end;
{$ENDREGION}
initialization
setDubCompiler(TCECompiler.dmd);
setDubCompiler(dmd);
dubBuildOptions:= TCEDubBuildOptions.create(nil);
finalization
dubBuildOptions.free;

View File

@ -7,7 +7,8 @@ interface
uses
Classes, SysUtils, FileUtil, ce_common, ce_writableComponent, LazFileUtils,
ghashmap, ghashset,
ce_dcd, ce_dialogs, ce_projutils, ce_interfaces, ce_dlang, ce_dastworx;
ce_dcd, ce_dialogs, ce_projutils, ce_interfaces, ce_dlang, ce_dastworx,
ce_compilers;
type
@ -314,98 +315,33 @@ end;
constructor TLibraryManager.create(aOwner: TComponent);
var
fName: string;
{$IFDEF WINDOWS}
fDmdPath: string;
{$ENDIF}
nme: string;
als: string;
lib: TLibraryItem;
i: integer;
begin
inherited;
fItemsByAlias := TItemsByAlias.create;
fCollection := TCollection.Create(TLibraryItem);
fCollection.FPOAttachObserver(self);
fname := getCoeditDocPath + libFname;
if fname.fileExists then
loadFromFile(fname);
if fCollection.Count = 0 then
nme := getCoeditDocPath + libFname;
if nme.fileExists then
loadFromFile(nme);
for i := fCollection.Count-1 downto 0 do
begin
{$IFDEF WINDOWS}
fDmdPath := ExeSearch('dmd.exe');
if fDmdPath.fileExists then
lib := libraryByIndex[i];
als := lib.libAlias.upperCase;
// TODO-cmaintenace: from 3 upd 1 remove auto suprerssion of libman entry for phobos and rt.
if (als = 'PHOBOS') or (als = 'RUNTIME') or (als = 'DRUNTIME') then
begin
// add phobos
fname := fDmdPath.ExtractFileDir;
fname := fname.ExtractFileDir;
with TLibraryItem(fCollection.Add) do begin
libAlias := 'phobos';
libFile := fname + '\lib\phobos.lib';
libSourcePath := fname.ExtractFileDir + '\src\phobos';
end;
// add druntime (no lib - only for DCD)
fname := fDmdPath.ExtractFileDir;
fname := fname.ExtractFileDir;
with TLibraryItem(fCollection.Add) do begin
libAlias := 'druntime';
libFile := '';
libSourcePath := fname.ExtractFileDir + '\src\druntime\import';
end;
fCollection.Delete(i);
continue;
end;
{$ENDIF}
{$IFDEF LINUX}
// add phobos
if '/usr/include/dmd/phobos'.dirExists then
begin
with TLibraryItem(fCollection.Add) do begin
libAlias := 'phobos';
libFile := '';
libSourcePath := '/usr/include/dmd/phobos';
end;
end;
// add druntime (no libraryByIndex - only for DCD)
if '/usr/include/dmd/druntime/import'.dirExists then
begin
with TLibraryItem(fCollection.Add) do begin
libAlias := 'druntime';
libFile := '';
libSourcePath := '/usr/include/dmd/druntime/import';
end;
end;
{$ENDIF}
{$IFDEF DARWIN}
if '/Library/D/dmd/src/phobos'.dirExists then
begin
with TLibraryItem(fCol.Add) do begin
libAlias := 'phobos';
libFile := '';
libSourcePath := '/Library/D/dmd/src/phobos';
end;
end;
// add druntime (no lib - only for DCD)
if '/Library/D/dmd/src/druntime/import'.dirExists then
begin
with TLibraryItem(fCol.Add) do begin
libAlias := 'druntime';
libFile := '';
libSourcePath := '/Library/D/dmd/src/druntime/import';
end;
end;
{$ENDIF}
//
lib.updateModulesInfo;
end;
updateItemsByAlias;
if (fCollection.Count = 0) and not (getCoeditDocPath + libFname).fileExists then
begin
dlgOkInfo(
'Coedit failed to add "druntime" and "phobos" to the library manager.'
+ 'If they are not already specified in the DCD configuration then the '
+ 'completion will not work properly');
end;
updateDCD;
//
for i := 0 to fCollection.Count-1 do
begin
if (libraryByIndex[i].libAlias <> 'phobos') and (libraryByIndex[i].libAlias <> 'druntime') then
libraryByIndex[i].updateModulesInfo;
end;
updateCrossDependencies;
end;
@ -697,8 +633,6 @@ begin
for i := 0 to fCollection.Count-1 do
begin
lib := libraryByIndex[i];
if (lib.libAlias = 'phobos') or (lib.libAlias = 'druntime') then
continue;
lib.dependencies.Clear;
for j := 0 to lib.modules.Count-1 do
for m := 0 to lib.moduleByIndex[j].imports.Count-1 do
@ -708,12 +642,12 @@ begin
if lib.hasModule(imp) then
continue;
dep := libraryByImport[imp];
// std / core / etc ...
if dep.isNil then
continue;
// ... this should not happen
if dep = lib then
continue;
// core or std are always handled by sc.ini
if dep.isNil or (dep.libAlias = 'phobos') or (dep.libAlias = 'druntime') then
continue;
// add deps
if lib.dependencies.IndexOf(dep.libAlias) > -1 then
continue;

View File

@ -36,7 +36,7 @@ type
TCERunnableOptions = class(TWritableLfmTextComponent)
private
fCompiler: TCECompiler;
fCompiler: DCompiler;
fDetectMain: boolean;
fDetectLibraries: boolean;
fOutputFolder: TCEPathname;
@ -44,12 +44,12 @@ type
fStaticSwitches: TStringList;
procedure setOutputFolder(const value: TCEPathname);
procedure setStaticSwitches(value: TStringList);
procedure setCompiler(value: TCECompiler);
procedure setCompiler(value: DCompiler);
protected
procedure afterLoad; override;
published
property alwaysToFolder: boolean read fAlwaysToFolder write fAlwaysToFolder;
property compiler: TCECompiler read fCompiler write setCompiler;
property compiler: DCompiler read fCompiler write setCompiler;
property detectMain: boolean read fDetectMain write fDetectMain;
property detectLibraries: boolean read fDetectLibraries write fDetectLibraries;
property outputFolder: TCEPathname read fOutputFolder write setOutputFolder;
@ -378,6 +378,7 @@ type
fMainMenuSubj: TCEMainMenuSubject;
fAppliOpts: TCEApplicationOptions;
fProjActionsLock: boolean;
fCompilerSelector: ICECompilerSelector;
procedure updateMainMenuProviders;
procedure updateFloatingWidgetOnTop(onTop: boolean);
procedure widgetDockingChanged(sender: TCEWidget; newState: TWidgetDockingState);
@ -544,8 +545,8 @@ type
fShowBuildDuration: boolean;
function getAdditionalPATH: string;
procedure setAdditionalPATH(const value: string);
function getNativeProjecCompiler: TCECompiler;
procedure setNativeProjecCompiler(value: TCECompiler);
function getNativeProjecCompiler: DCompiler;
procedure setNativeProjecCompiler(value: DCompiler);
procedure setSplitterScsrollSpeed(value: byte);
published
property additionalPATH: string read getAdditionalPATH write setAdditionalPath;
@ -556,7 +557,7 @@ type
property maxRecentProjects: integer read fMaxRecentProjs write fMaxRecentProjs;
property maxRecentDocuments: integer read fMaxRecentDocs write fMaxRecentDocs;
property maxRecentProjectsGroups: integer read fMaxRecentGroups write fMaxRecentGroups;
property nativeProjectCompiler: TCECompiler read getNativeProjecCompiler write setNativeProjecCompiler;
property nativeProjectCompiler: DCompiler read getNativeProjecCompiler write setNativeProjecCompiler;
property dscanUnittests: boolean read fDscanUnittests write fDscanUnittests default true;
property autoSaveProjectFiles: boolean read fAutoSaveProjectFiles write fAutoSaveProjectFiles default false;
property flatLook: boolean read fFlatLook write fFlatLook;
@ -690,14 +691,13 @@ begin
fOutputFolder += DirectorySeparator;
end;
procedure TCERunnableOptions.setCompiler(value: TCECompiler);
procedure TCERunnableOptions.setCompiler(value: DCompiler);
begin
case value of
TCECompiler.ldc: if not exeInSysPath('ldmd2' + exeExt) then
value := TCECompiler.dmd;
TCECompiler.gdc: if not exeInSysPath('gdmd' + exeExt) then
value := TCECompiler.dmd;
end;
if fCompiler = value then
exit;
fCompiler := value;
if not getCompilerSelector.isCompilerValid(fCompiler) then
fCompiler := dmd;
fCompiler :=value;
end;
@ -764,12 +764,12 @@ begin
fFlatLook:=true;
end;
function TCEApplicationOptionsBase.getNativeProjecCompiler: TCECompiler;
function TCEApplicationOptionsBase.getNativeProjecCompiler: DCompiler;
begin
exit(ce_ceproject.getCEProjectCompiler);
end;
procedure TCEApplicationOptionsBase.setNativeProjecCompiler(value: TCECompiler);
procedure TCEApplicationOptionsBase.setNativeProjecCompiler(value: DCompiler);
begin
ce_ceproject.setCEProjectCompiler(value);
end;
@ -1138,6 +1138,7 @@ begin
EntitiesConnector.forceUpdate;
fSymStringExpander:= getSymStringExpander;
fProjectGroup := getProjectGroup;
fCompilerSelector := getCompilerSelector;
getCMdParams;
fAppliOpts.assignTo(self);
@ -2604,9 +2605,11 @@ begin
dmdproc.OnTerminate:= @asyncprocTerminate;
dmdproc.Options := [poUsePipes, poStderrToOutPut];
case fRunnablesOptions.compiler of
TCECompiler.dmd: dmdProc.Executable :='dmd' + exeExt;
TCECompiler.ldc: dmdProc.Executable :='ldmd2' + exeExt;
TCECompiler.gdc: dmdProc.Executable :='gdmd' + exeExt;
dmd: dmdProc.Executable := fCompilerSelector.getCompilerPath(dmd);
gdc, gdmd: dmdProc.Executable := fCompilerSelector.getCompilerPath(gdmd);
ldc, ldmd: dmdProc.Executable := fCompilerSelector.getCompilerPath(ldmd);
user1: fCompilerSelector.getCompilerPath(user1);
user2: fCompilerSelector.getCompilerPath(user2);
end;
dmdproc.Parameters.Add(fDoc.fileName);
if not asObj then
@ -2883,10 +2886,9 @@ begin
fRunProc.Options := fRunProc.Options + [poNewConsole];
{$ENDIF}
end;
case fRunnablesOptions.compiler of
TCECompiler.gdc: fRunProc.Parameters.add('--compiler=gdc');
TCECompiler.ldc: fRunProc.Parameters.add('--compiler=ldc2');
end;
if fRunnablesOptions.compiler <> dmd then
fRunProc.Parameters.add('--compiler=' +
fCompilerSelector.getCompilerPath(fRunnablesOptions.compiler));
fRunProc.execute;
end;