mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-08-14 00:09:17 +02:00
implemented compilation of dependencies
git-svn-id: trunk@4073 -
This commit is contained in:
parent
26ea00db8d
commit
ea81b30e67
@ -2548,6 +2548,7 @@ begin
|
||||
+'designer'+ds+'jitform;'
|
||||
+'debugger;'
|
||||
+'packager;'
|
||||
+'packager'+ds+'registration;'
|
||||
+'components'+ds+'synedit;'
|
||||
+'components'+ds+'codetools;'
|
||||
+'components'+ds+'custom;'
|
||||
@ -2629,7 +2630,8 @@ begin
|
||||
DirTempl.AddChild(TDefineTemplate.Create('components path addition',
|
||||
Format(ctsAddsDirToSourcePath,['synedit']),
|
||||
ExternalMacroStart+'SrcPath',
|
||||
'..'+ds+'components'+ds+'synedit;'
|
||||
'registration;'
|
||||
+'..'+ds+'components'+ds+'synedit;'
|
||||
+'..'+ds+'components'+ds+'codetools;'
|
||||
+'..'+ds+'components'+ds+'custom;'
|
||||
+SrcPath
|
||||
|
@ -133,7 +133,7 @@ begin
|
||||
if BuildAll then
|
||||
CmdLine := CmdLine+' -B';
|
||||
CmdLine := CmdLine
|
||||
+ ' '+ AProject.CompilerOptions.MakeOptionsString(ProjectFilename)
|
||||
+ ' '+ AProject.CompilerOptions.MakeOptionsString(ProjectFilename,[])
|
||||
+ ' '+ PrepareCmdLineOption(ProjectFilename);
|
||||
if Assigned(FOnCmdLineCreate) then begin
|
||||
Abort:=false;
|
||||
@ -190,6 +190,9 @@ end.
|
||||
|
||||
{
|
||||
$Log$
|
||||
Revision 1.41 2003/04/17 18:56:10 mattias
|
||||
implemented compilation of dependencies
|
||||
|
||||
Revision 1.40 2003/03/13 23:27:22 mattias
|
||||
localized codetools options
|
||||
|
||||
|
@ -116,10 +116,16 @@ type
|
||||
|
||||
|
||||
{ TBaseCompilerOptions }
|
||||
|
||||
TCompilerCmdLineOption = (
|
||||
ccloNoLinkerOpts // exclude linker options
|
||||
);
|
||||
TCompilerCmdLineOptions = set of TCompilerCmdLineOption;
|
||||
|
||||
TBaseCompilerOptions = class
|
||||
private
|
||||
FBaseDirectory: string;
|
||||
FDefaultMakeOptionsFlags: TCompilerCmdLineOptions;
|
||||
fInheritedOptions: array[TInheritedCompilerOption] of string;
|
||||
fInheritedOptParseStamps: integer;
|
||||
fInheritedOptGraphStamps: integer;
|
||||
@ -211,6 +217,7 @@ type
|
||||
fAdditionalConfigFile: Boolean;
|
||||
fConfigFilePath: String;
|
||||
fCustomOptions: string;
|
||||
procedure SetDefaultMakeOptionsFlags(const AValue: TCompilerCmdLineOptions);
|
||||
protected
|
||||
procedure SetBaseDirectory(const AValue: string); virtual;
|
||||
procedure SetCompilerPath(const AValue: String); virtual;
|
||||
@ -239,8 +246,9 @@ type
|
||||
procedure Assign(CompOpts: TBaseCompilerOptions); virtual;
|
||||
function IsEqual(CompOpts: TBaseCompilerOptions): boolean; virtual;
|
||||
|
||||
function MakeOptionsString: String;
|
||||
function MakeOptionsString(const MainSourceFileName: string): String; virtual;
|
||||
function MakeOptionsString(Flags: TCompilerCmdLineOptions): String;
|
||||
function MakeOptionsString(const MainSourceFileName: string;
|
||||
Flags: TCompilerCmdLineOptions): String; virtual;
|
||||
function CustomOptionsAsString: string;
|
||||
function ConvertSearchPathToCmdLine(const switch, paths: String): String;
|
||||
function ConvertOptionsToCmdLine(const Delim, Switch, OptionStr: string): string;
|
||||
@ -253,6 +261,7 @@ type
|
||||
function MergeLinkerOptions(const OldOptions, AddOptions: string): string;
|
||||
function MergeCustomOptions(const OldOptions, AddOptions: string): string;
|
||||
function GetDefaultMainSourceFileName: string; virtual;
|
||||
function NeedsLinkerOpts: boolean;
|
||||
public
|
||||
{ Properties }
|
||||
property Owner: TObject read fOwner write fOwner;
|
||||
@ -261,6 +270,7 @@ type
|
||||
property ParsedOpts: TParsedCompilerOptions read FParsedOpts;
|
||||
property BaseDirectory: string read FBaseDirectory write SetBaseDirectory;
|
||||
property TargetFilename: String read fTargetFilename write fTargetFilename;
|
||||
property DefaultMakeOptionsFlags: TCompilerCmdLineOptions read FDefaultMakeOptionsFlags write SetDefaultMakeOptionsFlags;
|
||||
|
||||
property XMLFile: String read fXMLFile write fXMLFile;
|
||||
property XMLConfigFile: TXMLConfig read xmlconfig write xmlconfig;
|
||||
@ -733,6 +743,13 @@ begin
|
||||
ParsedOpts.SetUnparsedValue(pcosCompilerPath,fCompilerPath);
|
||||
end;
|
||||
|
||||
procedure TBaseCompilerOptions.SetDefaultMakeOptionsFlags(
|
||||
const AValue: TCompilerCmdLineOptions);
|
||||
begin
|
||||
if FDefaultMakeOptionsFlags=AValue then exit;
|
||||
FDefaultMakeOptionsFlags:=AValue;
|
||||
end;
|
||||
|
||||
procedure TBaseCompilerOptions.SetBaseDirectory(const AValue: string);
|
||||
begin
|
||||
if FBaseDirectory=AValue then exit;
|
||||
@ -1160,20 +1177,26 @@ begin
|
||||
Result:='';
|
||||
end;
|
||||
|
||||
function TBaseCompilerOptions.NeedsLinkerOpts: boolean;
|
||||
begin
|
||||
Result:=not (ccloNoLinkerOpts in fDefaultMakeOptionsFlags);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
TBaseCompilerOptions MakeOptionsString
|
||||
------------------------------------------------------------------------------}
|
||||
function TBaseCompilerOptions.MakeOptionsString: String;
|
||||
function TBaseCompilerOptions.MakeOptionsString(Flags: TCompilerCmdLineOptions
|
||||
): String;
|
||||
begin
|
||||
Result:=MakeOptionsString(GetDefaultMainSourceFileName)
|
||||
Result:=MakeOptionsString(GetDefaultMainSourceFileName,Flags);
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------
|
||||
function TBaseCompilerOptions.MakeOptionsString(
|
||||
const MainSourceFilename: string): String;
|
||||
const MainSourceFilename: string; Flags: TCompilerCmdLineOptions): String;
|
||||
------------------------------------------------------------------------------}
|
||||
function TBaseCompilerOptions.MakeOptionsString(
|
||||
const MainSourceFilename: string): String;
|
||||
const MainSourceFilename: string; Flags: TCompilerCmdLineOptions): String;
|
||||
var
|
||||
switches, tempsw: String;
|
||||
InhLinkerOpts: String;
|
||||
@ -1509,7 +1532,7 @@ Processor specific options:
|
||||
switches := switches + ' -gl';
|
||||
|
||||
{ Use Heaptrc Unit }
|
||||
if (UseHeaptrc) then
|
||||
if (UseHeaptrc) and (not (ccloNoLinkerOpts in Flags)) then
|
||||
switches := switches + ' -gh';
|
||||
|
||||
{ Generate code gprof }
|
||||
@ -1517,7 +1540,7 @@ Processor specific options:
|
||||
switches := switches + ' -pg';
|
||||
|
||||
{ Strip Symbols }
|
||||
if (StripSymbols) then
|
||||
if (StripSymbols) and (not (ccloNoLinkerOpts in Flags)) then
|
||||
switches := switches + ' -Xs';
|
||||
|
||||
{ Link Style
|
||||
@ -1525,23 +1548,26 @@ Processor specific options:
|
||||
-XS = Link with static libraries
|
||||
-XX = Link smart
|
||||
}
|
||||
case (LinkStyle) of
|
||||
1: switches := switches + ' -XD';
|
||||
2: switches := switches + ' -XS';
|
||||
3: switches := switches + ' -XX';
|
||||
end;
|
||||
if (not (ccloNoLinkerOpts in Flags)) then
|
||||
case (LinkStyle) of
|
||||
1: switches := switches + ' -XD';
|
||||
2: switches := switches + ' -XS';
|
||||
3: switches := switches + ' -XX';
|
||||
end;
|
||||
|
||||
// additional Linker options
|
||||
if PassLinkerOptions then begin
|
||||
if PassLinkerOptions and (not (ccloNoLinkerOpts in Flags)) then begin
|
||||
CurLinkerOptions:=ParsedOpts.GetParsedValue(pcosLinkerOptions);
|
||||
if (CurLinkerOptions<>'') then
|
||||
switches := switches + ' ' + ConvertOptionsToCmdLine(' ','-k', CurLinkerOptions);
|
||||
end;
|
||||
|
||||
// inherited Linker options
|
||||
InhLinkerOpts:=GetInheritedOption(icoLinkerOptions,true);
|
||||
if InhLinkerOpts<>'' then
|
||||
switches := switches + ' ' + ConvertOptionsToCmdLine(' ','-k', InhLinkerOpts);
|
||||
if (not (ccloNoLinkerOpts in Flags)) then begin
|
||||
InhLinkerOpts:=GetInheritedOption(icoLinkerOptions,true);
|
||||
if InhLinkerOpts<>'' then
|
||||
switches := switches + ' ' + ConvertOptionsToCmdLine(' ','-k', InhLinkerOpts);
|
||||
end;
|
||||
|
||||
{ ---------------- Other Tab -------------------- }
|
||||
|
||||
@ -1617,14 +1643,18 @@ Processor specific options:
|
||||
switches := switches + ' ' + ConvertSearchPathToCmdLine('-Fi', InhIncludePath);
|
||||
|
||||
// library path
|
||||
CurLibraryPath:=ParsedOpts.GetParsedValue(pcosLibraryPath);
|
||||
if (CurLibraryPath <> '') then
|
||||
switches := switches + ' ' + ConvertSearchPathToCmdLine('-Fl', CurLibraryPath);
|
||||
if (not (ccloNoLinkerOpts in Flags)) then begin
|
||||
CurLibraryPath:=ParsedOpts.GetParsedValue(pcosLibraryPath);
|
||||
if (CurLibraryPath <> '') then
|
||||
switches := switches + ' ' + ConvertSearchPathToCmdLine('-Fl', CurLibraryPath);
|
||||
end;
|
||||
|
||||
// inherited library path
|
||||
InhLibraryPath:=GetInheritedOption(icoLibraryPath,true);
|
||||
if (InhLibraryPath <> '') then
|
||||
switches := switches + ' ' + ConvertSearchPathToCmdLine('-Fl', InhLibraryPath);
|
||||
if (not (ccloNoLinkerOpts in Flags)) then begin
|
||||
InhLibraryPath:=GetInheritedOption(icoLibraryPath,true);
|
||||
if (InhLibraryPath <> '') then
|
||||
switches := switches + ' ' + ConvertSearchPathToCmdLine('-Fl', InhLibraryPath);
|
||||
end;
|
||||
|
||||
// object path
|
||||
CurObjectPath:=ParsedOpts.GetParsedValue(pcosObjectPath);
|
||||
@ -1653,7 +1683,8 @@ Processor specific options:
|
||||
|
||||
{ Unit output directory }
|
||||
if UnitOutputDirectory<>'' then
|
||||
CurOutputDir:=ParsedOpts.GetParsedValue(pcosOutputDir)
|
||||
CurOutputDir:=CreateRelativePath(ParsedOpts.GetParsedValue(pcosOutputDir),
|
||||
BaseDirectory)
|
||||
else
|
||||
CurOutputDir:='';
|
||||
if CurOutputDir<>'' then
|
||||
@ -2203,20 +2234,20 @@ begin
|
||||
ModalResult:=mrCancel;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ TfrmCompilerOptions ButtonApplyClicked }
|
||||
{------------------------------------------------------------------------------}
|
||||
{------------------------------------------------------------------------------
|
||||
TfrmCompilerOptions ButtonApplyClicked
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TfrmCompilerOptions.ButtonApplyClicked(Sender: TObject);
|
||||
begin
|
||||
// Apply any changes
|
||||
PutCompilerOptions;
|
||||
end;
|
||||
|
||||
{------------------------------------------------------------------------------}
|
||||
{ TfrmCompilerOptions ButtonTestClicked }
|
||||
{ This function is for testing the MakeOptionsString function only. Remove }
|
||||
{ this function and its button when the function is working correctly. }
|
||||
{------------------------------------------------------------------------------}
|
||||
{------------------------------------------------------------------------------
|
||||
TfrmCompilerOptions ButtonTestClicked
|
||||
This function is for testing the MakeOptionsString function only. Remove
|
||||
this function and its button when the function is working correctly.
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TfrmCompilerOptions.ButtonTestClicked(Sender: TObject);
|
||||
var
|
||||
teststr: String;
|
||||
@ -2226,7 +2257,7 @@ begin
|
||||
Assert(False, 'Trace:Test MakeOptionsString function');
|
||||
|
||||
PutCompilerOptions;
|
||||
teststr := CompilerOpts.MakeOptionsString;
|
||||
teststr := CompilerOpts.MakeOptionsString(CompilerOpts.DefaultMakeOptionsFlags);
|
||||
WriteLn('CompilerOpts.MakeOptionsString: ' + teststr);
|
||||
i:=1;
|
||||
LineLen:=0;
|
||||
@ -2281,8 +2312,12 @@ end;
|
||||
TfrmCompilerOptions GetCompilerOptions
|
||||
------------------------------------------------------------------------------}
|
||||
procedure TfrmCompilerOptions.GetCompilerOptions;
|
||||
var i: integer;
|
||||
var
|
||||
i: integer;
|
||||
EnabledLinkerOpts: Boolean;
|
||||
begin
|
||||
EnabledLinkerOpts:=CompilerOpts.NeedsLinkerOpts;
|
||||
|
||||
{ Get the compiler options and apply them to the dialog }
|
||||
case CompilerOpts.Style of
|
||||
1: radStyleIntel.Checked := true;
|
||||
@ -2310,6 +2345,7 @@ begin
|
||||
chkChecksOverflow.Checked := CompilerOpts.OverflowChecks;
|
||||
chkChecksStack.Checked := CompilerOpts.StackChecks;
|
||||
|
||||
grpHeapSize.Enabled:=EnabledLinkerOpts;
|
||||
edtHeapSize.Text := IntToStr(CompilerOpts.HeapSize);
|
||||
|
||||
case CompilerOpts.Generate of
|
||||
@ -2336,18 +2372,22 @@ begin
|
||||
chkDebugDBX.Checked := CompilerOpts.GenerateDebugDBX;
|
||||
chkUseLineInfoUnit.Checked := CompilerOpts.UseLineInfoUnit;
|
||||
chkUseHeaptrc.Checked := CompilerOpts.UseHeaptrc;
|
||||
chkUseHeaptrc.Enabled:=EnabledLinkerOpts;
|
||||
chkGenGProfCode.Checked := CompilerOpts.GenGProfCode;
|
||||
chkSymbolsStrip.Checked := CompilerOpts.StripSymbols;
|
||||
chkSymbolsStrip.Enabled:=EnabledLinkerOpts;
|
||||
|
||||
case CompilerOpts.LinkStyle of
|
||||
1: radLibsLinkDynamic.Checked := true;
|
||||
2: radLibsLinkStatic.Checked := true;
|
||||
3: radLibsLinkSmart.Checked := true;
|
||||
end;
|
||||
grpLinkLibraries.Enabled:=EnabledLinkerOpts;
|
||||
|
||||
chkOptionsLinkOpt.Checked := CompilerOpts.PassLinkerOptions;
|
||||
edtOptionsLinkOpt.Text := CompilerOpts.LinkerOptions;
|
||||
|
||||
grpOptions.Enabled:=EnabledLinkerOpts;
|
||||
|
||||
chkErrors.Checked := CompilerOpts.ShowErrors;
|
||||
chkWarnings.Checked := CompilerOpts.ShowWarn;
|
||||
chkNotes.Checked := CompilerOpts.ShowNotes;
|
||||
@ -2379,6 +2419,7 @@ begin
|
||||
edtOtherUnits.Text := CompilerOpts.OtherUnitFiles;
|
||||
edtIncludeFiles.Text := CompilerOpts.IncludeFiles;
|
||||
edtLibraries.Text := CompilerOpts.Libraries;
|
||||
grpLibraries.Enabled:=EnabledLinkerOpts;
|
||||
edtCompiler.Text := CompilerOpts.CompilerPath;
|
||||
edtUnitOutputDir.Text := CompilerOpts.UnitOutputDirectory;
|
||||
|
||||
@ -2410,13 +2451,13 @@ begin
|
||||
OldCompOpts.Assign(CompilerOpts);
|
||||
|
||||
if (radStyleIntel.Checked) then
|
||||
CompilerOpts.Style := 1
|
||||
CompilerOpts.Style := 1
|
||||
else if (radStyleATT.Checked) then
|
||||
CompilerOpts.Style := 2
|
||||
CompilerOpts.Style := 2
|
||||
else if (radStyleAsIs.Checked) then
|
||||
CompilerOpts.Style := 3
|
||||
CompilerOpts.Style := 3
|
||||
else
|
||||
CompilerOpts.Style := 1;
|
||||
CompilerOpts.Style := 1;
|
||||
|
||||
CompilerOpts.D2Extensions := chkSymD2Ext.Checked;
|
||||
CompilerOpts.CStyleOperators := chkSymCOper.Checked;
|
||||
@ -2446,32 +2487,32 @@ begin
|
||||
CompilerOpts.HeapSize := hs;
|
||||
|
||||
if (radGenFaster.Checked) then
|
||||
CompilerOpts.Generate := 1
|
||||
CompilerOpts.Generate := 1
|
||||
else if (radGenSmaller.Checked) then
|
||||
CompilerOpts.Generate := 2
|
||||
CompilerOpts.Generate := 2
|
||||
else
|
||||
CompilerOpts.Generate := 1;
|
||||
CompilerOpts.Generate := 1;
|
||||
|
||||
if (radTarget386.Checked) then
|
||||
CompilerOpts.TargetProcessor := 1
|
||||
CompilerOpts.TargetProcessor := 1
|
||||
else if (radTargetPent.Checked) then
|
||||
CompilerOpts.TargetProcessor := 2
|
||||
CompilerOpts.TargetProcessor := 2
|
||||
else if (radTargetPentPro.Checked) then
|
||||
CompilerOpts.TargetProcessor := 3
|
||||
CompilerOpts.TargetProcessor := 3
|
||||
else
|
||||
CompilerOpts.TargetProcessor := 1;
|
||||
CompilerOpts.TargetProcessor := 1;
|
||||
|
||||
CompilerOpts.VariablesInRegisters := chkOptVarsInReg.Checked;
|
||||
CompilerOpts.UncertainOptimizations := chkOptUncertain.Checked;
|
||||
|
||||
if (radOptLevel1.Checked) then
|
||||
CompilerOpts.OptimizationLevel := 1
|
||||
CompilerOpts.OptimizationLevel := 1
|
||||
else if (radOptLevel2.Checked) then
|
||||
CompilerOpts.OptimizationLevel := 2
|
||||
CompilerOpts.OptimizationLevel := 2
|
||||
else if (radOptLevel3.Checked) then
|
||||
CompilerOpts.OptimizationLevel := 3
|
||||
CompilerOpts.OptimizationLevel := 3
|
||||
else
|
||||
CompilerOpts.OptimizationLevel := 1;
|
||||
CompilerOpts.OptimizationLevel := 1;
|
||||
|
||||
CompilerOpts.GenerateDebugInfo := chkDebugGDB.Checked;
|
||||
CompilerOpts.GenerateDebugDBX := chkDebugDBX.Checked;
|
||||
|
@ -59,7 +59,10 @@ type
|
||||
TPkgOpenFlags = set of TPkgOpenFlag;
|
||||
|
||||
TPkgCompileFlag = (
|
||||
pcfCompileAll
|
||||
pcfCleanCompile, // append -B to the compiler options
|
||||
pcfDoNotCompileDependencies,
|
||||
pcfOnlyIfNeeded,
|
||||
pcfAutomatic
|
||||
);
|
||||
TPkgCompileFlags = set of TPkgCompileFlag;
|
||||
|
||||
@ -92,9 +95,69 @@ type
|
||||
|
||||
var
|
||||
PkgBoss: TBasePkgManager;
|
||||
|
||||
const
|
||||
PkgSaveFlagNames: array[TPkgSaveFlag] of string = (
|
||||
'psfSaveAs',
|
||||
'psfAskBeforeSaving'
|
||||
);
|
||||
|
||||
PkgOpenFlagNames: array[TPkgOpenFlag] of string = (
|
||||
'pofAddToRecent'
|
||||
);
|
||||
|
||||
PkgCompileFlagNames: array[TPkgCompileFlag] of string = (
|
||||
'pcfCleanCompile',
|
||||
'pcfDoNotCompileDependencies',
|
||||
'pcfOnlyIfNeeded',
|
||||
'pcfAutomatic'
|
||||
);
|
||||
|
||||
function PkgSaveFlagsToString(Flags: TPkgSaveFlags): string;
|
||||
function PkgOpenFlagsToString(Flags: TPkgOpenFlags): string;
|
||||
function PkgCompileFlagsToString(Flags: TPkgCompileFlags): string;
|
||||
|
||||
implementation
|
||||
|
||||
function PkgSaveFlagsToString(Flags: TPkgSaveFlags): string;
|
||||
var
|
||||
f: TPkgSaveFlag;
|
||||
begin
|
||||
Result:='';
|
||||
for f:=Low(TPkgSaveFlag) to High(TPkgSaveFlag) do begin
|
||||
if not (f in Flags) then continue;
|
||||
if Result<>'' then Result:=Result+',';
|
||||
Result:=Result+PkgSaveFlagNames[f];
|
||||
end;
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
function PkgOpenFlagsToString(Flags: TPkgOpenFlags): string;
|
||||
var
|
||||
f: TPkgOpenFlag;
|
||||
begin
|
||||
Result:='';
|
||||
for f:=Low(TPkgOpenFlag) to High(TPkgOpenFlag) do begin
|
||||
if not (f in Flags) then continue;
|
||||
if Result<>'' then Result:=Result+',';
|
||||
Result:=Result+PkgOpenFlagNames[f];
|
||||
end;
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
function PkgCompileFlagsToString(Flags: TPkgCompileFlags): string;
|
||||
var
|
||||
f: TPkgCompileFlag;
|
||||
begin
|
||||
Result:='';
|
||||
for f:=Low(TPkgCompileFlag) to High(TPkgCompileFlag) do begin
|
||||
if not (f in Flags) then continue;
|
||||
if Result<>'' then Result:=Result+',';
|
||||
Result:=Result+PkgCompileFlagNames[f];
|
||||
end;
|
||||
Result:='['+Result+']';
|
||||
end;
|
||||
|
||||
initialization
|
||||
PkgBoss:=nil;
|
||||
|
||||
|
@ -337,8 +337,9 @@ type
|
||||
// package requires this package)
|
||||
lpfVisited, // Used by the PackageGraph to avoid double checking
|
||||
lpfDestroying, // set during destruction
|
||||
lpfSkipSaving,
|
||||
lpfCircle
|
||||
lpfSkipSaving, // Used by PkgBoss to skip saving
|
||||
lpfCircle, // Used by the PackageGraph to mark circles
|
||||
lpfStateFileLoaded // state file data valid
|
||||
);
|
||||
TLazPackageFlags = set of TLazPackageFlag;
|
||||
|
||||
@ -372,6 +373,8 @@ type
|
||||
FFlags: TLazPackageFlags;
|
||||
FIconFile: string;
|
||||
FInstalled: TPackageInstallType;
|
||||
FLastCompilerFilename: string;
|
||||
FLastCompilerParams: string;
|
||||
FMacros: TTransferMacroList;
|
||||
FModifiedLock: integer;
|
||||
FPackageEditor: TBasePackageEditor;
|
||||
@ -379,6 +382,7 @@ type
|
||||
FReadOnly: boolean;
|
||||
FRemovedFiles: TList; // TList of TPkgFile
|
||||
FRegistered: boolean;
|
||||
FStateFileDate: longint;
|
||||
FUsageOptions: TPkgAdditionalCompilerOptions;
|
||||
function GetAutoIncrementVersionOnBuild: boolean;
|
||||
function GetAutoUpdate: boolean;
|
||||
@ -429,6 +433,8 @@ type
|
||||
procedure GetInheritedCompilerOptions(var OptionsList: TList);
|
||||
function GetCompileSourceFilename: string;
|
||||
function GetOutputDirectory: string;
|
||||
function GetStateFilename: string;
|
||||
function GetCompilerFilename: string;
|
||||
// files
|
||||
function FindPkgFile(const AFilename: string;
|
||||
ResolveLinks, IgnoreRemoved: boolean): TPkgFile;
|
||||
@ -491,13 +497,18 @@ type
|
||||
property Flags: TLazPackageFlags read FFlags write SetFlags;
|
||||
property IconFile: string read FIconFile write SetIconFile;
|
||||
property Installed: TPackageInstallType read FInstalled write SetInstalled;
|
||||
property Registered: boolean read FRegistered write SetRegistered;
|
||||
property LastCompilerFilename: string read FLastCompilerFilename
|
||||
write FLastCompilerFilename;
|
||||
property LastCompilerParams: string read FLastCompilerParams
|
||||
write FLastCompilerParams;
|
||||
property Macros: TTransferMacroList read FMacros;
|
||||
property Modified: boolean read GetModified write SetModified;
|
||||
property PackageType: TLazPackageType read FPackageType write SetPackageType;
|
||||
property ReadOnly: boolean read FReadOnly write SetReadOnly;
|
||||
property Registered: boolean read FRegistered write SetRegistered;
|
||||
property RemovedFilesCount: integer read GetRemovedCount;
|
||||
property RemovedFiles[Index: integer]: TPkgFile read GetRemovedFiles;
|
||||
property Macros: TTransferMacroList read FMacros;
|
||||
property StateFileDate: longint read FStateFileDate write FStateFileDate;
|
||||
property UsageOptions: TPkgAdditionalCompilerOptions
|
||||
read FUsageOptions;
|
||||
end;
|
||||
@ -529,7 +540,8 @@ const
|
||||
'RunTime', 'DesignTime', 'RunAndDesignTime');
|
||||
LazPackageFlagNames: array[TLazPackageFlag] of string = (
|
||||
'lpfAutoIncrementVersionOnBuild', 'lpfModified', 'lpfAutoUpdate',
|
||||
'lpfNeeded', 'lpfVisited', 'lpfDestroying', 'lpfSkipSaving', 'lpfCircle');
|
||||
'lpfNeeded', 'lpfVisited', 'lpfDestroying', 'lpfSkipSaving', 'lpfCircle',
|
||||
'lpfStateFileLoaded');
|
||||
|
||||
var
|
||||
// All TPkgDependency are added to this AVL tree (sorted for names, not version!)
|
||||
@ -1499,6 +1511,7 @@ begin
|
||||
FCompilerOptions:=TPkgCompilerOptions.Create(Self);
|
||||
FCompilerOptions.ParsedOpts.OnLocalSubstitute:=@SubstitutePkgMacro;
|
||||
FCompilerOptions.ParsedOpts.InvalidateGraphOnChange:=true;
|
||||
FCompilerOptions.DefaultMakeOptionsFlags:=[ccloNoLinkerOpts];
|
||||
FUsageOptions:=TPkgAdditionalCompilerOptions.Create(Self);
|
||||
FUsageOptions.ParsedOpts.OnLocalSubstitute:=@SubstitutePkgMacro;
|
||||
Clear;
|
||||
@ -2072,6 +2085,17 @@ begin
|
||||
Result:='';
|
||||
end;
|
||||
|
||||
function TLazPackage.GetStateFilename: string;
|
||||
begin
|
||||
Result:=GetOutputDirectory
|
||||
+ChangeFileExt(GetCompileSourceFilename,'.compiled');
|
||||
end;
|
||||
|
||||
function TLazPackage.GetCompilerFilename: string;
|
||||
begin
|
||||
Result:=CompilerOptions.ParsedOpts.GetParsedValue(pcosCompilerPath);
|
||||
end;
|
||||
|
||||
{ TPkgComponent }
|
||||
|
||||
procedure TPkgComponent.SetPkgFile(const AValue: TPkgFile);
|
||||
|
@ -154,6 +154,7 @@ type
|
||||
procedure MarkNeededPackages;
|
||||
function FindBrokenDependencyPath(APackage: TLazPackage): TList;
|
||||
function FindCircleDependencyPath(APackage: TLazPackage): TList;
|
||||
function GetAutoCompilationOrder(APackage: TLazPackage): TList;
|
||||
public
|
||||
// packages handling
|
||||
function CreateNewPackage(const Prefix: string): TLazPackage;
|
||||
@ -1036,6 +1037,40 @@ begin
|
||||
FindCircle(APackage,Result);
|
||||
end;
|
||||
|
||||
function TLazPackageGraph.GetAutoCompilationOrder(APackage: TLazPackage
|
||||
): TList;
|
||||
|
||||
procedure GetTopologicalOrder(const FirstDependency: TPkgDependency);
|
||||
var
|
||||
Dependency: TPkgDependency;
|
||||
RequiredPackage: TLazPackage;
|
||||
begin
|
||||
Dependency:=FirstDependency;
|
||||
while Dependency<>nil do begin
|
||||
if Dependency.LoadPackageResult=lprSuccess then begin
|
||||
RequiredPackage:=Dependency.RequiredPackage;
|
||||
if not (lpfVisited in RequiredPackage.Flags) then begin
|
||||
RequiredPackage.Flags:=RequiredPackage.Flags+[lpfVisited];
|
||||
if RequiredPackage.AutoUpdate then begin
|
||||
// add first all needed packages
|
||||
GetTopologicalOrder(RequiredPackage.FirstRequiredDependency);
|
||||
// then add this package
|
||||
if Result=nil then Result:=TList.Create;
|
||||
Result.Add(RequiredPackage);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
Dependency:=Dependency.NextRequiresDependency;
|
||||
end;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=nil;
|
||||
MarkAllPackagesAsNotVisited;
|
||||
APackage.Flags:=APackage.Flags+[lpfVisited];
|
||||
GetTopologicalOrder(APackage.FirstRequiredDependency);
|
||||
end;
|
||||
|
||||
procedure TLazPackageGraph.MarkAllPackagesAsNotVisited;
|
||||
var
|
||||
i: Integer;
|
||||
|
@ -84,6 +84,12 @@ type
|
||||
procedure OnApplicationIdle(Sender: TObject);
|
||||
private
|
||||
function DoShowSavePackageAsDialog(APackage: TLazPackage): TModalResult;
|
||||
function CompileRequiredPackages(APackage: TLazPackage): TModalResult;
|
||||
function CheckPackageGraphForCompilation(APackage: TLazPackage): TModalResult;
|
||||
function DoPreparePackageOutputDirectory(APackage: TLazPackage): TModalResult;
|
||||
function DoSavePackageCompiledState(APackage: TLazPackage;
|
||||
const CompilerFilename, CompilerParams: string): TModalResult;
|
||||
function CheckIfPackageNeedsCompilation(APackage: TLazPackage): boolean;
|
||||
public
|
||||
constructor Create(TheOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
@ -96,7 +102,7 @@ type
|
||||
|
||||
procedure LoadInstalledPackages; override;
|
||||
function AddPackageToGraph(APackage: TLazPackage): TModalResult;
|
||||
|
||||
|
||||
function ShowConfigureCustomComponents: TModalResult; override;
|
||||
function DoNewPackage: TModalResult; override;
|
||||
function DoShowOpenInstalledPckDlg: TModalResult; override;
|
||||
@ -159,7 +165,7 @@ var
|
||||
Flags: TPkgCompileFlags;
|
||||
begin
|
||||
Flags:=[];
|
||||
if CompileAll then Include(Flags,pcfCompileAll);
|
||||
if CompileAll then Include(Flags,pcfCleanCompile);
|
||||
Result:=DoCompilePackage(APackage,Flags);
|
||||
end;
|
||||
|
||||
@ -525,6 +531,197 @@ begin
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
function TPkgManager.CompileRequiredPackages(APackage: TLazPackage
|
||||
): TModalResult;
|
||||
var
|
||||
AutoPackages: TList;
|
||||
i: Integer;
|
||||
begin
|
||||
AutoPackages:=PackageGraph.GetAutoCompilationOrder(APackage);
|
||||
if AutoPackages<>nil then begin
|
||||
try
|
||||
i:=0;
|
||||
while i<AutoPackages.Count do begin
|
||||
Result:=DoCompilePackage(TLazPackage(AutoPackages[i]),
|
||||
[pcfDoNotCompileDependencies,pcfOnlyIfNeeded,
|
||||
pcfAutomatic]);
|
||||
if Result<>mrOk then exit;
|
||||
inc(i);
|
||||
end;
|
||||
finally
|
||||
AutoPackages.Free;
|
||||
end;
|
||||
end;
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
function TPkgManager.CheckPackageGraphForCompilation(APackage: TLazPackage
|
||||
): TModalResult;
|
||||
var
|
||||
PathList: TList;
|
||||
begin
|
||||
// check for broken dependencies
|
||||
PathList:=PackageGraph.FindBrokenDependencyPath(APackage);
|
||||
if PathList<>nil then begin
|
||||
DoShowPackageGraphPathList(PathList);
|
||||
Result:=MessageDlg('Broken dependency',
|
||||
'A required packages was not found. See package graph.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// check for circle dependencies
|
||||
PathList:=PackageGraph.FindCircleDependencyPath(APackage);
|
||||
if PathList<>nil then begin
|
||||
DoShowPackageGraphPathList(PathList);
|
||||
Result:=MessageDlg('Circle in package dependencies',
|
||||
'There is a circle in the required packages. See package graph.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
function TPkgManager.DoSavePackageCompiledState(APackage: TLazPackage;
|
||||
const CompilerFilename, CompilerParams: string): TModalResult;
|
||||
var
|
||||
XMLConfig: TXMLConfig;
|
||||
StateFile: String;
|
||||
begin
|
||||
StateFile:=APackage.GetStateFilename;
|
||||
try
|
||||
ClearFile(StateFile,true);
|
||||
XMLConfig:=TXMLConfig.Create(StateFile);
|
||||
try
|
||||
XMLConfig.SetValue('Compiler/Value',CompilerFilename);
|
||||
XMLConfig.SetValue('Params/Value',CompilerParams);
|
||||
XMLConfig.Flush;
|
||||
finally
|
||||
XMLConfig.Free;
|
||||
end;
|
||||
APackage.LastCompilerFilename:=CompilerFilename;
|
||||
APackage.LastCompilerParams:=CompilerParams;
|
||||
APackage.StateFileDate:=FileAge(StateFile);
|
||||
APackage.Flags:=APackage.Flags+[lpfStateFileLoaded];
|
||||
except
|
||||
on E: Exception do begin
|
||||
Result:=MessageDlg('Error writing file',
|
||||
'Unable to write state file "'+StateFile+'"'#13
|
||||
+'of package '+APackage.IDAsString+'.',
|
||||
mtError,[mbAbort,mbCancel],0);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:=MainIDE.DoDeleteAmbigiousFiles(StateFile);
|
||||
if Result<>mrOk then exit;
|
||||
end;
|
||||
|
||||
function TPkgManager.DoPreparePackageOutputDirectory(APackage: TLazPackage
|
||||
): TModalResult;
|
||||
var
|
||||
OutputDir: String;
|
||||
StateFile: String;
|
||||
begin
|
||||
OutputDir:=APackage.GetOutputDirectory;
|
||||
StateFile:=APackage.GetStateFilename;
|
||||
|
||||
// create the output directory
|
||||
if not ForceDirectory(OutputDir) then begin
|
||||
Result:=MessageDlg('Unable to create directory',
|
||||
'Unable to create output directory "'+OutputDir+'"'#13
|
||||
+'for package '+APackage.IDAsString+'.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
end;
|
||||
|
||||
// delete old Compile State file
|
||||
if FileExists(StateFile) and not DeleteFile(StateFile) then begin
|
||||
Result:=MessageDlg('Unable to delete file',
|
||||
'Unable to delete old state file "'+StateFile+'"'#13
|
||||
+'for package '+APackage.IDAsString+'.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
end;
|
||||
APackage.Flags:=APackage.Flags-[lpfStateFileLoaded];
|
||||
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
||||
function TPkgManager.CheckIfPackageNeedsCompilation(APackage: TLazPackage
|
||||
): boolean;
|
||||
var
|
||||
OutputDir: String;
|
||||
SrcFilename: String;
|
||||
CompilerFilename: String;
|
||||
CompilerParams: String;
|
||||
StateFilename: String;
|
||||
StateFileAge: Integer;
|
||||
i: Integer;
|
||||
XMLConfig: TXMLConfig;
|
||||
CurFile: TPkgFile;
|
||||
begin
|
||||
Result:=true;
|
||||
|
||||
writeln('TPkgManager.CheckIfPackageNeedsCompilation A ',APackage.IDAsString);
|
||||
// check state file
|
||||
StateFilename:=APackage.GetStateFilename;
|
||||
if not FileExists(StateFilename) then exit;
|
||||
|
||||
StateFileAge:=FileAge(StateFilename);
|
||||
|
||||
// read the state file
|
||||
if (not (lpfStateFileLoaded in APackage.Flags))
|
||||
or (APackage.StateFileDate<>StateFileAge) then begin
|
||||
try
|
||||
XMLConfig:=TXMLConfig.Create(StateFilename);
|
||||
try
|
||||
APackage.LastCompilerFilename:=
|
||||
XMLConfig.GetValue('Compiler/Value','');
|
||||
APackage.LastCompilerParams:=
|
||||
XMLConfig.GetValue('Params/Value','');
|
||||
finally
|
||||
XMLConfig.Free;
|
||||
end;
|
||||
APackage.StateFileDate:=StateFileAge;
|
||||
except
|
||||
on E: Exception do begin
|
||||
MessageDlg('Error reading file',
|
||||
'Unable to read state file "'+StateFilename+'"'#13
|
||||
+'of package '+APackage.IDAsString+'.',
|
||||
mtError,[mbCancel],0);
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
APackage.Flags:=APackage.Flags+[lpfStateFileLoaded];
|
||||
end;
|
||||
|
||||
OutputDir:=APackage.GetOutputDirectory;
|
||||
SrcFilename:=OutputDir+APackage.GetCompileSourceFilename;
|
||||
CompilerFilename:=APackage.GetCompilerFilename;
|
||||
CompilerParams:=APackage.CompilerOptions.MakeOptionsString(
|
||||
APackage.CompilerOptions.DefaultMakeOptionsFlags)
|
||||
+' '+CreateRelativePath(SrcFilename,APackage.Directory);
|
||||
|
||||
// check compiler command
|
||||
if CompilerFilename<>APackage.LastCompilerFilename then exit;
|
||||
if CompilerParams<>APackage.LastCompilerParams then exit;
|
||||
|
||||
// check main source file
|
||||
if StateFileAge<FileAge(SrcFilename) then exit;
|
||||
|
||||
// check package files
|
||||
for i:=0 to APackage.FileCount-1 do begin
|
||||
CurFile:=APackage.Files[i];
|
||||
if FileExists(CurFile.Filename)
|
||||
and (StateFileAge<FileAge(CurFile.Filename)) then exit;
|
||||
end;
|
||||
|
||||
writeln('TPkgManager.CheckIfPackageNeedsCompilation END ',APackage.IDAsString);
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
constructor TPkgManager.Create(TheOwner: TComponent);
|
||||
begin
|
||||
inherited Create(TheOwner);
|
||||
@ -904,79 +1101,88 @@ end;
|
||||
function TPkgManager.DoCompilePackage(APackage: TLazPackage;
|
||||
Flags: TPkgCompileFlags): TModalResult;
|
||||
var
|
||||
PathList: TList;
|
||||
PkgCompileTool: TExternalToolOptions;
|
||||
OutputDir: String;
|
||||
SrcFilename: String;
|
||||
CompilerFilename: String;
|
||||
CompilerParams: String;
|
||||
begin
|
||||
Result:=mrCancel;
|
||||
|
||||
writeln('TPkgManager.DoCompilePackage A ',APackage.IDAsString,' Flags=',PkgCompileFlagsToString(Flags));
|
||||
|
||||
if APackage.AutoCreated then exit;
|
||||
|
||||
// check for broken dependencies
|
||||
PathList:=PackageGraph.FindBrokenDependencyPath(APackage);
|
||||
if PathList<>nil then begin
|
||||
DoShowPackageGraphPathList(PathList);
|
||||
Result:=MessageDlg('Broken dependency',
|
||||
'A required packages was not found. See package graph.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
// check graph for circles and broken dependencies
|
||||
if not (pcfDoNotCompileDependencies in Flags) then begin
|
||||
Result:=CheckPackageGraphForCompilation(APackage);
|
||||
if Result<>mrOk then exit;
|
||||
end;
|
||||
|
||||
// check for circle dependencies
|
||||
PathList:=PackageGraph.FindCircleDependencyPath(APackage);
|
||||
if PathList<>nil then begin
|
||||
DoShowPackageGraphPathList(PathList);
|
||||
Result:=MessageDlg('Circle in package dependencies',
|
||||
'There is a circle in the required packages. See package graph.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
exit;
|
||||
// save all open files
|
||||
if not (pcfAutomatic in Flags) then begin
|
||||
Result:=MainIDE.DoSaveForBuild;
|
||||
if Result<>mrOk then exit;
|
||||
end;
|
||||
|
||||
// create the output directory
|
||||
OutputDir:=APackage.GetOutputDirectory;
|
||||
if not ForceDirectory(OutputDir) then begin
|
||||
Result:=MessageDlg('Unable to create directory',
|
||||
'Unable to create output directory "'+OutputDir+'"'#13
|
||||
+'for package '+APackage.IDAsString+'.',
|
||||
mtError,[mbCancel,mbAbort],0);
|
||||
|
||||
// automatically compile required packages
|
||||
if not (pcfDoNotCompileDependencies in Flags) then begin
|
||||
Result:=CompileRequiredPackages(APackage);
|
||||
if Result<>mrOk then exit;
|
||||
end;
|
||||
|
||||
// check if compilation is neccessary
|
||||
if ([pcfOnlyIfNeeded,pcfCleanCompile]*Flags<>[])
|
||||
and (not CheckIfPackageNeedsCompilation(APackage)) then begin
|
||||
Result:=mrOk;
|
||||
exit;
|
||||
end;
|
||||
|
||||
// save everything
|
||||
Result:=MainIDE.DoSaveForBuild;
|
||||
Result:=DoPreparePackageOutputDirectory(APackage);
|
||||
if Result<>mrOk then exit;
|
||||
|
||||
// update dependencies
|
||||
|
||||
// ToDo
|
||||
|
||||
|
||||
|
||||
// create package main source file
|
||||
Result:=DoSavePackageMainSource(APackage,Flags);
|
||||
if Result<>mrOk then exit;
|
||||
SrcFilename:=CreateRelativePath(OutputDir+APackage.GetCompileSourceFilename,
|
||||
APackage.Directory);
|
||||
|
||||
// create external tool to run the compiler
|
||||
OutputDir:=APackage.GetOutputDirectory;
|
||||
SrcFilename:=CreateRelativePath(OutputDir+APackage.GetCompileSourceFilename,
|
||||
APackage.Directory);
|
||||
CompilerFilename:=APackage.GetCompilerFilename;
|
||||
CompilerParams:=APackage.CompilerOptions.MakeOptionsString(
|
||||
APackage.CompilerOptions.DefaultMakeOptionsFlags)
|
||||
+' '+SrcFilename;
|
||||
|
||||
PkgCompileTool:=TExternalToolOptions.Create;
|
||||
PkgCompileTool.Title:='Compiling package '+APackage.IDAsString;
|
||||
PkgCompileTool.Filename:=APackage.CompilerOptions.CompilerPath;
|
||||
PkgCompileTool.ScanOutputForFPCMessages:=true;
|
||||
PkgCompileTool.ScanOutputForMakeMessages:=true;
|
||||
PkgCompileTool.WorkingDirectory:=APackage.Directory;
|
||||
PkgCompileTool.CmdLineParams:=APackage.CompilerOptions.MakeOptionsString
|
||||
+' '+SrcFilename;
|
||||
try
|
||||
PkgCompileTool.Title:='Compiling package '+APackage.IDAsString;
|
||||
PkgCompileTool.Filename:=CompilerFilename;
|
||||
PkgCompileTool.ScanOutputForFPCMessages:=true;
|
||||
PkgCompileTool.ScanOutputForMakeMessages:=true;
|
||||
PkgCompileTool.WorkingDirectory:=APackage.Directory;
|
||||
PkgCompileTool.CmdLineParams:=CompilerParams;
|
||||
|
||||
// clear old errors
|
||||
SourceNotebook.ClearErrorLines;
|
||||
// clear old errors
|
||||
SourceNotebook.ClearErrorLines;
|
||||
|
||||
// compile package
|
||||
Result:=EnvironmentOptions.ExternalTools.Run(PkgCompileTool,MainIDE.MacroList);
|
||||
// compile package
|
||||
Result:=EnvironmentOptions.ExternalTools.Run(PkgCompileTool,MainIDE.MacroList);
|
||||
if Result=mrOk then begin
|
||||
// compilation succeded -> write state file
|
||||
Result:=DoSavePackageCompiledState(APackage,
|
||||
CompilerFilename,CompilerParams);
|
||||
if Result<>mrOk then exit;
|
||||
end;
|
||||
finally
|
||||
// clean up
|
||||
PkgCompileTool.Free;
|
||||
|
||||
// clean up
|
||||
PkgCompileTool.Free;
|
||||
MainIDE.DoCheckFilesOnDisk;
|
||||
if not (pcfAutomatic in Flags) then begin
|
||||
// check for changed files on disk
|
||||
MainIDE.DoCheckFilesOnDisk;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:=mrOk;
|
||||
end;
|
||||
|
Loading…
Reference in New Issue
Block a user