lazbuild: started package system

git-svn-id: trunk@9793 -
This commit is contained in:
mattias 2006-09-02 20:37:13 +00:00
parent 1eedc104fc
commit 7edbac0155
4 changed files with 183 additions and 61 deletions

View File

@ -11,7 +11,6 @@
</General>
<PublishOptions>
<Version Value="2"/>
<IgnoreBinaries Value="False"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
<ExcludeFileFilter Value="*.(bak|ppu|ppw|o|so);*~;backup"/>
</PublishOptions>

View File

@ -18,6 +18,12 @@
***************************************************************************
Command line utility to compile lazarus projects and packages.
!!! Under construction. !!!
ToDo:
Separate the visual parts in the IDE from the package and build system.
Then use the non visual parts here.
}
program lazbuild;
@ -27,7 +33,8 @@ uses
Classes, SysUtils, CustApp, LCLProc, Forms, Controls, FileUtil,
CodeToolManager,
InitialSetupDlgs, OutputFilter, Compiler,
EnvironmentOpts, IDETranslations, LazarusIDEStrConsts, LazConf, MainIntf;
EnvironmentOpts, IDETranslations, LazarusIDEStrConsts, LazConf, MainIntf,
BasePkgManager, PackageDefs, PackageLinks, PackageSystem;
type
@ -39,17 +46,28 @@ type
fInitResult: boolean;
TheOutputFilter: TOutputFilter;
TheCompiler: TCompiler;
// external tools
procedure OnExtToolFreeOutputFilter(OutputFilter: TOutputFilter;
ErrorOccurred: boolean);
procedure OnExtToolNeedsOutputFilter(var OutputFilter: TOutputFilter;
var Abort: boolean);
// global package functions
procedure GetDependencyOwnerDescription(Dependency: TPkgDependency;
var Description: string);
procedure GetDependencyOwnerDirectory(Dependency: TPkgDependency;
var Directory: string);
procedure GetWritablePkgOutputDirectory(APackage: TLazPackage;
var AnOutDirectory: string);
protected
function BuildFile(Filename: string): boolean;
function BuildPackage(const Filename: string): boolean;
function LoadPackage(const Filename: string): TLazPackage;
function Init: boolean;
procedure LoadEnvironmentOptions;
procedure SetupOutputFilter;
procedure SetupCompilerInterface;
procedure SetupPackageSystem;
public
Files: TStringList;
constructor Create(TheOwner: TComponent); override;
@ -74,6 +92,40 @@ begin
end;
procedure TLazBuildApplication.GetDependencyOwnerDescription(
Dependency: TPkgDependency; var Description: string);
begin
GetDescriptionOfDependencyOwner(Dependency,Description);
end;
procedure TLazBuildApplication.GetDependencyOwnerDirectory(
Dependency: TPkgDependency; var Directory: string);
begin
GetDirectoryOfDependencyOwner(Dependency,Directory);
end;
procedure TLazBuildApplication.GetWritablePkgOutputDirectory(
APackage: TLazPackage; var AnOutDirectory: string);
var
NewOutDir: String;
begin
if DirectoryIsWritableCached(AnOutDirectory) then exit;
ForceDirectory(AnOutDirectory);
InvalidateFileStateCache;
if DirectoryIsWritableCached(AnOutDirectory) then exit;
//debugln('TPkgManager.GetWritablePkgOutputDirectory AnOutDirectory=',AnOutDirectory,' ',dbgs(DirectoryIsWritable(AnOutDirectory)));
// output directory is not writable
// -> redirect to config directory
NewOutDir:=SetDirSeparators('/$(TargetCPU)-$(TargetOS)');
MacroList.SubstituteStr(NewOutDir);
NewOutDir:=TrimFilename(GetPrimaryConfigPath+PathDelim+'lib'+PathDelim
+APackage.Name+NewOutDir);
AnOutDirectory:=NewOutDir;
//debugln('TPkgManager.GetWritablePkgOutputDirectory APackage=',APackage.IDAsString,' AnOutDirectory="',AnOutDirectory,'"');
end;
function TLazBuildApplication.BuildFile(Filename: string): boolean;
begin
Result:=false;
@ -93,6 +145,40 @@ begin
Init;
end;
function TLazBuildApplication.LoadPackage(const Filename: string): TLazPackage;
begin
// check if package is already loaded
Result:=PackageGraph.FindPackageWithFilename(AFilename,true);
if (Result<>nil) then exit;
Result:=TLazPackage.Create;
// load the package file
XMLConfig:=TXMLConfig.Create(AFilename);
try
APackage.Filename:=AFilename;
APackage.LoadFromXMLConfig(XMLConfig,'Package/');
finally
XMLConfig.Free;
end;
// check Package Name
if (Result.Name='') or (not IsValidIdent(Result.Name)) then begin
Error(
Format(lisPkgMangThePackageNameOfTheFileIsInvalid, ['"', Result.Name,
'"', #13, '"', Result.Filename, '"']),
mtError,[mbCancel,mbAbort],0);
end;
// check if Package with same name is already loaded
ConflictPkg:=PackageGraph.FindAPackageWithName(Result.Name,nil);
if ConflictPkg<>nil then begin
// replace package
PackageGraph.ReplacePackage(ConflictPkg,Result);
end else begin
// add to graph
PackageGraph.AddPackage(Result);
end;
// save package file links
PkgLinks.SaveUserLinks;
end;
function TLazBuildApplication.Init: boolean;
var
InteractiveSetup: Boolean;
@ -107,14 +193,10 @@ begin
InteractiveSetup:=false;
SetupCompilerFilename(InteractiveSetup);
SetupLazarusDirectory(InteractiveSetup);
//SetupTransferMacros;
//InitCodeToolBoss;
//PkgBoss:=TPkgManager.Create(nil);
//SetupMacros;
SetupPackageSystem;
SetupOutputFilter;
SetupCompilerInterface;
fInitResult:=true;
end;
@ -152,6 +234,35 @@ begin
end;
end;
procedure TLazBuildApplication.SetupPackageSystem;
begin
OnGetDependencyOwnerDescription:=@GetDependencyOwnerDescription;
OnGetDependencyOwnerDirectory:=@GetDependencyOwnerDirectory;
OnGetWritablePkgOutputDirectory:=@GetWritablePkgOutputDirectory;
// package links
PkgLinks:=TPackageLinks.Create;
PkgLinks.UpdateAll;
PkgLinks.DependencyOwnerGetPkgFilename:=@PkgLinksDependencyOwnerGetPkgFilename;
// package graph
PackageGraph:=TLazPackageGraph.Create;
PackageGraph.OnChangePackageName:=@PackageGraphChangePackageName;
PackageGraph.OnAddPackage:=@PackageGraphAddPackage;
PackageGraph.OnDeletePackage:=@PackageGraphDeletePackage;
PackageGraph.OnDependencyModified:=@PackageGraphDependencyModified;
PackageGraph.OnBeginUpdate:=@PackageGraphBeginUpdate;
PackageGraph.OnEndUpdate:=@PackageGraphEndUpdate;
// package macros
{CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
'PKGSRCPATH',nil,@MacroFunctionPkgSrcPath);
CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
'PKGUNITPATH',nil,@MacroFunctionPkgUnitPath);
CodeToolBoss.DefineTree.MacroFunctions.AddExtended(
'PKGINCPATH',nil,@MacroFunctionPkgIncPath);}
end;
constructor TLazBuildApplication.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
@ -163,7 +274,8 @@ begin
// free project, if it is still there
//FreeThenNil(Project1);
//FreeThenNil(PkgBoss);
FreeThenNil(PackageGraph);
FreeThenNil(PkgLinks);
FreeThenNil(TheCompiler);
FreeThenNil(TheOutputFilter);
//FreeThenNil(MacroList);
@ -280,6 +392,7 @@ end;
procedure TLazBuildApplication.Error(const ErrorMsg: string);
begin
writeln('ERROR: ',ErrorMsg);
Halt;
end;
var

View File

@ -44,8 +44,9 @@ uses
{$IFDEF IDE_MEM_CHECK}
MemCheck,
{$ENDIF}
Classes, SysUtils, Forms,
Classes, SysUtils, Forms, FileUtil,
LazIDEIntf, PackageIntf, MenuIntf,
LazarusIDEStrConsts, EnvironmentOpts,
PackageDefs, ComponentReg, CompilerOptions, Project;
type
@ -158,6 +159,12 @@ function PkgSaveFlagsToString(Flags: TPkgSaveFlags): string;
function PkgOpenFlagsToString(Flags: TPkgOpenFlags): string;
function PkgCompileFlagsToString(Flags: TPkgCompileFlags): string;
procedure GetDescriptionOfDependencyOwner(Dependency: TPkgDependency;
var Description: string);
procedure GetDirectoryOfDependencyOwner(Dependency: TPkgDependency;
var Directory: string);
implementation
function PkgSaveFlagsToString(Flags: TPkgSaveFlags): string;
@ -199,6 +206,51 @@ begin
Result:='['+Result+']';
end;
procedure GetDescriptionOfDependencyOwner(Dependency: TPkgDependency;
var Description: string);
var
DepOwner: TObject;
begin
DepOwner:=Dependency.Owner;
if (DepOwner<>nil) then begin
if DepOwner is TLazPackage then begin
Description:=Format(lisPkgMangPackage, [TLazPackage(DepOwner).IDAsString]
);
end else if DepOwner is TProject then begin
Description:=Format(lisPkgMangProject, [ExtractFileNameOnly(TProject(
DepOwner).ProjectInfoFile)]);
end else if DepOwner=PkgBoss then begin
Description:=lisPkgMangLazarus;
end else begin
Description:=DepOwner.ClassName
end;
end else begin
Description:=Format(lisPkgMangDependencyWithoutOwner, [Dependency.AsString]
);
end;
end;
procedure GetDirectoryOfDependencyOwner(Dependency: TPkgDependency;
var Directory: string);
var
DepOwner: TObject;
begin
DepOwner:=Dependency.Owner;
if (DepOwner<>nil) then begin
if DepOwner is TLazPackage then begin
Directory:=TLazPackage(DepOwner).Directory;
end else if DepOwner is TProject then begin
Directory:=TProject(DepOwner).ProjectDirectory;
end else if DepOwner=PkgBoss then begin
Directory:=EnvironmentOptions.LazarusDirectory;
end else begin
Directory:=''
end;
end else begin
Directory:=''
end;
end;
{ TBasePkgManager }
constructor TBasePkgManager.Create(TheOwner: TComponent);

View File

@ -51,7 +51,7 @@ uses
AVL_Tree, Laz_XMLCfg,
// IDE Interface
IDEExternToolIntf, NewItemIntf, ProjectIntf, PackageIntf, MenuIntf,
LazIDEIntf,
MacroIntf, LazIDEIntf,
// IDE
LazConf, LazarusIDEStrConsts, IDEProcs, ObjectLists, DialogProcs, IDECommands,
EnvironmentOpts, MiscOptions, InputHistory, ProjectDefs, Project,
@ -557,47 +557,14 @@ end;
procedure TPkgManager.GetDependencyOwnerDescription(
Dependency: TPkgDependency; var Description: string);
var
DepOwner: TObject;
begin
DepOwner:=Dependency.Owner;
if (DepOwner<>nil) then begin
if DepOwner is TLazPackage then begin
Description:=Format(lisPkgMangPackage, [TLazPackage(DepOwner).IDAsString]
);
end else if DepOwner is TProject then begin
Description:=Format(lisPkgMangProject, [ExtractFileNameOnly(TProject(
DepOwner).ProjectInfoFile)]);
end else if DepOwner=Self then begin
Description:=lisPkgMangLazarus;
end else begin
Description:=DepOwner.ClassName
end;
end else begin
Description:=Format(lisPkgMangDependencyWithoutOwner, [Dependency.AsString]
);
end;
GetDescriptionOfDependencyOwner(Dependency,Description);
end;
procedure TPkgManager.GetDependencyOwnerDirectory(Dependency: TPkgDependency;
var Directory: string);
var
DepOwner: TObject;
begin
DepOwner:=Dependency.Owner;
if (DepOwner<>nil) then begin
if DepOwner is TLazPackage then begin
Directory:=TLazPackage(DepOwner).Directory;
end else if DepOwner is TProject then begin
Directory:=TProject(DepOwner).ProjectDirectory;
end else if DepOwner=Self then begin
Directory:=EnvironmentOptions.LazarusDirectory;
end else begin
Directory:=''
end;
end else begin
Directory:=''
end;
GetDirectoryOfDependencyOwner(Dependency,Directory);
end;
procedure TPkgManager.GetWritablePkgOutputDirectory(APackage: TLazPackage;
@ -613,9 +580,9 @@ begin
//debugln('TPkgManager.GetWritablePkgOutputDirectory AnOutDirectory=',AnOutDirectory,' ',dbgs(DirectoryIsWritable(AnOutDirectory)));
// output directory is not writable
// -> redirect to home directory
// -> redirect to config directory
NewOutDir:=SetDirSeparators('/$(TargetCPU)-$(TargetOS)');
MainIDE.MacroList.SubstituteStr(NewOutDir);
IDEMacros.SubstituteMacros(NewOutDir);
NewOutDir:=TrimFilename(GetPrimaryConfigPath+PathDelim+'lib'+PathDelim
+APackage.Name+NewOutDir);
AnOutDirectory:=NewOutDir;
@ -1390,8 +1357,7 @@ begin
SourceNotebook.ClearErrorLines;
// compile package
Result:=EnvironmentOptions.ExternalTools.Run(FPCMakeTool,
MainIDE.MacroList,nil,nil);
Result:=LazarusIDE.RunExternalTool(FPCMakeTool);
if Result<>mrOk then begin
Result:=MessageDlg('fpcmake failed',
'Calling '+FPCMakeTool.Filename+' to create Makefile from '
@ -1831,7 +1797,7 @@ begin
// check output state file of required package
if RequiredPackage.OutputStateFile<>'' then begin
OtherStateFile:=RequiredPackage.OutputStateFile;
MainIDE.MacroList.SubstituteStr(OtherStateFile);
IDEMacros.SubstituteMacros(OtherStateFile);
if FileExists(OtherStateFile)
and (FileAge(OtherStateFile)>StateFileAge) then begin
DebugLn('TPkgManager.CheckIfDependenciesNeedCompilation Required ',
@ -2346,7 +2312,7 @@ end;
function TPkgManager.GetPublishPackageDir(APackage: TLazPackage): string;
begin
Result:=APackage.PublishOptions.DestinationDirectory;
if MainIDE.MacroList.SubstituteStr(Result) then begin
if IDEMacros.SubstituteMacros(Result) then begin
if FilenameIsAbsolute(Result) then begin
Result:=AppendPathDelim(TrimFilename(Result));
end else begin
@ -4148,7 +4114,7 @@ begin
if Result<>mrOk then exit;
TargetDir:=MiscellaneousOptions.BuildLazOpts.TargetDirectory;
MainIDE.MacroList.SubstituteStr(TargetDir);
IDEMacros.SubstituteMacros(TargetDir);
if not ForceDirectory(TargetDir) then begin
Result:=MessageDlg(lisPkgMangUnableToCreateDirectory,
Format(lisPkgMangUnableToCreateTargetDirectoryForLazarus, [#13, '"',
@ -4202,14 +4168,6 @@ begin
// add include path to config directory
ConfigDir:=AppendPathDelim(GetPrimaryConfigPath);
AddOption(PrepareCmdLineOption('-Fi'+ConfigDir));
// add target option
// ToDo
{TargetDir:=MiscellaneousOptions.BuildLazOpts.TargetDirectory;
MainIDE.MacroList.SubstituteStr(TargetDir);
// ToDo write a function in lazconf for this
//if TargetDir<>'' then
AddOption('-FE'+TargetFilename);}
end;
function TPkgManager.DoPublishPackage(APackage: TLazPackage;