add main option for #77 + mostly drafted the feature

This commit is contained in:
Basile Burg 2016-06-28 09:39:51 +02:00
parent e674c89a96
commit 1b5076f959
3 changed files with 109 additions and 58 deletions

View File

@ -10,6 +10,8 @@ uses
type type
// TODO-clibman: improve import analysis, caching, hashmap, backup, update.
(** (**
* Information for a module in a library manager entry * Information for a module in a library manager entry
*) *)
@ -17,16 +19,12 @@ type
private private
fName: string; fName: string;
fImports: TStringList; fImports: TStringList;
fDeps: TstringList;
procedure setImports(value: TStringList); procedure setImports(value: TStringList);
procedure setDependencies(value: TStringList);
published published
// the.module.name // the.module.name
property name: string read fName write fname; property name: string read fName write fname;
// all the imports in this module // all the imports in this module
property imports: TStringList read fImports write setImports; property imports: TStringList read fImports write setImports;
// the aliases to the libraries used by this module.
property dependencies: TStringList read fDeps write setDependencies;
public public
constructor Create(ACollection: TCollection); override; constructor Create(ACollection: TCollection); override;
destructor Destroy; override; destructor Destroy; override;
@ -44,8 +42,10 @@ type
fLibFile: string; fLibFile: string;
fProjFile: string; fProjFile: string;
fEnabled: boolean; fEnabled: boolean;
fModules: TOwnedCollection; fDependencies: TStringList;
procedure setModules(value: TOwnedCollection); fModules: TCollection;
procedure setDependencies(value: TStringList);
procedure setModules(value: TCollection);
function getModuleInfo(ix: integer): TModuleInfo; function getModuleInfo(ix: integer): TModuleInfo;
published published
property libAlias: string read fAlias write fAlias; property libAlias: string read fAlias write fAlias;
@ -53,14 +53,16 @@ type
property libFile: string read fLibFile write fLibFile; property libFile: string read fLibFile write fLibFile;
property projectFile: string read fProjFile write fProjFile; property projectFile: string read fProjFile write fProjFile;
property enabled: boolean read fEnabled write fEnabled default true; property enabled: boolean read fEnabled write fEnabled default true;
// TODO-creminder: dont forget that this prop is not written // TODO-clibman: dont forget that these props are not written
property modules: TOwnedCollection read fModules write setModules stored false; property dependencies: TStringList read fDependencies write setDependencies stored false;
property modules: TCollection read fModules write setModules stored false;
public public
constructor Create(ACollection: TCollection); override; constructor Create(ACollection: TCollection); override;
destructor Destroy; override;
procedure updateModulesInfo; procedure updateModulesInfo;
procedure updateModulesDependencies;
function addModuleInfo: TModuleInfo; function addModuleInfo: TModuleInfo;
function hasModule(const value: string): boolean; function hasModule(const value: string): boolean;
property moduleInfos[ix: integer]: TModuleInfo read getModuleInfo;
end; end;
(** (**
@ -69,32 +71,34 @@ type
TLibraryManager = class(TWritableLfmTextComponent) TLibraryManager = class(TWritableLfmTextComponent)
private private
fCol: TCollection; fCol: TCollection;
function getLibrary(index: integer): TLibraryItem; function getItems(index: integer): TLibraryItem;
procedure setCol(value: TCollection); procedure setCol(value: TCollection);
published published
property libraries: TCollection read fCol write setCol; property libraries: TCollection read fCol write setCol;
public public
constructor create(aOwner: TComponent); override; constructor create(aOwner: TComponent); override;
destructor destroy; override; destructor destroy; override;
//
(** (**
* the caller gets all the *.lib/*.a files in aList if someAliases is nil * The caller gets all the static library files in list if aliases is nil
* otherwise the static libs selected by the aliases in someAliases. * otherwise the static library files selected by the aliases.
*) *)
procedure getLibFiles(someAliases, aList: TStrings); procedure getLibFiles(aliases, list: TStrings);
(** (**
* the caller gets all the paths were are located the lib sources in aList if someAliases is nil * The caller gets all the paths were are located the library sources in list
* otherwise the paths where are located the lib sources selected by the aliases in someAliases. * if aliases is nil otherwise the paths where are located the sources of the
* livraries selected by aliases.
*) *)
procedure getLibSources(someAliases, aList: TStrings); procedure getLibSources(aliases, list: TStrings);
(** (**
* The caller gets all the static library files and their source root * The caller gets all the static library files and the source path
* that are required by the specified source code. * that are required by the specified source code.
*) *)
procedure getLibsForSource(source, libs, paths: TStrings); procedure getLibsForSource(source, libs, paths: TStrings);
// //
procedure updateDCD; procedure updateDCD;
property lib[index: integer]: TLibraryItem read getLibrary; default; // find the aliases of the libraries used by this library.
procedure updateCrossDependencies;
property items[index: integer]: TLibraryItem read getItems; default;
end; end;
const const
@ -109,13 +113,11 @@ constructor TModuleInfo.Create(ACollection: TCollection);
begin begin
inherited create(ACollection); inherited create(ACollection);
fImports := TStringList.Create; fImports := TStringList.Create;
fDeps := TstringList.Create;
end; end;
destructor TModuleInfo.Destroy; destructor TModuleInfo.Destroy;
begin begin
fImports.free; fImports.free;
fDeps.Free;
inherited; inherited;
end; end;
@ -124,18 +126,21 @@ begin
fImports.Assign(value); fImports.Assign(value);
end; end;
procedure TModuleInfo.setDependencies(value: TStringList);
begin
fDeps.Assign(value);
end;
constructor TLibraryItem.Create(ACollection: TCollection); constructor TLibraryItem.Create(ACollection: TCollection);
begin begin
inherited create(ACollection); inherited create(ACollection);
fModules := TOwnedCollection.Create(self, TModuleInfo); fModules := TCollection.Create(TModuleInfo);
fDependencies := TStringList.Create;
fEnabled:=true; fEnabled:=true;
end; end;
destructor TLibraryItem.Destroy;
begin
fDependencies.Free;
fModules.Free;
inherited;
end;
function TLibraryItem.getModuleInfo(ix: integer): TModuleInfo; function TLibraryItem.getModuleInfo(ix: integer): TModuleInfo;
begin begin
exit(TModuleInfo(fModules.Items[ix])); exit(TModuleInfo(fModules.Items[ix]));
@ -156,11 +161,16 @@ begin
exit(false); exit(false);
end; end;
procedure TLibraryItem.setModules(value: TOwnedCollection); procedure TLibraryItem.setModules(value: TCollection);
begin begin
fModules.Assign(value); fModules.Assign(value);
end; end;
procedure TLibraryItem.setDependencies(value: TStringList);
begin
fDependencies.Assign(value);
end;
procedure TLibraryItem.updateModulesInfo; procedure TLibraryItem.updateModulesInfo;
var var
prj: ICECommonProject; prj: ICECommonProject;
@ -223,11 +233,6 @@ begin
end; end;
end; end;
procedure TLibraryItem.updateModulesDependencies;
begin
end;
constructor TLibraryManager.create(aOwner: TComponent); constructor TLibraryManager.create(aOwner: TComponent);
var var
fName: string; fName: string;
@ -275,7 +280,7 @@ begin
libSourcePath := '/usr/include/dmd/phobos'; libSourcePath := '/usr/include/dmd/phobos';
end; end;
end; end;
// add druntime (no lib - only for DCD) // add druntime (no items - only for DCD)
if '/usr/include/dmd/druntime/import'.dirExists then if '/usr/include/dmd/druntime/import'.dirExists then
begin begin
with TLibraryItem(fCol.Add) do begin with TLibraryItem(fCol.Add) do begin
@ -314,10 +319,12 @@ begin
end; end;
updateDCD; updateDCD;
// //
for i := 2 to fCol.Count-1 do for i := 0 to fCol.Count-1 do
begin begin
TLibraryItem(fCol.Items[i]).updateModulesInfo; if (items[i].libAlias <> 'phobos') and (items[i].libAlias <> 'druntime') then
items[i].updateModulesInfo;
end; end;
updateCrossDependencies;
end; end;
destructor TLibraryManager.destroy; destructor TLibraryManager.destroy;
@ -333,7 +340,7 @@ begin
fCol.assign(value); fCol.assign(value);
end; end;
function TLibraryManager.getLibrary(index: integer): TLibraryItem; function TLibraryManager.getItems(index: integer): TLibraryItem;
begin begin
exit(TLibraryItem(fCol.Items[index])); exit(TLibraryItem(fCol.Items[index]));
end; end;
@ -360,7 +367,7 @@ begin
end; end;
end; end;
procedure TLibraryManager.getLibFiles(someAliases, aList: TStrings); procedure TLibraryManager.getLibFiles(aliases, list: TStrings);
var var
itm: TLibraryItem; itm: TLibraryItem;
lst: TStringList; lst: TStringList;
@ -371,16 +378,16 @@ begin
begin begin
itm := TLibraryItem(fCol.Items[i]); itm := TLibraryItem(fCol.Items[i]);
if (not itm.enabled) or if (not itm.enabled) or
(someAliases.isNotNil and (someAliases.IndexOf(itm.libAlias) = -1)) then (aliases.isNotNil and (aliases.IndexOf(itm.libAlias) = -1)) then
continue; continue;
// single lib files // single items files
if fileExists(itm.libFile) then if fileExists(itm.libFile) then
begin begin
if aList.IndexOf(itm.libFile) <> -1 then if list.IndexOf(itm.libFile) <> -1 then
continue; continue;
aList.Add(itm.libFile); list.Add(itm.libFile);
end end
// folder of lib file // folder of items file
else if itm.libFile.dirExists then else if itm.libFile.dirExists then
begin begin
lst := TStringList.Create; lst := TStringList.Create;
@ -392,8 +399,8 @@ begin
for j:= 0 to lst.Count-1 do for j:= 0 to lst.Count-1 do
begin begin
if lst[j].extractFileExt = libExt then if lst[j].extractFileExt = libExt then
if aList.IndexOf(lst[j]) = -1 then if list.IndexOf(lst[j]) = -1 then
aList.Add(lst[j]); list.Add(lst[j]);
end; end;
finally finally
lst.Free; lst.Free;
@ -402,8 +409,7 @@ begin
end; end;
end; end;
procedure TLibraryManager.getLibSources(aliases, list: TStrings);
procedure TLibraryManager.getLibSources(someAliases, aList: TStrings);
var var
itm: TLibraryItem; itm: TLibraryItem;
i: Integer; i: Integer;
@ -412,14 +418,14 @@ begin
begin begin
itm := TLibraryItem(fCol.Items[i]); itm := TLibraryItem(fCol.Items[i]);
if (not itm.enabled) or if (not itm.enabled) or
(someAliases.isNotNil and (someAliases.IndexOf(itm.libAlias) = -1)) then (aliases.isNotNil and (aliases.IndexOf(itm.libAlias) = -1)) then
continue; continue;
// //
if aList.IndexOf(itm.libSourcePath) <> -1 then if list.IndexOf(itm.libSourcePath) <> -1 then
continue; continue;
if not itm.libSourcePath.dirExists then if not itm.libSourcePath.dirExists then
continue; continue;
aList.Add('-I' + itm.libSourcePath); list.Add('-I' + itm.libSourcePath);
end; end;
end; end;
@ -437,7 +443,7 @@ begin
getImports(tks, imp); getImports(tks, imp);
for i := 0 to fCol.Count-1 do for i := 0 to fCol.Count-1 do
begin begin
itm := lib[i]; itm := items[i];
for j := imp.Count-1 downto 0 do if itm.hasModule(imp[j]) then for j := imp.Count-1 downto 0 do if itm.hasModule(imp[j]) then
begin begin
imp.Delete(j); imp.Delete(j);
@ -445,6 +451,11 @@ begin
continue; continue;
libs.Add(itm.libFile); libs.Add(itm.libFile);
paths.Add('-I'+itm.libSourcePath); paths.Add('-I'+itm.libSourcePath);
if itm.dependencies.Count > 0 then
begin
getLibFiles(itm.dependencies, libs);
getLibSources(itm.dependencies, paths);
end;
end; end;
end; end;
finally finally
@ -453,6 +464,34 @@ begin
end; end;
end; end;
procedure TLibraryManager.updateCrossDependencies;
var
i, j, k, m: integer;
begin
for i := 0 to fCol.Count-1 do
begin
if (items[i].libAlias = 'phobos') or (items[i].libAlias = 'druntime') then
continue;
items[i].dependencies.Clear;
for j := 0 to items[i].modules.Count-1 do
for m := 0 to items[i].moduleInfos[j].imports.Count-1 do
begin
for k := 0 to fCol.Count-1 do
begin
if k = i then
continue;
if (items[k].libAlias = 'phobos') or (items[k].libAlias = 'druntime') then
continue;
if items[k].hasModule(items[i].moduleInfos[j].imports[m]) then
begin
items[i].dependencies.Add(items[k].libAlias);
break;
end;
end;
end;
end;
end;
initialization initialization
registerClasses([TLibraryManager, TLibraryItem]); registerClasses([TLibraryManager, TLibraryItem]);
LibMan := TLibraryManager.create(nil); LibMan := TLibraryManager.create(nil);

View File

@ -486,9 +486,15 @@ begin
if List.Selected.isNil then if List.Selected.isNil then
exit; exit;
al := List.Selected.Caption; al := List.Selected.Caption;
if inputQuery('library alias', '', al) then if (al = 'phobos') or (al = 'druntime') then
begin
dlgOkInfo('phobos and druntime cannot be renamed');
end else
begin
if inputQuery('library alias', '', al) then
List.Selected.Caption := al; List.Selected.Caption := al;
RowToLibrary(List.Selected); RowToLibrary(List.Selected);
end;
end; end;
procedure TCELibManEditorWidget.btnEnabledClick(Sender: TObject); procedure TCELibManEditorWidget.btnEnabledClick(Sender: TObject);
@ -732,8 +738,10 @@ begin
itm.libSourcePath := row.SubItems[1]; itm.libSourcePath := row.SubItems[1];
itm.projectFile := row.SubItems[2]; itm.projectFile := row.SubItems[2];
itm.enabled := row.SubItems[3] = enableStr[true]; itm.enabled := row.SubItems[3] = enableStr[true];
itm.updateModulesInfo;
LibMan.updateDCD; LibMan.updateDCD;
LibMan.updateCrossDependencies;
end; end;
function sourceRoot(project: ICECommonProject): string; function sourceRoot(project: ICECommonProject): string;

View File

@ -466,6 +466,7 @@ type
fAutoSaveProjectFiles: boolean; fAutoSaveProjectFiles: boolean;
fFlatLook: boolean; fFlatLook: boolean;
fDetectMain: boolean; fDetectMain: boolean;
fDetectRunnableImports: boolean;
function getAdditionalPATH: string; function getAdditionalPATH: string;
procedure setAdditionalPATH(const value: string); procedure setAdditionalPATH(const value: string);
function getDubCompiler: TCECompiler; function getDubCompiler: TCECompiler;
@ -492,6 +493,7 @@ type
property autoSaveProjectFiles: boolean read fAutoSaveProjectFiles write fAutoSaveProjectFiles default false; property autoSaveProjectFiles: boolean read fAutoSaveProjectFiles write fAutoSaveProjectFiles default false;
property flatLook: boolean read fFlatLook write setFlatLook; property flatLook: boolean read fFlatLook write setFlatLook;
property detectMain: boolean read fDetectMain write fDetectMain; property detectMain: boolean read fDetectMain write fDetectMain;
property detectRunnableImports: boolean read fDetectRunnableImports write fDetectRunnableImports;
// published for ICEEditableOptions but stored by DCD wrapper since it reloads before CEMainForm // published for ICEEditableOptions but stored by DCD wrapper since it reloads before CEMainForm
property dcdPort: word read fDcdPort write fDcdPort stored false; property dcdPort: word read fDcdPort write fDcdPort stored false;
@ -2265,11 +2267,13 @@ begin
end end
else dmdproc.Parameters.Add('-version=runnable_module'); else dmdproc.Parameters.Add('-version=runnable_module');
LibMan.getLibFiles(nil, dmdproc.Parameters); if fAppliOpts.detectRunnableImports then
LibMan.getLibSources(nil, dmdproc.Parameters); LibMan.getLibsForSource(fDoc.Lines, dmdproc.Parameters, dmdproc.Parameters)
else
//LibMan.getLibsForSource(fDoc.Lines, dmdproc.Parameters, dmdproc.Parameters); begin
LibMan.getLibFiles(nil, dmdproc.Parameters);
LibMan.getLibSources(nil, dmdproc.Parameters);
end;
deleteDups(dmdproc.Parameters); deleteDups(dmdproc.Parameters);
dmdproc.Execute; dmdproc.Execute;