{$ifdef Delphi} const fpmkunitsrc : array[0..599] of string[240]=( {$else Delphi} const fpmkunitsrc : array[0..599,1..240] of char=( {$endif Delphi} '{'#010+ ' This file is part of the Free Pascal Makefile Package'#010+ #010+ ' Implementation of fpmake classes and functions'#010+ #010+ ' Copyright (c) 2007 by the freepascal team'#010+ #010+ ' See the file COPYING.FPC, included in this distribution,'#010+ ' for details abo','ut the copyright.'#010+ #010+ ' This program is distributed in the hope that it will be useful,'#010+ ' but WITHOUT ANY WARRANTY; without even the implied warranty of'#010+ ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.'#010+ #010+ ' ***************************','****************************************'+ '***}'#010+ #010+ 'unit fpmkunit;'#010+ #010+ '{$Mode objfpc}'#010+ '{$H+}'#010+ '{$inline on}'#010+ #010+ '{ For target or cpu dependent dependencies add also an overload were y'+ 'ou'#010+ ' can pass only a set of cpus. This is disabled for now because it cre', 'ates'#010+ ' an error in the compiler with overload choosing }'#010+ '{ define cpu_only_overloads}'#010+ #010+ 'Interface'#010+ #010+ '{$ifndef NO_UNIT_PROCESS}'#010+ ' {$define HAS_UNIT_PROCESS}'#010+ '{$endif NO_UNIT_PROCESS}'#010+ #010+ '{$ifndef NO_UNIT_ZIPPER}'#010+ ' {$define HAS_UNIT_ZIPPER}'#010+ '{$endif ','NO_UNIT_ZIPPER}'#010+ #010+ 'uses'#010+ ' SysUtils, Classes, StrUtils'#010+ '{$ifdef HAS_UNIT_PROCESS}'#010+ ' ,process'#010+ '{$endif HAS_UNIT_PROCESS}'#010+ '{$ifdef HAS_UNIT_ZIPPER}'#010+ ' ,zipper'#010+ '{$endif HAS_UNIT_ZIPPER}'#010+ ' ;'#010+ #010+ 'Type'#010+ ' TFileType = (ftSource,ftUnit,ftObject,ftResource,ftEx','ecutable,ftSt'+ 'aticLibrary,'#010+ ' ftSharedLibrary);'#010+ ' TFileTypes = set of TFileType;'#010+ #010+ ' // Please keep this order, see OSCPUSupported below'#010+ ' TCpu=(cpuNone,'#010+ ' i386,m68k,powerpc,sparc,x86_64,arm,powerpc64,avr,armeb'#010+ ' );'#010+ ' TCPUS = Se','t of TCPU;'#010+ #010+ ' // Please keep this order, see OSCPUSupported below'#010+ ' TOS=(osNone,'#010+ ' linux,go32v2,win32,os2,freebsd,beos,netbsd,'#010+ ' amiga,atari, solaris, qnx, netware, openbsd,wdosx,'#010+ ' palmos,macos,darwin,emx,watcom,morphos,netwlibc,'#010+ ' ',' win64,wince,gba,nds,embedded,symbian'#010+ ' );'#010+ ' TOSes = Set of TOS;'#010+ #010+ ' TCompilerMode = (cmFPC,cmTP,cmObjFPC,cmDelphi,cmMacPas);'#010+ ' TCompilerModes = Set of TCompilerMode;'#010+ #010+ ' TTargetType = (ttProgram,ttUnit,ttImplicitUnit,ttCleanOnlyUnit,ttExa'+ 'mpl','eUnit,ttExampleProgram);'#010+ ' TTargetTypes = set of TTargetType;'#010+ #010+ ' TTargetState = (tsNeutral,tsConsidering,tsNoCompile,tsCompiled,tsIns'+ 'talled,tsNotFound);'#010+ ' TTargetStates = Set of TTargetState;'#010+ #010+ ' TSourceType = (stDoc,stSrc,stExample,stTest);',#010+ ' TSourceTypes = set of TSourceType;'#010+ #010+ ' TVerboseLevel = (vlError,vlWarning,vlInfo,vldebug,vlCommand);'#010+ ' TVerboseLevels = Set of TVerboseLevel;'#010+ #010+ ' TCommandAt = (caBeforeCompile,caAfterCompile,'#010+ ' caBeforeInstall,caAfterInstall,',#010+ ' caBeforeArchive,caAfterArchive,'#010+ ' caBeforeClean,caAfterClean,'#010+ ' caBeforeDownload,caAfterDownload);'#010+ #010+ ' TDependencyType = (depPackage,depImplicitPackage,depUnit,depInclude)'+ ';'#010+ ' TDependencyTypes = se','t of TDependencyType;'#010+ #010+ ' TLogEvent = Procedure (Level : TVerboseLevel; Const Msg : String) of'+ ' Object;'#010+ #010+ ' TRunMode = (rmCompile,rmBuild,rmInstall,rmArchive,rmClean,rmManifest'+ ');'#010+ #010+ 'Const'#010+ ' // Aliases'#010+ ' Amd64 = X86_64;'#010+ ' PPC = PowerPC;'#010+ ' PPC64',' = PowerPC64;'#010+ ' DOS = Go32v2;'#010+ ' MacOSX = Darwin;'#010+ #010+ ' AllOSes = [Low(TOS)..High(TOS)];'#010+ ' AllCPUs = [Low(TCPU)..High(TCPU)];'#010+ ' AllUnixOSes = [Linux,FreeBSD,NetBSD,OpenBSD,Darwin,QNX,BeOS,Solaris'+ '];'#010+ ' AllBSDOSes = [FreeBSD,NetBSD,OpenBSD,D','arwin];'#010+ ' AllWindowsOSes = [Win32,Win64,WinCE];'#010+ #010+ ' { This table is kept OS,Cpu because it is easier to maintain (PFV) }'+ #010+ ' OSCPUSupported : array[TOS,TCpu] of boolean = ('#010+ ' { os none i386 m68k ppc sparc x86_64 arm pp', 'c64 avr armeb}'#010+ ' { none } ( false, false, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { linux } ( false, true, true, true, true, true, true, tru'+ 'e, false, true ),'#010+ ' { go32v2 } ( false, true, false, fals','e, false, false, false, f'+ 'alse, false, false),'#010+ ' { win32 } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { os2 } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { freebsd } ','( false, true, true, false, false, true, false, f'+ 'alse, false, false),'#010+ ' { beos } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { netbsd } ( false, true, true, true, true, false, false, fal'+ 'se, fals','e, false),'#010+ ' { amiga } ( false, false, true, true, false, false, false, fal'+ 'se, false, false),'#010+ ' { atari } ( false, false, true, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { solaris } ( false, true, false, false, true,',' false, false, f'+ 'alse, false, false),'#010+ ' { qnx } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { netware } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { openbsd } ( false,',' true, true, false, false, false, false, f'+ 'alse, false, false),'#010+ ' { wdosx } ( false, true, false, false, false, false, false, fal'+ 'se, false, false),'#010+ ' { palmos } ( false, false, true, false, false, false, true, fal'+ 'se, false, false','),'#010+ ' { macos } ( false, false, false, true, false, false, false, fal'+ 'se, false, false),'#010+ ' { darwin } ( false, true, false, true, false, true, true, tru'+ 'e, false, false),'#010+ ' { emx } ( false, true, false, false, false, false,',' false, f'+ 'alse, false, false),'#010+ ' { watcom } ( false, true, false, false, false ,false, false, fal'+ 'se, false, false),'#010+ ' { morphos } ( false, false, false, true, false ,false, false, fal'+ 'se, false, false),'#010+ ' { netwlibc }( false, true, ','false, false, false, false, false, f'+ 'alse, false, false),'#010+ ' { win64 } ( false, false, false, false, false, true, false, fal'+ 'se, false, false),'#010+ ' { wince }( false, true, false, false, false, false, true, fal'+ 'se, false, false),'#010+ ' {',' gba } ( false, false, false, false, false, false, true, f'+ 'alse, false, false),'#010+ ' { nds } ( false, false, false, false, false, false, true, fal'+ 'se, false, false),'#010+ ' { embedded }( false, true, true, true, true, true, true, ','t'+ 'rue, true, true ),'#010+ ' { symbian } ( false, true, false, false, false, false, true, fal'+ 'se, false, false)'#010+ ' );'#010+ #010+ ' // Useful'#010+ ' UnitExt = '#039'.ppu'#039';'#010+ ' PPUExt = UnitExt;'#010+ ' PasExt = '#039'.pas'#039';'#010+ ' PPExt = '#039'.pp'#039';'#010+ ' IncExt = '#039'.inc'#039';'#010+ ' ObjExt = ',#039'.o'#039';'#010+ ' RstExt = '#039'.rst'#039';'#010+ ' LibExt = '#039'.a'#039';'#010+ ' SharedLibExt = '#039'.so'#039';'#010+ ' DLLExt = '#039'.dll'#039';'#010+ ' ExeExt = '#039'.exe'#039';'#010+ ' ZipExt = '#039'.zip'#039';'#010+ #010+ ' FPMakePPFile = '#039'fpmake.pp'#039';'#010+ ' ManifestFile = '#039'manifest.xml'#039';'#010+ ' UnitConfigFile = '#039'fpunits.conf'#039';'#010+ #010+ ' DirNotFoun','d = '#039''#039';'#010+ #010+ ' UnitTargets = [ttUnit,ttImplicitUnit,ttCleanOnlyUnit,ttExampleUnit];'+ #010+ ' ProgramTargets = [ttProgram,ttExampleProgram];'#010+ #010+ ' DefaultMessages = [vlError,vlWarning,vlCommand];'#010+ ' AllMessages = [vlError,vlWarning,vlCommand,v','lInfo];'#010+ #010+ #010+ 'Type'#010+ ' { TNamedItem }'#010+ #010+ ' TNamedItem = Class(TCollectionItem)'#010+ ' private'#010+ ' FName: String;'#010+ ' procedure SetName(const AValue: String);virtual;'#010+ ' Public'#010+ ' property Name : String Read FName Write SetName;'#010+ ' end;'#010+ #010+ ' { TNamedCollect','ion }'#010+ #010+ ' TNamedCollection = Class(TCollection)'#010+ ' private'#010+ ' FUniqueNames: Boolean;'#010+ ' Public'#010+ ' Function IndexOfName(const AName : String) : Integer;'#010+ ' Function ItemByName(const AName : String) : TNamedItem;'#010+ ' Property UniqueNames : Bo','olean Read FUniqueNames;'#010+ ' end;'#010+ #010+ ' { TNamedItemList }'#010+ #010+ ' TNamedItemList = Class(TFPList)'#010+ ' private'#010+ ' function GetNamedItem(Index : Integer): TNamedItem;'#010+ ' procedure SetNamedItem(Index : Integer; const AValue: TNamedItem);'+ #010+ ' public'#010+ ' F','unction IndexOfName(const AName : String) : Integer;'#010+ ' Function ItemByName(const ANAme : String) : TNamedItem;'#010+ ' Property NamedItems[Index : Integer] : TNamedItem Read GetNamedIte'+ 'm Write SetNamedItem; default;'#010+ ' end;'#010+ #010+ ' { TCommand }'#010+ ' T','Command = Class(TNamedItem)'#010+ ' private'#010+ ' FAfterCommand: TNotifyEvent;'#010+ ' FBeforeCommand: TNotifyEvent;'#010+ ' FCommand: String;'#010+ ' FCommandAt: TCommandAt;'#010+ ' FDestFile: String;'#010+ ' FIgnoreResult: Boolean;'#010+ ' FOptions: String;'#010+ ' FSourceF','ile: String;'#010+ ' Public'#010+ ' Property SourceFile : String Read FSourceFile Write FSourceFile;'#010+ ' Property DestFile : String Read FDestFile Write FDestFile;'#010+ ' Property Command : String Read FCommand Write FCommand;'#010+ ' Property Options : Str','ing Read FOptions Write FOptions;'#010+ ' Property At : TCommandAt Read FCommandAt Write FCommandAt;'#010+ ' Property IgnoreResult : Boolean Read FIgnoreResult Write FIgnoreRe'+ 'sult;'#010+ ' Property BeforeCommand : TNotifyEvent Read FBeforeCommand Write',' '+ 'FBeforeCommand;'#010+ ' Property AfterCommand : TNotifyEvent Read FAfterCommand Write FAft'+ 'erCommand;'#010+ ' end;'#010+ #010+ ' { TCommands }'#010+ #010+ ' TCommands = Class(TNamedCollection)'#010+ ' private'#010+ ' FDefaultAt: TCommandAt;'#010+ ' function GetCommand(const Dest : Stri','ng): TCommand;'#010+ ' function GetCommandItem(Index : Integer): TCommand;'#010+ ' procedure SetCommandItem(Index : Integer; const AValue: TCommand);'+ #010+ ' Public'#010+ ' Function AddCommand(Const Cmd : String) : TCommand;'#010+ ' Function AddCommand(Const Cmd',',Options : String) : TCommand;'#010+ ' Function AddCommand(Const Cmd,Options,Dest,Source : String) : TCom'+ 'mand;'#010+ ' Function AddCommand(At : TCommandAt; Const Cmd : String) : TComman'+ 'd;'#010+ ' Function AddCommand(At : TCommandAt; Const Cmd,Options :',' String)'+ ' : TCommand;'#010+ ' Function AddCommand(At : TCommandAt; Const Cmd,Options, Dest,Sourc'+ 'e : String) : TCommand;'#010+ ' Property CommandItems[Index : Integer] : TCommand Read GetCommandI'+ 'tem Write SetCommandItem;'#010+ ' Property Commands[Dest : ','String] : TCommand Read GetCommand; def'+ 'ault;'#010+ ' Property DefaultAt : TCommandAt Read FDefaultAt Write FDefaultAt;'#010+ ' end;'#010+ #010+ ' { TFPVersion }'#010+ #010+ ' TFPVersion = Class(TPersistent)'#010+ ' private'#010+ ' FMajor,'#010+ ' FMinor,'#010+ ' FMicro,'#010+ ' FBuild : Wor','d;'#010+ ' function GetAsString: String;'#010+ ' function GetEmpty: Boolean;'#010+ ' procedure SetAsString(const AValue: String);'#010+ ' Public'#010+ ' Procedure Clear;'#010+ ' Procedure Assign(Source : TPersistent); override;'#010+ ' Function CompareVersion(AVersion : TF','PVersion) : Integer;'#010+ ' Function SameVersion(AVersion : TFPVersion) : Boolean;'#010+ ' Property AsString : String Read GetAsString Write SetAsString;'#010+ ' Property Empty : Boolean Read GetEmpty;'#010+ ' Published'#010+ ' Property Major : Word Read FMajor Wri','te FMajor;'#010+ ' Property Minor : Word Read FMinor Write FMinor;'#010+ ' Property Micro : Word Read FMicro Write FMicro;'#010+ ' Property Build : Word Read FBuild Write FBuild;'#010+ ' end;'#010+ #010+ ' { TConditionalString }'#010+ ' TConditionalString = Class'#010+ ' private'#010+ ' ','FOSes : TOSes;'#010+ ' FCPUs : TCPUs;'#010+ ' FValue : String;'#010+ ' Public'#010+ ' Constructor Create;virtual;'#010+ ' Property Value : String Read FValue Write FValue;'#010+ ' Property OSes : TOSes Read FOSes Write FOSes;'#010+ ' Property CPUs : TCPUs Read FCP','US Write FCPUs;'#010+ ' end;'#010+ #010+ ' TConditionalStringClass = class of TConditionalString;'#010+ #010+ ' { TConditionalStrings }'#010+ #010+ ' TConditionalStrings = Class(TFPList)'#010+ ' private'#010+ ' FCSClass : TConditionalStringClass;'#010+ ' function GetConditionalString(Index : ','Integer): TConditionalStri'+ 'ng;'#010+ ' procedure SetConditionalString(Index : Integer; const AValue: TCon'+ 'ditionalString);'#010+ ' Public'#010+ ' Constructor Create(AClass:TConditionalStringClass);'#010+ ' Function Add(Const Value : String) : TConditionalStrin','g;inline;'#010+ ' Function Add(Const Value : String;const OSes:TOSes) : TConditional'+ 'String;inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function Add(Const Value : String;const CPUs:TCPUs) : TConditional'+ 'String;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' ','Function Add(Const Value : String;const CPUs:TCPUs;const OSes:TO'+ 'Ses) : TConditionalString;'#010+ ' Property ConditionalStrings[Index : Integer] : TConditionalString '+ 'Read GetConditionalString Write SetConditionalString; default;'#010+ ' end;'#010+ #010+ ' { TDep','endency }'#010+ ' TDependency = Class(TConditionalString)'#010+ ' private'#010+ ' FDependencyType : TDependencyType;'#010+ ' // Package, Unit'#010+ ' FTarget : TObject;'#010+ ' FVersion : TFPVersion;'#010+ ' FRequireChecksum : Cardinal;'#010+ ' // Filenames, Includes'#010+ ' FTar','getFileName : String;'#010+ ' Function GetVersion : string;'#010+ ' Procedure SetVersion(const V : string);'#010+ ' Public'#010+ ' Constructor Create;override;'#010+ ' Destructor Destroy;override;'#010+ ' Property Target : TObject Read FTarget Write FTarget;'#010+ ' Pro','perty DependencyType : TDependencyType Read FDependencyType;'#010+ ' Property TargetFileName : String Read FTargetFileName Write FTarge'+ 'tFileName;'#010+ ' Property Version : String Read GetVersion Write SetVersion;'#010+ ' Property RequireChecksum : Car','dinal Read FRequireChecksum Write '+ 'FRequireChecksum;'#010+ ' end;'#010+ #010+ ' TDependencies = Class(TConditionalStrings)'#010+ ' function GetDependency(Index : Integer): TDependency;'#010+ ' procedure SetDependency(Index : Integer; const AValue: TDependency'+ ');'#010+ ' Pu','blic'#010+ ' Function Add(Const Value : String) : TDependency;inline;'#010+ ' Function Add(Const Value : String;const OSes:TOSes) : TDependency;'+ 'inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function Add(Const Value : String;const CPUs:TCPUs) : TDependenc','y'+ ';inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function Add(Const Value : String;const CPUs:TCPUs;const OSes:TOSe'+ 's) : TDependency;'#010+ ' Function AddUnit(Const Value : String) : TDependency;inline;'#010+ ' Function AddUnit(Const Value : String;const O','Ses:TOSes) : TDepen'+ 'dency;inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function AddUnit(Const Value : String;const CPUs:TCPUs) : TDepende'+ 'ncy;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function AddUnit(Const Value : String;const CPUs:TCPUs;const OSes', ':TOSes) : TDependency;'#010+ ' Function AddInclude(Const Value : String) : TDependency;inline;'#010+ ' Function AddInclude(Const Value : String;const OSes:TOSes) : TDepe'+ 'ndency;inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function AddInclude(Const Value ',': String;const CPUs:TCPUs) : TDe'+ 'pendency;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function AddInclude(Const Value : String;const CPUs:TCPUs;const OS'+ 'es:TOSes) : TDependency;'#010+ ' Property Dependencies[Index : Integer] : TDependency Read GetDep','e'+ 'ndency Write SetDependency; default;'#010+ ' end;'#010+ #010+ ' { TTarget }'#010+ #010+ ' TTarget = Class(TNamedItem)'#010+ ' private'#010+ ' FInstall : Boolean;'#010+ ' FAfterClean: TNotifyEvent;'#010+ ' FAfterCompile: TNotifyEvent;'#010+ ' FBeforeClean: TNotifyEvent;'#010+ ' FBeforeCompile:',' TNotifyEvent;'#010+ ' FCPUs: TCPUs;'#010+ ' FOSes: TOSes;'#010+ ' FMode: TCompilerMode;'#010+ ' FResourceStrings: Boolean;'#010+ ' FObjectPath,'#010+ ' FUnitPath,'#010+ ' FIncludePath : TConditionalStrings;'#010+ ' FDependencies : TDependencies;'#010+ ' FCommands : TCommands',';'#010+ ' FDirectory: String;'#010+ ' FExtension: String;'#010+ ' FTargetSourceFileName : String;'#010+ ' FFileType: TFileType;'#010+ ' FOptions: String;'#010+ ' FFPCTarget: String;'#010+ ' FTargetState: TTargetState;'#010+ ' FTargetType: TTargetType;'#010+ ' Protected'#010+ ' Func','tion GetSourceFileName : String; virtual;'#010+ ' Function GetUnitFileName : String; virtual;'#010+ ' Function GetObjectFileName : String; virtual;'#010+ ' Function GetRSTFileName : String; Virtual;'#010+ ' Function GetProgramFileName(AOS : TOS) : String; ','Virtual;'#010+ ' Public'#010+ ' Constructor Create(ACollection : TCollection); override;'#010+ ' Destructor Destroy; override;'#010+ ' Function GetOutputFileName (AOs : TOS) : String; Virtual;'#010+ ' procedure SetName(const AValue: String);override;'#010+ ' Proced','ure GetCleanFiles(List : TStrings; const APrefixU, APrefix'+ 'B : String; ACPU:TCPU; AOS : TOS); virtual;'#010+ ' Procedure GetInstallFiles(List : TStrings; const APrefixU, APrefix'+ 'B: String; ACPU:TCPU; AOS : TOS); virtual;'#010+ ' Procedure GetArchiveF','iles(List : TStrings; ACPU:TCPU; AOS : TOS)'+ '; virtual;'#010+ ' Property Dependencies : TDependencies Read FDependencies;'#010+ ' Property Commands : TCommands Read FCommands;'#010+ ' Property State : TTargetState Read FTargetState;'#010+ ' Property TargetTy','pe : TTargetType Read FTargetType Write FTarget'+ 'Type;'#010+ ' Property OSes : TOSes Read FOSes Write FOSes;'#010+ ' Property CPUs : TCPUs Read FCPUs Write FCPUs;'#010+ ' Property Mode : TCompilerMode Read FMode Write FMode;'#010+ ' Property Options : String',' Read FOptions Write Foptions;'#010+ ' Property SourceFileName: String Read GetSourceFileName ;'#010+ ' Property UnitFileName : String Read GetUnitFileName;'#010+ ' Property ObjectFileName : String Read GetObjectFileName;'#010+ ' Property RSTFileName : Str','ing Read GetRSTFileName;'#010+ ' Property FPCTarget : String Read FFPCTarget Write FFPCTarget;'#010+ ' Property Extension : String Read FExtension Write FExtension;'#010+ ' Property FileType : TFileType Read FFileType Write FFileType;'#010+ ' Property Dire','ctory : String Read FDirectory Write FDirectory;'#010+ ' Property ResourceStrings : Boolean Read FResourceStrings Write FRe'+ 'sourceStrings;'#010+ ' Property Install : Boolean Read FInstall Write FInstall;'#010+ ' Property TargetSourceFileName: String Rea','d FTargetSourceFileName'+ ';'#010+ ' Property ObjectPath : TConditionalStrings Read FObjectPath;'#010+ ' Property UnitPath : TConditionalStrings Read FUnitPath;'#010+ ' Property IncludePath : TConditionalStrings Read FIncludePath;'#010+ ' // Events.'#010+ ' Proper','ty BeforeCompile : TNotifyEvent Read FBeforeCompile Write '+ 'FBeforeCompile;'#010+ ' Property AfterCompile : TNotifyEvent Read FAfterCompile Write FAft'+ 'erCompile;'#010+ ' Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBefor'+ 'eClean;'#010+ ' Pro','perty AfterClean : TNotifyEvent Read FAfterClean Write FAfter'+ 'Clean;'#010+ ' end;'#010+ #010+ ' { TTargets }'#010+ #010+ ' TTargets = Class(TNamedCollection)'#010+ ' private'#010+ ' function GetTargetItem(Index : Integer): TTarget;'#010+ ' function GetTarget(const AName : String): T','Target;'#010+ ' procedure SetTargetItem(Index : Integer; const AValue: TTarget);'#010+ ' Public'#010+ ' Function AddUnit(Const AUnitName : String) : TTarget;inline;'#010+ ' Function AddUnit(Const AUnitName : String;const OSes:TOSes) : TTar'+ 'get;inline;'#010+ '{$ifdef',' cpu_only_overloads}'#010+ ' Function AddUnit(Const AUnitName : String;const CPUs:TCPUs) : TTar'+ 'get;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function AddUnit(Const AUnitName : String;const CPUs:TCPUs;const O'+ 'Ses:TOSes) : TTarget;'#010+ ' Function AddI','mplicitUnit(Const AUnitName : String;InstallUnit:bo'+ 'olean=true) : TTarget;inline;'#010+ ' Function AddImplicitUnit(Const AUnitName : String;const OSes:TOSes'+ ';InstallUnit:boolean=true) : TTarget;inline;'#010+ ' Function AddImplicitUnit(Const AUnitName',' : String;const CPUs:TCP'+ 'Us;InstallUnit:boolean=true) : TTarget;inline;'#010+ ' Function AddImplicitUnit(Const AUnitName : String;const CPUs:TCPUs'+ ';const OSes:TOSes;InstallUnit:boolean=true) : TTarget;'#010+ ' Function AddProgram(Const AProgramName :',' String) : TTarget;inlin'+ 'e;'#010+ ' Function AddProgram(Const AProgramName : String;const OSes:TOSes) '+ ': TTarget;inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function AddProgram(Const AProgramName : String;const CPUs:TCPUs) '+ ': TTarget;inline;'#010+ '{$endif c','pu_only_overloads}'#010+ ' Function AddProgram(Const AProgramName : String;const CPUs:TCPUs;c'+ 'onst OSes:TOSes) : TTarget;'#010+ ' Function AddExampleUnit(Const AUnitName : String) : TTarget;inline'+ ';'#010+ ' Function AddExampleUnit(Const AUnitName : Strin','g;const OSes:TOSe'+ 's) : TTarget;inline;'#010+ '{$ifdef cpu_only_overloads}'#010+ ' Function AddExampleUnit(Const AUnitName : String;const CPUs:TCPUs)'+ ' : TTarget;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function AddExampleUnit(Const AUnitName : String;cons','t CPUs:TCPU'+ 's;const OSes:TOSes) : TTarget;'#010+ ' Function AddExampleProgram(Const AProgramName : String) : TTarget;'+ 'inline;'#010+ ' Function AddExampleProgram(Const AProgramName : String;const OSes:'+ 'TOSes) : TTarget;inline;'#010+ '{$ifdef cpu_only_overload','s}'#010+ ' Function AddExampleProgram(Const AProgramName : String;const CPUs:'+ 'TCPUs) : TTarget;inline;'#010+ '{$endif cpu_only_overloads}'#010+ ' Function AddExampleProgram(Const AProgramName : String;const CPUs:'+ 'TCPUs;const OSes:TOSes) : TTarget;'#010+ ' Prope','rty Targets[AName : String] : TTarget Read GetTarget; defau'+ 'lt;'#010+ ' Property TargetItems[Index : Integer] : TTarget Read GetTargetItem'+ ' Write SetTargetItem;'#010+ ' end;'#010+ #010+ ' { TSource }'#010+ #010+ ' TSource = Class(TNamedItem)'#010+ ' private'#010+ ' FSourceType : TSou','rceType;'#010+ ' Public'#010+ ' Constructor Create(ACollection : TCollection); override;'#010+ ' Destructor Destroy; override;'#010+ ' property SourceType : TSourceType read FSourceType;'#010+ ' end;'#010+ #010+ ' { TSources }'#010+ #010+ ' TSources = Class(TNamedCollection)'#010+ ' private'#010, ' function GetSourceItem(Index : Integer): TSource;'#010+ ' procedure SetSourceItem(Index : Integer; const AValue: TSource);'#010+ ' public'#010+ ' Function AddDoc(const AFiles : String) : TSource;'#010+ ' Function AddSrc(const AFiles : String) : TSource;'#010, ' Function AddExample(const AFiles : String) : TSource;'#010+ ' Function AddTest(const AFiles : String) : TSource;'#010+ ' procedure AddDocFiles(const AFileMask: string; Recursive: boolean '+ '= False);'#010+ ' procedure AddSrcFiles(const AFileMask: stri','ng; Recursive: boolea'+ 'n = False);'#010+ ' procedure AddExampleFiles(const AFileMask: string; Recursive: bool'+ 'ean = False);'#010+ ' procedure AddTestFiles(const AFileMask: string; Recursive: boolean'+ ' = False);'#010+ ' Property SourceItems[Index : Integer] ',': TSource Read GetSourceIt'+ 'em Write SetSourceItem;default;'#010+ ' end;'#010+ #010+ ' { TPackage }'#010+ #010+ ' TPackage = Class(TNamedItem)'#010+ ' private'#010+ ' FAfterArchive: TNotifyEvent;'#010+ ' FAfterClean: TNotifyEvent;'#010+ ' FAfterCompile: TNotifyEvent;'#010+ ' FAfterInstall: T','NotifyEvent;'#010+ ' FAfterManifest: TNotifyEvent;'#010+ ' FBeforeArchive: TNotifyEvent;'#010+ ' FBeforeClean: TNotifyEvent;'#010+ ' FBeforeCompile: TNotifyEvent;'#010+ ' FBeforeInstall: TNotifyEvent;'#010+ ' FBeforeManifest: TNotifyEvent;'#010+ ' FUnitPath,'#010+ ' FObje','ctPath,'#010+ ' FIncludePath,'#010+ ' FSourcePath,'#010+ ' FExamplePath,'#010+ ' FTestPath,'#010+ ' FCleanFiles,'#010+ ' FInstallFiles : TConditionalStrings;'#010+ ' FDependencies : TDependencies;'#010+ ' FCPUs: TCPUs;'#010+ ' FOSes: TOSes;'#010+ ' FTargetState: TTargetState;'#010+ ' ',' FTargets: TTargets;'#010+ ' FSources: TSources;'#010+ ' FDirectory: String;'#010+ ' FOptions: String;'#010+ ' FFileName: String;'#010+ ' FAuthor: String;'#010+ ' FLicense: String;'#010+ ' FHomepageURL: String;'#010+ ' FDownloadURL: String;'#010+ ' FVersion: TFPVersion;'#010+ ' F','Email : String;'#010+ ' FNeedLibC : Boolean;'#010+ ' FCommands : TCommands;'#010+ ' FDescriptionFile : String;'#010+ ' FDescription : String;'#010+ ' FInstalledChecksum : Cardinal;'#010+ ' // Cached directory of installed packages'#010+ ' FUnitDir : String;'#010+ ' Functi','on GetDescription : string;'#010+ ' Function GetFileName : string;'#010+ ' Function GetVersion : string;'#010+ ' Procedure SetVersion(const V : string);'#010+ ' Protected'#010+ ' procedure SetName(const AValue: String);override;'#010+ ' procedure LoadUnitConfigFromF','ile(Const AFileName: String);'#010+ ' procedure SaveUnitConfigToFile(Const AFileName: String;ACPU:TCPU;A'+ 'OS:TOS);'#010+ ' Public'#010+ ' constructor Create(ACollection: TCollection); override;'#010+ ' destructor destroy; override;'#010+ ' Function GetUnitsOutput','Dir(ACPU:TCPU; AOS : TOS):String;'#010+ ' Function GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;'#010+ ' Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); vi'+ 'rtual;'#010+ ' procedure GetInstallFiles(List: TStrings;Types : TTargetTypes;A','C'+ 'PU:TCPU; AOS : TOS);'#010+ ' Procedure GetArchiveFiles(List : TStrings; ACPU:TCPU; AOS : TOS); '+ 'virtual;'#010+ ' Procedure GetManifest(Manifest : TStrings);'#010+ ' Property Version : String Read GetVersion Write SetVersion;'#010+ ' Property FileName : Str','ing Read GetFileName Write FFileName;'#010+ ' Property HomepageURL : String Read FHomepageURL Write FHomepageURL'+ ';'#010+ ' Property DownloadURL : String Read FDownloadURL Write FDownloadURL'+ ';'#010+ ' Property Email : String Read FEmail Write FEmail;'#010+ ' ','Property Author : String Read FAuthor Write FAuthor;'#010+ ' Property License : String Read FLicense Write FLicense;'#010+ ' Property Directory : String Read FDirectory Write FDirectory;'#010+ ' Property Description : String Read GetDescription Write F','Descrip'+ 'tion;'#010+ ' Property DescriptionFile : String Read FDescriptionFile Write FDes'+ 'criptionFile;'#010+ ' Property InstalledChecksum : Cardinal Read FInstalledChecksum Writ'+ 'e FInstalledChecksum;'#010+ ' // Compiler options.'#010+ ' Property OSes : TOSes ','Read FOSes Write FOSes;'#010+ ' Property CPUs : TCPUs Read FCPUs Write FCPUs;'#010+ ' Property NeedLibC : Boolean Read FNeedLibC Write FNeedLibC;'#010+ ' Property Options: String Read FOptions Write FOptions;'#010+ ' Property UnitPath : TConditionalStrings',' Read FUnitPath;'#010+ ' Property ObjectPath : TConditionalStrings Read FObjectPath;'#010+ ' Property IncludePath : TConditionalStrings Read FIncludePath;'#010+ ' Property SourcePath : TConditionalStrings Read FSourcePath;'#010+ ' Property ExamplePath : TC','onditionalStrings Read FExamplePath;'#010+ ' Property TestPath : TConditionalStrings Read FTestPath;'#010+ ' // Targets and dependencies'#010+ ' Property InstallFiles : TConditionalStrings Read FInstallFiles;'#010+ ' Property CleanFiles : TConditionalStrin','gs Read FCleanFiles;'#010+ ' Property Dependencies : TDependencies Read FDependencies;'#010+ ' Property Commands : TCommands Read FCommands;'#010+ ' Property State : TTargetState Read FTargetState;'#010+ ' Property Targets : TTargets Read FTargets;'#010+ ' Pro','perty Sources : TSources Read FSources;'#010+ ' Property UnitDir : String Read FUnitDir Write FUnitDir;'#010+ ' // events'#010+ ' Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FB'+ 'eforeCompile;'#010+ ' Property AfterCompile : TNotifyEvent R','ead FAfterCompile Write FA'+ 'fterCompile;'#010+ ' Property BeforeInstall : TNotifyEvent Read FBeforeInstall Write FB'+ 'eforeInstall;'#010+ ' Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAft'+ 'erInstall;'#010+ ' Property BeforeClean : TNotifyEv','ent Read FBeforeClean Write FBef'+ 'oreClean;'#010+ ' Property AfterClean : TNotifyEvent Read FAfterClean Write FAfterCl'+ 'ean;'#010+ ' Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FB'+ 'eforeArchive;'#010+ ' Property AfterArchive : TNotifyEven','t Read FAfterArchive Write FA'+ 'fterArchive;'#010+ ' Property BeforeManifest : TNotifyEvent Read FBeforeManifest Write '+ 'FBeforeManifest;'#010+ ' Property AfterManifest : TNotifyEvent Read FAfterManifest Write FA'+ 'fterManifest;'#010+ ' end;'#010+ #010+ ' { TPackages }'#010+ #010+ ' ','TPackages = Class(TNamedCollection)'#010+ ' private'#010+ ' function GetPackage(const AName : String): TPackage;'#010+ ' function GetPackageItem(AIndex : Integer): TPackage;'#010+ ' procedure SetPackageItem(AIndex : Integer; const AValue: TPackage)'+ ';'#010+ ' Public',#010+ ' Function AddPackage(Const AName : String) : TPackage;'#010+ ' Property Packages[AName : String] : TPackage Read GetPackage ; Def'+ 'ault;'#010+ ' Property PackageItems[AIndex : Integer] : TPackage Read GetPackage'+ 'Item Write SetPackageItem;'#010+ ' end;'#010+ #010, ' { TCustomDefaults }'#010+ #010+ ' TCustomDefaults = Class(TPersistent)'#010+ ' Private'#010+ ' FArchive: String;'#010+ ' FCompiler: String;'#010+ ' FCopy: String;'#010+ ' FMkDir: String;'#010+ ' FMove: String;'#010+ ' FOptions: String;'#010+ ' FCPU: TCPU;'#010+ ' FOS: TOS;'#010+ ' FMode : T','CompilerMode;'#010+ ' FCompilerVersion : String;'#010+ ' FPrefix: String;'#010+ ' FLocalUnitDir,'#010+ ' FGlobalUnitDir,'#010+ ' FBaseInstallDir,'#010+ ' FUnitInstallDir,'#010+ ' FBinInstallDir,'#010+ ' FDocInstallDir,'#010+ ' FExamplesInstallDir : String;'#010+ ' FRemove: String',';'#010+ ' FTarget: String;'#010+ ' FUnixPaths: Boolean;'#010+ ' FNoFPCCfg: Boolean;'#010+ ' function GetLocalUnitDir: String;'#010+ ' function GetGlobalUnitDir: String;'#010+ ' function GetBaseInstallDir: String;'#010+ ' function GetBinInstallDir: String;'#010+ ' function',' GetCompiler: String;'#010+ ' function GetDocInstallDir: String;'#010+ ' function GetExamplesInstallDir: String;'#010+ ' function GetUnitInstallDir: String;'#010+ ' procedure SetLocalUnitDir(const AValue: String);'#010+ ' procedure SetGlobalUnitDir(const AValu','e: String);'#010+ ' procedure SetBaseInstallDir(const AValue: String);'#010+ ' procedure SetCPU(const AValue: TCPU);'#010+ ' procedure SetOS(const AValue: TOS);'#010+ ' procedure SetPrefix(const AValue: String);'#010+ ' procedure SetTarget(const AValue: String',');'#010+ ' Protected'#010+ ' procedure RecalcTarget;'#010+ ' Public'#010+ ' Constructor Create;'#010+ ' Procedure InitDefaults;'#010+ ' procedure CompilerDefaults; virtual;'#010+ ' Procedure LocalInit(Const AFileName : String);'#010+ ' Procedure LoadFromFile(Const AFileName :',' String);'#010+ ' Procedure SaveToFile(Const AFileName : String);'#010+ ' procedure SaveToStream(S : TStream);virtual;'#010+ ' procedure LoadFromStream(S : TStream);virtual;'#010+ ' // Compile Information'#010+ ' Property Target : String Read FTarget Write Set','Target;'#010+ ' Property OS : TOS Read FOS Write SetOS;'#010+ ' Property CPU : TCPU Read FCPU Write SetCPU;'#010+ ' Property Mode : TCompilerMode Read FMode Write FMode;'#010+ ' Property UnixPaths : Boolean Read FUnixPaths Write FUnixPaths;'#010+ ' Property Op','tions : String Read FOptions Write FOptions; // De'+ 'fault compiler options.'#010+ ' Property NoFPCCfg : Boolean Read FNoFPCCfg Write FNoFPCCfg;'#010+ ' // paths etc.'#010+ ' Property LocalUnitDir : String Read GetLocalUnitDir Write SetLocal'+ 'UnitDir;'#010+ ' ',' Property GlobalUnitDir : String Read GetGlobalUnitDir Write SetG'+ 'lobalUnitDir;'#010+ ' Property Prefix : String Read FPrefix Write SetPrefix;'#010+ ' Property BaseInstallDir : String Read GetBaseInstallDir Write SetB'+ 'aseInstallDir;'#010+ ' Property Uni','tInstallDir : String Read GetUnitInstallDir Write FU'+ 'nitInstallDir;'#010+ ' Property BinInstallDir : String Read GetBinInstallDir Write FBinIn'+ 'stallDir;'#010+ ' Property DocInstallDir : String Read GetDocInstallDir Write FDocIn'+ 'stallDir;'#010+ ' Property ','ExamplesInstallDir : String Read GetExamplesInstallDir '+ 'Write FExamplesInstallDir;'#010+ ' // Command tools. If not set, internal commands will be used.'#010+ ' Property Compiler : String Read GetCompiler Write FCompiler; // Co'+ 'mpiler. Defaults to f','pc'#010+ ' Property Copy : String Read FCopy Write FCopy; // copy'+ ' $(FILES) to $(DEST)'#010+ ' Property Move : String Read FMove Write FMove; // Move'+ ' $(FILES) to $(DEST)'#010+ ' Property Remove : String Read FRemove Write FRemove','; // De'+ 'lete $(FILES)'#010+ ' Property MkDir : String Read FMkDir write FMkDir; // Make'+ ' $(DIRECTORY)'#010+ ' Property Archive : String Read FArchive Write FArchive; // zip '+ '$(ARCHIVE) $(FILESORDIRS)'#010+ ' end;'#010+ #010+ ' { TBasicDefaults }'#010+ #010+ ' T','BasicDefaults = Class(TCustomDefaults)'#010+ ' end;'#010+ #010+ ' { TFPCDefaults }'#010+ #010+ ' TFPCDefaults = Class(TCustomDefaults)'#010+ ' public'#010+ ' procedure CompilerDefaults; override;'#010+ ' end;'#010+ #010+ ' { TBuildEngine }'#010+ #010+ ' TBuildEngine = Class(TComponent)'#010+ ' private'#010+ ' // ge','neral variables'#010+ ' FCompiler : String;'#010+ ' FStartDir : String;'#010+ ' FForceCompile : Boolean;'#010+ ' FListMode : Boolean;'#010+ '{$ifdef HAS_UNIT_ZIPPER}'#010+ ' FZipFile: TZipper;'#010+ '{$endif HAS_UNIT_ZIPPER}'#010+ ' FExternalPackages : TPackages;'#010+ ' // Logging',#010+ ' FLogPrefix : String;'#010+ ' // Events'#010+ ' FOnLog: TLogEvent;'#010+ ' FAfterArchive: TNotifyEvent;'#010+ ' FAfterClean: TNotifyEvent;'#010+ ' FAfterCompile: TNotifyEvent;'#010+ ' FAfterInstall: TNotifyEvent;'#010+ ' FAfterManifest: TNotifyEvent;'#010+ ' FBeforeAr','chive: TNotifyEvent;'#010+ ' FBeforeClean: TNotifyEvent;'#010+ ' FBeforeCompile: TNotifyEvent;'#010+ ' FBeforeInstall: TNotifyEvent;'#010+ ' FBeforeManifest: TNotifyEvent;'#010+ ' Protected'#010+ ' Procedure Error(const Msg : String);'#010+ ' Procedure Error(const Fmt :',' String; const Args : Array of const)'+ ';'#010+ ' // Internal copy/delete/move/archive/mkdir files'#010+ ' Function SysDirectoryExists(const ADir:string):Boolean;'#010+ ' Function SysFileExists(const AFileName:string):Boolean;'#010+ ' Procedure SysCopyFile(','Const Src,Dest : String); virtual;'#010+ ' Procedure SysMoveFile(Const Src,Dest : String); virtual;'#010+ ' Procedure SysDeleteFile(Const AFileName : String); virtual;'#010+ ' Procedure SysArchiveFiles(List : TStrings; Const AFileName : Strin'+ 'g); virtua','l;'#010+ ' procedure LogIndent;'#010+ ' procedure LogUnIndent;'#010+ ' Procedure Log(Level : TVerboseLevel; Const Msg : String);'#010+ ' Procedure Log(Level : TVerboseLevel; Const Fmt : String; const Arg'+ 's : Array Of Const);'#010+ ' Procedure EnterDir(ADir : St','ring);'#010+ ' Function GetCompiler : String;'#010+ ' Function InstallPackageFiles(APAckage : TPackage; tt : TTargetType'+ '; Const Dest : String):Boolean;'#010+ ' Function FileNewer(const Src,Dest : String) : Boolean;'#010+ ' Procedure LogSearchPath(const ASe','archPathName:string;Path:TCondi'+ 'tionalStrings; ACPU:TCPU;AOS:TOS);'#010+ ' Function FindFileInPath(Path:TConditionalStrings; AFileName:String'+ '; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;'#010+ #010+ ' //package commands'#010+ ' Procedure ResolveFileName','s(APackage : TPackage; ACPU:TCPU;AOS:TO'+ 'S;DoChangeDir:boolean=true);'#010+ ' function GetUnitDir(APackage:TPackage):String;'#010+ ' procedure AddDependencyIncludePaths(L:TStrings;ATarget: TTarget);'#010+ ' procedure AddDependencyUnitPaths(L:TStrings;AP','ackage: TPackage);'+ #010+ ' Public'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' destructor Destroy;override;'#010+ ' // Public Copy/delete/Move/Archive/Mkdir Commands.'#010+ ' Procedure ExecuteCommand(const Cmd,Args : String; IgnoreError : B', 'oolean = False); virtual;'#010+ ' Procedure CmdCopyFiles(List : TStrings; Const DestDir : String);'#010+ ' Procedure CmdCreateDir(const DestDir : String);'#010+ ' Procedure CmdMoveFiles(List : TStrings; Const DestDir : String);'#010+ ' Procedure CmdDeleteF','iles(List : TStrings);'#010+ ' Procedure CmdArchiveFiles(List : TStrings; Const ArchiveFile : Str'+ 'ing);'#010+ ' Procedure ExecuteCommands(Commands : TCommands; At : TCommandAt);'#010+ ' // Dependency commands'#010+ ' Function DependencyOK(ADependency : TDe','pendency) : Boolean;'#010+ ' // Target commands'#010+ ' Function GetCompilerCommand(APackage : TPackage; ATarget : TTarge'+ 't) : String;'#010+ ' Function TargetOK(ATarget : TTarget) : Boolean;'#010+ ' Function NeedsCompile(APackage:TPackage; ATarget : TTar','get) : B'+ 'oolean;'#010+ ' Procedure Compile(APackage:TPackage; ATarget : TTarget); virtual;'+ #010+ ' Procedure MaybeCompile(APackage:TPackage; ATarget: TTarget);'#010+ ' Procedure CompileDependencies(APackage:TPackage; ATarget: TTarget)'+ ';'#010+ ' // Package c','ommands'#010+ '{ Function GetPackageDir(APackage : TPackage; AbsolutePath : Boole'+ 'an = False) : String;'#010+ ' Function GetUnitsOutputDir(APackage : TPackage; AbsolutePath : Bo'+ 'olean = False) : String;'#010+ ' Function GetBinOutputDir(APackage : TPac','kage; AbsolutePath : Bo'+ 'olean = False) : String; }'#010+ ' Function PackageOK(APackage : TPackage) : Boolean; virtual;'#010+ ' Procedure DoBeforeCompile(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterCompile(APackage : TPackage);virtual;'#010+ ' P','rocedure DoBeforeInstall(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterInstall(APackage : TPackage);virtual;'#010+ ' Procedure DoBeforeArchive(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterArchive(APackage : TPackage);virtual;'#010+ ' Pro','cedure DoBeforeClean(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterClean(APackage : TPackage);virtual;'#010+ ' Function NeedsCompile(APackage : TPackage) : Boolean; virtual;'#010+ ' Procedure Compile(APackage : TPackage);'#010+ ' Procedure MaybeC','ompile(APackage:TPackage);'#010+ ' Procedure Install(APackage : TPackage);'#010+ ' Procedure Archive(APackage : TPackage);'#010+ ' Procedure Manifest(APackage : TPackage);'#010+ ' Procedure Clean(APackage : TPackage);'#010+ ' Procedure CompileDependencies(APac','kage : TPackage);'#010+ ' Function CheckExternalPackage(Const APackageName : String):TPacka'+ 'ge;'#010+ ' procedure CreateOutputDir(APackage: TPackage);'#010+ ' // Packages commands'#010+ ' Procedure Compile(Packages : TPackages);'#010+ ' Procedure Install(Packa','ges : TPackages);'#010+ ' Procedure Archive(Packages : TPackages);'#010+ ' procedure Manifest(Packages: TPackages);'#010+ ' Procedure Clean(Packages : TPackages);'#010+ ' Property ListMode : Boolean Read FListMode Write FListMode;'#010+ ' Property ForceCompile',' : Boolean Read FForceCompile Write FForceC'+ 'ompile;'#010+ ' Property ExternalPackages: TPackages Read FExternalPackages;'#010+ ' // Events'#010+ ' Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FB'+ 'eforeCompile;'#010+ ' Property AfterCompile ',': TNotifyEvent Read FAfterCompile Write FA'+ 'fterCompile;'#010+ ' Property BeforeInstall : TNotifyEvent Read FBeforeInstall Write FB'+ 'eforeInstall;'#010+ ' Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAft'+ 'erInstall;'#010+ ' Property BeforeC','lean : TNotifyEvent Read FBeforeClean Write FBef'+ 'oreClean;'#010+ ' Property AfterClean : TNotifyEvent Read FAfterClean Write FAfterCl'+ 'ean;'#010+ ' Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FB'+ 'eforeArchive;'#010+ ' Property AfterArchi','ve : TNotifyEvent Read FAfterArchive Write FA'+ 'fterArchive;'#010+ ' Property BeforeManifest : TNotifyEvent Read FBeforeManifest Write '+ 'FBeforeManifest;'#010+ ' Property AfterManifest : TNotifyEvent Read FAfterManifest Write FA'+ 'fterManifest;'#010+ ' Propert','y OnLog : TLogEvent Read FOnLog Write FOnlog;'#010+ ' end;'#010+ #010+ ' { TCustomInstaller }'#010+ #010+ ' TCustomInstaller = Class(TComponent)'#010+ ' private'#010+ ' FBuildEngine: TBuildEngine;'#010+ ' FPackages: TPackages;'#010+ ' FRunMode: TRunMode;'#010+ ' FListMode : Boolean;'#010+ ' FL','ogLevels : TVerboseLevels;'#010+ ' Protected'#010+ ' Procedure Log(Level : TVerboseLevel; Const Msg : String);'#010+ ' Procedure CreatePackages; virtual;'#010+ ' Procedure CheckPackages; virtual;'#010+ ' Procedure CreateBuildEngine; virtual;'#010+ ' Procedure Error(','const Msg : String);'#010+ ' Procedure Error(const Fmt : String; Args : Array of const);'#010+ ' Procedure AnalyzeOptions;'#010+ ' Procedure Usage(const FMT : String; Args : Array of const);'#010+ ' Procedure Compile(Force : Boolean); virtual;'#010+ ' Procedur','e Clean; virtual;'#010+ ' Procedure Install; virtual;'#010+ ' Procedure Archive; virtual;'#010+ ' Procedure Manifest; virtual;'#010+ ' Property BuildEngine : TBuildEngine Read FBuildEngine;'#010+ ' Public'#010+ ' Constructor Create(AOwner : TComponent); virtual;'#010+ ' ',' Destructor destroy; override;'#010+ ' Function AddPackage(Const AName : String) : TPackage;'#010+ ' Function Run : Boolean;'#010+ ' //files in package'#010+ ' Property Packages : TPackages Read FPackages;'#010+ ' Property RunMode : TRunMode Read FRunMode;'#010+ ' ',' Property ListMode : Boolean Read FListMode;'#010+ ' end;'#010+ #010+ ' { TFPCInstaller }'#010+ ' TFPCInstaller = class(TCustomInstaller)'#010+ ' public'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' end;'#010+ #010+ ' { TBasicInstaller }'#010+ ' TBasicInstaller = class(TCust','omInstaller)'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' end;'#010+ #010+ ' TReplaceFunction = Function (Const AName,Args : String) : String of '+ 'Object;'#010+ #010+ ' { TValueItem }'#010+ #010+ ' TValueItem = Class(TObject)'#010+ ' FValue : String;'#010+ ' Constructor ','Create(AValue : String);'#010+ ' end;'#010+ #010+ ' { TFunctionItem }'#010+ #010+ ' TFunctionItem = Class(TObject)'#010+ ' FFunc : TReplaceFunction;'#010+ ' Constructor Create(AFunc : TReplaceFunction);'#010+ ' end;'#010+ #010+ ' { TDictionary }'#010+ #010+ ' TDictionary = Class(TComponent)'#010+ ' FList : ','TStringList;'#010+ ' Public'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' Destructor Destroy;override;'#010+ ' Procedure AddVariable(Const AName,Value : String);'#010+ ' Procedure AddFunction(Const AName : String; FReplacement : TReplac'+ 'eFunc','tion);'#010+ ' Procedure RemoveItem(Const AName : String);'#010+ ' Function GetValue(Const AName : String) : String;'#010+ ' Function GetValue(Const AName,Args : String) : String; virtual;'#010+ ' Function ReplaceStrings(Const ASource : String) : String; v','irtua'+ 'l;'#010+ ' end;'#010+ #010+ ' ECollectionError = Class(Exception);'#010+ ' EDictionaryError = Class(Exception);'#010+ ' EInstallerError = Class(Exception);'#010+ #010+ ' TInstallerClass = Class of TCustomInstaller;'#010+ ' TDictionaryClass = Class of TDictionary;'#010+ #010+ 'Type'#010+ ' TArchiveE','vent = Procedure (Const AFileName : String; List : TStrin'+ 'gs) of Object;'#010+ ' TArchiveProc = Procedure (Const AFileName : String; List : TStrings)'+ ';'#010+ #010+ 'Var'#010+ ' DictionaryClass : TDictionaryClass = TDictionary;'#010+ ' OnArchiveFiles : TArchiveEvent = Nil;',#010+ ' ArchiveFilesProc : TArchiveProc = Nil;'#010+ #010+ ' Defaults : TCustomDefaults; // Set by installer.'#010+ ' Dictionary : TDictionary;'#010+ #010+ #010+ 'Function CurrentOS : String;'#010+ 'Function CurrentCPU : String;'#010+ #010+ 'Function Installer(InstallerClass: TInstallerClass) : TC','ustomInstall'+ 'er; overload;'#010+ 'Function Installer : TCustomInstaller; overload;'#010+ #010+ 'Function OSToString(OS: TOS) : String;'#010+ 'Function OSesToString(OSes: TOSes) : String;'#010+ 'Function CPUToString(CPU: TCPU) : String;'#010+ 'Function CPUSToString(CPUS: TCPUS) : S','tring;'#010+ 'Function StringToOS(const S : String) : TOS;'#010+ 'Function OSesToString(const S : String) : TOSes;'#010+ 'Function StringToCPU(const S : String) : TCPU;'#010+ 'Function StringToCPUS(const S : String) : TCPUS;'#010+ 'Function ModeToString(Mode: TCompilerMode) ',': String;'#010+ 'Function StringToMode(const S : String) : TCompilerMode;'#010+ 'Function MakeTargetString(CPU : TCPU;OS: TOS) : String;'#010+ 'Procedure StringToCPUOS(const S : String; Var CPU : TCPU; Var OS: TOS)'+ ';'#010+ 'Function FixPath (const APath : String) : Str','ing;'#010+ 'Procedure ChangeDir(const APath : String);'#010+ 'Function Substitute(Const Source : String; Macros : Array of string) :'+ ' String;'#010+ 'Procedure SplitCommand(Const Cmd : String; Var Exe,Options : String);'#010+ #010+ 'Implementation'#010+ #010+ 'uses typinfo;'#010+ #010+ 'ResourceStr','ing'#010+ ' SErrInvalidCPU = '#039'Invalid CPU name "%s"'#039';'#010+ ' SErrInvalidOS = '#039'Invalid OS name "%s"'#039';'#010+ ' SErrInvalidMode = '#039'Invalid compiler mode "%s"'#039';'#010+ ' SErrInvalidTarget = '#039'Invalid compiler target "%s"'#039';'#010+ ' SErrNameExists ',' = '#039'Name "%s" already exists in the colle'+ 'ction.'#039';'#010+ ' SErrNoSuchName = '#039'Could not find item with name "%s" in t'+ 'he collection.'#039';'#010+ ' SErrInValidArgument = '#039'Invalid command-line argument at positi'+ 'on %d: %s'#039';'#010+ ' SErrNeedArgument = '#039,'Option at position %d (%s) needs an ar'+ 'gument'#039';'#010+ ' SErrNoPackagesDefined = '#039'No action possible: No packages were de'+ 'fined.'#039';'#010+ ' SErrInstaller = '#039'The installer encountered the following'+ ' error:'#039';'#010+ ' SErrDepUnknownTarget = '#039'Unknown target ','in dependencies for %s'+ ': %s'#039';'#010+ ' SErrExternalCommandFailed = '#039'External command "%s" failed with e'+ 'xit code %d'#039';'#010+ ' SErrCreatingDirectory = '#039'Failed to create directory "%s"'#039';'#010+ ' SErrDeletingFile = '#039'Failed to delete file "%s"'#039';'#010+ ' SErrMovingFi','le = '#039'Failed to move file "%s" to "%s"'#039';'+ #010+ ' SErrCopyingFile = '#039'Failed to copy file "%s" to "%s"'#039';'#010+ ' SErrChangeDirFailed = '#039'Failed to enter directory "%s"'#039';'#010+ ' SErrInvalidArgumentToSubstitute = '#039'Invalid number of arguments t'+ 'o Su','bstitute'#039';'#010+ ' SErrNoArchiveSupport = '#039'This binary contains no archive support'+ '. Please recompile with archive support'#039';'#010+ ' SErrNoDictionaryItem = '#039'No item called "%s" in the dictionary'#039+ ';'#010+ ' SErrNoDictionaryValue = '#039'The item "%s" in the dictio','nary is no'+ 't a value'#039';'#010+ ' SErrNoDictionaryFunc = '#039'The item "%s" in the dictionary is not '+ 'a function'#039';'#010+ ' SErrInvalidFPCInfo = '#039'Compiler returns invalid information, c'+ 'heck if fpc -iV works'#039';'#010+ ' SErrDependencyNotFound = '#039'Could not find unit d','irectory for de'+ 'pendency package "%s"'#039';'#010+ ' SErrAlreadyInitialized = '#039'Installer can only be initialized once'+ #039';'#010+ ' SErrInvalidState = '#039'Invalid state for target %s'#039';'#010+ #010+ ' SWarnCircularTargetDependency = '#039'Warning: Circular dependency de'+ 'tected w','hen compiling target %s with target %s'#039';'#010+ ' SWarnCircularPackageDependency = '#039'Warning: Circular dependency d'+ 'etected when compiling package %s with package %s'#039';'#010+ ' SWarnFailedToSetTime = '#039'Warning: Failed to set timestamp on f'+ 'ile "%s"'#039';'#010+ ' SW','arnFailedToGetTime = '#039'Warning: Failed to get timestamp fr'+ 'om file "%s"'#039';'#010+ ' SWarnFileDoesNotExist = '#039'Warning: File "%s" does not exist'#039+ ';'#010+ ' SWarnAttemptingToCompileNonNeutralTarget = '#039'Warning: Attempting '+ 'to compile non-neutral target %s'#039';',#010+ ' SWarnSourceFileNotFound = '#039'Warning: Source file "%s" not found '+ 'for %s'#039';'#010+ ' SWarnIncludeFileNotFound = '#039'Warning: Include file "%s" not found'+ ' for %s'#039';'#010+ ' SWarnDepUnitNotFound = '#039'Warning: Dependency on unit %s is no'+ 't supported for %s'#039';'#010+ #010, ' SInfoCompilingPackage = '#039'Compiling package %s'#039';'#010+ ' SInfoCompilingTarget = '#039'Compiling target %s'#039';'#010+ ' SInfoExecutingCommand = '#039'Executing command "%s %s"'#039';'#010+ ' SInfoCreatingOutputDir = '#039'Creating output dir "%s"'#039';'#010+ ' SInfoInstallingPackage',' = '#039'Installing package %s'#039';'#010+ ' SInfoArchivingPackage = '#039'Archiving package %s in "%s"'#039';'#010+ ' SInfoCleaningPackage = '#039'Cleaning package %s'#039';'#010+ ' SInfoManifestPackage = '#039'Creating manifest for package %s'#039';'+ #010+ ' SInfoCopyingFile = '#039'Copying',' file "%s" to "%s"'#039';'#010+ ' SInfoSourceNewerDest = '#039'Source file "%s" (%s) is newer than d'+ 'estination "%s" (%s).'#039';'#010+ #010+ ' SDbgComparingFileTimes = '#039'Comparing file "%s" time "%s" to "%'+ 's" time "%s".'#039';'#010+ ' SDbgCompilingDependenciesOfTarget = '#039'Compili','ng dependencies of'+ ' target %s'#039';'#010+ ' SDbgResolvingSourcesOfTarget = '#039'Resolving filenames of target %s'+ ' for %s'#039';'#010+ ' SDbgResolvedSourceFile = '#039'Resolved source file %s to "%s"'#039+ ';'#010+ ' SDbgResolvedIncludeFile = '#039'Resolved include file %s to "%s"'#039+ ';'#010+ ' ','SDbgOutputNotYetAvailable = '#039'Output file %s not available'#039';'+ #010+ ' SDbgDependencyOnUnit = '#039'Dependency of %s on unit %s'#039';'#010+ ' SDbgDependencyUnitRecompiled = '#039'Dependent unit %s is being recom'+ 'piled'#039';'#010+ ' SDbgMustCompile = '#039'Must compile %','s'#039';'#010+ ' SDbgSkippingTargetWrongCPU = '#039'Skipping target %s, different CPU '+ '(%s)'#039';'#010+ ' SDbgSkippingTargetWrongOS = '#039'Skipping target %s, different OS ('+ '%s)'#039';'#010+ ' SDbgTargetIsNotAUnitOrProgram = '#039'Skipping Target %s, not an unit'+ ' or program'#039';'#010+ ' SDbgConsi','deringTarget = '#039'Considering target %s'#039';'#010+ ' SDbgConsideringPackage = '#039'Considering package %s'#039';'#010+ ' SDbgExternalDependency = '#039'External dependency %s found in "%s'+ '"'#039';'#010+ ' SDbgBuildEngineArchiving = '#039'Build engine archiving'#039';'#010+ ' SDbgBuildEng','ineGenerateManifests = '#039'Build engine generating ma'+ 'nifests'#039';'#010+ ' SDbgBuildEngineCleaning = '#039'Build engine cleaning'#039';'#010+ ' SDbgGenerating = '#039'Generating "%s"'#039';'#010+ ' SDbgLoading = '#039'Loading "%s"'#039';'#010+ ' SDbgFound = ',#039'Found'#039';'#010+ ' SDbgNotFound = '#039'Not Found'#039';'#010+ ' SDbgDirectoryExists = '#039'Directory "%s" %s'#039';'#010+ ' SDbgFileExists = '#039'File "%s" %s'#039';'#010+ ' SDbgArchivingFile = '#039'Archiving "%s"'#039';'#010+ ' SDbgSearchPath = '#039'Using %s pat','h "%s"'#039';'#010+ ' SDbgEnterDir = '#039'Entering directory "%s"'#039';'#010+ ' SDbgPackageChecksumChanged = '#039'Dependent package %s is modified'#039+ ';'#010+ #010+ ' // Help messages for usage'#010+ ' SValue = '#039'Value'#039';'#010+ ' SHelpUsage = '#039'Usage: %s command [','options]'#039';'#010+ ' SHelpCommand = '#039'Where command is one of the following:'#039+ ';'#010+ ' SHelpCompile = '#039'Compile all units in the package(s).'#039';'+ #010+ ' SHelpBuild = '#039'Build all units in the package(s).'#039';'#010+ ' SHelpInstall = '#039'Install all ','units in the package(s).'#039+ ';'#010+ ' SHelpClean = '#039'Clean (remove) all units in the package(s'+ ').'#039';'#010+ ' SHelpArchive = '#039'Create archive (zip) with all units in th'+ 'e package(s).'#039';'#010+ ' SHelpHelp = '#039'This message.'#039';'#010+ ' SHelpManifest ',' = '#039'Create a manifest suitable for import i'+ 'n repository.'#039';'#010+ ' SHelpCmdOptions = '#039'Where options is one or more of the follo'+ 'wing:'#039';'#010+ ' SHelpCPU = '#039'Compile for indicated CPU.'#039';'#010+ ' SHelpOS = '#039'Compile for indicated OS'#039';',#010+ ' SHelpTarget = '#039'Compile for indicated target'#039';'#010+ ' SHelpList = '#039'list commands instead of actually executi'+ 'ng them.'#039';'#010+ ' SHelpPrefix = '#039'Use indicated prefix directory for all co'+ 'mmands.'#039';'#010+ ' SHelpNoFPCCfg = '#039'Compi','ler will not use fpc.cfg'#039';'#010+ ' SHelpBaseInstallDir = '#039'Use indicated directory as base install d'+ 'ir.'#039';'#010+ ' SHelpLocalUnitDir = '#039'Use indicated directory as local (user) u'+ 'nit dir.'#039';'#010+ ' SHelpGlobalUnitDir = '#039'Use indicated directory as global unit ','d'+ 'ir.'#039';'#010+ ' SHelpCompiler = '#039'Use indicated binary as compiler'#039';'#010+ ' SHelpConfig = '#039'Use indicated config file when compiling.'+ #039';'#010+ ' SHelpVerbose = '#039'Be verbose when working.'#039';'#010+ #010+ #010+ 'Const'#010+ ' // Keys for Defaults file. Do not localize','.'#010+ ' KeyCompiler = '#039'Compiler'#039';'#010+ ' KeyArchive = '#039'Archive'#039';'#010+ ' KeyCopy = '#039'Copy'#039';'#010+ ' KeyMkDir = '#039'MkDir'#039';'#010+ ' KeyMove = '#039'Move'#039';'#010+ ' KeyRemove = '#039'Remove'#039';'#010+ ' KeyOptions = '#039'Options'#039';'#010+ ' KeyCPU = '#039'CPU'#039';'#010+ ' KeyOS = '#039'OS'#039';'#010+ ' KeyMode ',' = '#039'Mode'#039';'#010+ ' KeyPrefix = '#039'Prefix'#039';'#010+ ' KeyTarget = '#039'Target'#039';'#010+ ' KeyNoFPCCfg = '#039'NoFPCCfg'#039';'#010+ ' KeyLocalUnitDir = '#039'LocalUnitDir'#039';'#010+ ' KeyGlobalUnitDir = '#039'GlobalUnitDir'#039';'#010+ ' KeyBaseInstallDir = '#039'BaseInstallDir'#039';'#010+ ' KeyUnitInstallDir',' = '#039'UnitInstallDir'#039';'#010+ ' KeyBinInstallDir = '#039'BinInstallDir'#039';'#010+ ' KeyDocInstallDir = '#039'DocInstallDir'#039';'#010+ ' KeyExamplesInstallDir = '#039'ExamplesInstallDir'#039';'#010+ ' // Keys for unit config'#010+ ' KeyName = '#039'Name'#039';'#010+ ' KeyVersion = '#039'Version'#039';'#010+ ' Ke','yChecksum = '#039'Checksum'#039';'#010+ ' KeyNeedLibC = '#039'NeedLibC'#039';'#010+ ' KeyDepends = '#039'Depends'#039';'#010+ #010+ '{*********************************************************************'+ '*******'#010+ ' Helpers'#010+ '******************************************','**************************'+ '********}'#010+ #010+ #010+ 'Function QuoteXML(S : String) : string;'#010+ #010+ ' Procedure W(Var J : Integer; Var R : String; T : String);'#010+ ' Var'#010+ ' I: integer;'#010+ ' begin'#010+ ' If J+Length(T)>Length(R) then'#010+ ' SetLength(R,J+Length(T));'#010+ ' F','or I:=1 to Length(t) do'#010+ ' begin'#010+ ' R[J]:=T[i];'#010+ ' If I'#039': W(J,Result,gtStr);'#010+ ' // Escape whitespace',' using CharRefs to be consistent with W3 s'+ 'pec X 3.3.3'#010+ ' #9: w(J,Result,'#039' '#039');'#010+ '{ #10: wrtStr('#039' '#039');'#010+ ' #13: wrtStr('#039' '#039');}'#010+ ' else'#010+ ' Result[J]:=S[i];'#010+ ' end;'#010+ ' If (J=Length(Result)) and (ILength(Result) then'#010+ ' SetLength(Result,J);'#010+ 'end;'#010+ #010+ #010+ 'function maybequoted(const s:string):string;'#010+ 'const'#010+ ' {$IFDEF MSWINDOWS}'#010+ ' FORBIDDEN_CHARS = ['#039'!'#039', '#039'@'#039', '#039'#'#039', '#039'$'#039+ ', '#039'%'#039', '#039'^'#039', '#039'&'#039', '#039'*'#039', '#039'(',#039', '#039+ ')'#039','#010+ ' '#039'{'#039', '#039'}'#039', '#039#039#039#039', '#039'`'+ #039', '#039'~'#039'];'#010+ ' {$ELSE}'#010+ ' FORBIDDEN_CHARS = ['#039'!'#039', '#039'@'#039', '#039'#'#039', '#039'$'#039+ ', '#039'%'#039', '#039'^'#039', '#039'&'#039', '#039'*'#039', '#039'('#039', '#039+ ')'#039','#010+ ' '#039'{'#039', '#039'}'#039', '#039#039#039#039', '#039':'+ #039', '#039'\'#039', '#039'`'#039', '#039'~'#039'];'#010+ ' {$ENDIF}'#010+ 'var'#010+ ' s1 : string;'#010+ ' i : in','teger;'#010+ ' quoted : boolean;'#010+ 'begin'#010+ ' quoted:=false;'#010+ ' s1:='#039'"'#039';'#010+ ' for i:=1 to length(s) do'#010+ ' begin'#010+ ' case s[i] of'#010+ ' '#039'"'#039' :'#010+ ' begin'#010+ ' quoted:=true;'#010+ ' s1:=s1+'#039'\"'#039';'#010+ ' end;'#010+ ' '#039' '#039','#010+ ' #128..#255 :'#010+ ' ',' begin'#010+ ' quoted:=true;'#010+ ' s1:=s1+s[i];'#010+ ' end;'#010+ ' else begin'#010+ ' if s[i] in FORBIDDEN_CHARS then'#010+ ' quoted:=True;'#010+ ' s1:=s1+s[i];'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' if quoted then'#010+ ' maybequ','oted:=s1+'#039'"'#039#010+ ' else'#010+ ' maybequoted:=s;'#010+ 'end;'#010+ #010+ #010+ 'procedure ReadIniFile(Const AFileName: String;L:TStrings);'#010+ 'Var'#010+ ' F : TFileStream;'#010+ ' Line : String;'#010+ ' I,P,PC : Integer;'#010+ 'begin'#010+ ' F:=TFileStream.Create(AFileName,fmOpenRead);'#010+ ' Try'#010+ ' L.LoadFromS','tream(F);'#010+ ' // Fix lines.'#010+ ' For I:=L.Count-1 downto 0 do'#010+ ' begin'#010+ ' Line:=L[I];'#010+ ' P:=Pos('#039'='#039',Line);'#010+ ' PC:=Pos('#039';'#039',Line); // Comment line.'#010+ ' If (P=0) or ((PC<>0) and (PC-1 then'#010+ ' C.Target:=P.Items[J];'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'function AddConditionalStrings(Dest : TStrings; Src : TConditionalStri'+ 'ngs;ACPU:TCPU;AOS:TOS; Const APrefix ',': String='#039#039') : Integer ;'#010+ 'Var'#010+ ' I : Integer;'#010+ ' C : TConditionalString;'#010+ ' S : String;'#010+ 'begin'#010+ ' Result:=0;'#010+ ' Dictionary.AddVariable('#039'CPU'#039',CPUToString(ACPU));'#010+ ' Dictionary.AddVariable('#039'OS'#039',OSToString(AOS));'#010+ ' For I:=0 to Src.Count-1 do'#010+ ' begin',#010+ ' C:=Src[I];'#010+ ' if (ACPU in C.CPUs) and (AOS in C.OSes) then'#010+ ' begin'#010+ ' If (APrefix<>'#039#039') then'#010+ ' S:=APrefix+C.Value'#010+ ' else'#010+ ' S:=C.Value;'#010+ ' Dest.Add(Dictionary.ReplaceStrings(S));'#010+ ' ',' Inc(Result);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'function FileListToString(List : TStrings; const APrefix : String) : S'+ 'tring;'#010+ 'Var'#010+ ' I : integer;'#010+ ' S : String;'#010+ 'begin'#010+ ' Result:='#039#039';'#010+ ' For I:=0 to List.Count-1 do'#010+ ' begin'#010+ ' If (I>0) then'#010+ ' ',' Result:=Result+'#039' '#039';'#010+ ' S:=APrefix+List[i];'#010+ ' If (Pos('#039' '#039',S)<>0) then'#010+ ' S:='#039'"'#039'+S+'#039'"'#039';'#010+ ' Result:=Result+S;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'function FixPath (const APath : String) : String;'#010+ 'Var'#010+ ' P : PChar;'#010+ 'begin'#010+ ' Result:=APath;'#010+ ' If (r','esult<>'#039#039') then'#010+ ' begin'#010+ ' P:=PChar(Result);'#010+ ' While (P^<>#0) do'#010+ ' begin'#010+ ' If P^ in ['#039'/'#039','#039'\'#039'] then'#010+ ' P^:=PathDelim;'#010+ ' Inc(P);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure ChangeDir(const APath : String);'#010+ 'b','egin'#010+ ' if Not SetCurrentDir(APath) then'#010+ ' Raise EInstallerError.CreateFmt(SErrChangeDirFailed,[APath]);'#010+ 'end;'#010+ #010+ #010+ 'procedure SearchFiles(const AFileName: string; Recursive: boolean; var'+ ' List: TStrings);'#010+ #010+ ' procedure AddRecursiveFiles(const Se','archDir, FileMask: string; Rec'+ 'ursive: boolean);'#010+ ' const'#010+ ' IgnoreCase = {$ifdef UNIX}False{$else}True{$endif};'#010+ ' var'#010+ ' Info : TSearchRec;'#010+ ' begin'#010+ ' if FindFirst(SearchDir+'#039'*'#039',faAnyFile and faDirectory,Info)'+ '=0 then'#010+ ' begin'#010+ ' repea','t'#010+ ' if ((Info.Attr and faDirectory) = faDirectory) and (Info.Nam'+ 'e <> '#039'.'#039') and (Info.Name <> '#039'..'#039') and (Recursive) then'+ #010+ ' AddRecursiveFiles(SearchDir + Info.Name + PathDelim, FileM'+ 'ask, Recursive);'#010+ ' if ((Info.Attr a','nd faDirectory) <> faDirectory) and IsWild'+ '(Info.Name, FileMask, IgnoreCase) then'#010+ ' List.Add(SearchDir + Info.Name);'#010+ ' until FindNext(Info)<>0;'#010+ ' end;'#010+ ' FindClose(Info);'#010+ ' end;'#010+ #010+ 'var'#010+ ' CurrDir,'#010+ ' BasePath: string;'#010+ ' i: integ','er;'#010+ 'begin'#010+ ' BasePath := ExtractFilePath(ExpandFileName(AFileName));'#010+ ' AddRecursiveFiles(BasePath, ExtractFileName(AFileName), Recursive);'#010+ #010+ ' CurrDir:=GetCurrentDir;'#010+ ' for i := 0 to Pred(List.Count) do'#010+ ' List[i] := ExtractRelativepath(Incl','udeTrailingPathDelimiter(Curr'+ 'Dir), List[i]);'#010+ 'end;'#010+ #010+ #010+ 'procedure SplitCommand(const Cmd : String; var Exe, Options : String);'+ #010+ #010+ 'Const'#010+ ' WhiteSpace = [#9,#10,#13,'#039' '#039'];'#010+ ' QuoteChars = ['#039#039#039#039','#039'"'#039'];'#010+ #010+ 'Var'#010+ ' I : Integer;'#010+ ' InQuote : Boolean;'#010+ ' LastQuo','te : Char;'#010+ ' S : String;'#010+ #010+ 'begin'#010+ ' S:=Trim(Cmd);'#010+ ' InQuote:=False;'#010+ ' LastQuote:=#0;'#010+ ' I:=1;'#010+ ' While (I<=Length(S)) and (Inquote or not (S[I] in whiteSpace)) do'#010+ ' begin'#010+ ' If S[i] in QuoteChars then'#010+ ' begin'#010+ ' InQuote:=Not (S[i]=Las','tQuote);'#010+ ' If InQuote then'#010+ ' LastQuote:=S[i]'#010+ ' else'#010+ ' LastQuote:=#0;'#010+ ' end;'#010+ ' Inc(I);'#010+ ' end;'#010+ ' Exe:=Copy(S,1,I-1);'#010+ ' Delete(S,1,I);'#010+ ' Options:=Trim(S);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef HAS_UNIT_PROCESS}'#010+ 'function GetCompilerInfo','(const ACompiler,AOptions:string):string;'#010+ 'const'#010+ ' BufSize = 1024;'#010+ 'var'#010+ ' S: TProcess;'#010+ ' Buf: array [0..BufSize - 1] of char;'#010+ ' Count: longint;'#010+ 'begin'#010+ ' S:=TProcess.Create(Nil);'#010+ ' S.Commandline:=ACompiler+'#039' '#039'+AOptions;'#010+ ' S.Options:=[poUsePipes','];'#010+ ' S.execute;'#010+ ' Count:=s.output.read(buf,BufSize);'#010+ ' S.Free;'#010+ ' SetLength(Result,Count);'#010+ ' Move(Buf,Result[1],Count);'#010+ 'end;'#010+ '{$endif HAS_UNIT_PROCESS}'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' ',' TNamedItem'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'procedure TNamedItem.SetName(const AValue: String);'#010+ #010+ 'begin'#010+ ' if FName=AValue then exit;'#010+ ' With TNamedCollection(Collection) do'#010+ ' ',' If UniqueNames then'#010+ ' If (IndexOfName(AVAlue)<>-1) then'#010+ ' Raise ECollectionError.CreateFmt(SErrNameExists,[AValue]);'#010+ ' FName:=AValue;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' ',' TNamedCollection'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TNamedCollection.IndexOfName(const AName: String): Integer;'#010+ #010+ 'begin'#010+ ' Result:=Count-1;'#010+ ' While (Result>=0) and (','CompareText(TNamedItem(Items[Result]).FName'+ ',AName)<>0) do'#010+ ' Dec(Result);'#010+ 'end;'#010+ #010+ 'function TNamedCollection.ItemByName(const AName: String): TNamedItem;'+ #010+ #010+ 'Var'#010+ ' I : Integer;'#010+ #010+ 'begin'#010+ ' I:=IndexOfName(AName);'#010+ ' If (I=-1) Then'#010+ ' Raise ECollecti','onError.CreateFmt(SErrNoSuchName,[AName]);'#010+ ' Result:=TNamedItem(Items[i]);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TNamedItemList'#010+ '************************************','********************************'+ '********}'#010+ #010+ 'function TNamedItemList.GetNamedItem(Index : Integer): TNamedItem;'#010+ 'begin'#010+ ' Result:=TNamedItem(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TNamedItemList.SetNamedItem(Index : Integer; const AValue: T'+ 'NamedItem);',#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'function TNamedItemList.IndexOfName(const AName: String): Integer;'#010+ 'begin'#010+ ' Result:=Count-1;'#010+ ' While (Result>=0) and (CompareText(GetNamedItem(Result).Name,AName)<'+ '>0) do'#010+ ' Dec(Result);'#010+ 'end;'#010+ #010+ #010+ 'function ','TNamedItemList.ItemByName(const ANAme: String): TNamedItem;'+ #010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=IndexOfName(AName);'#010+ ' If (I=-1) Then'#010+ ' Raise ECollectionError.CreateFmt(SErrNoSuchName,[AName]);'#010+ ' Result:=TNamedItem(Items[i]);'#010+ 'end;'#010+ #010+ #010+ '{***********','********************************************************'+ '*********'#010+ ' TTargets'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TTargets.GetTargetItem(Index : Integer): TTar','get;'#010+ 'begin'#010+ ' Result:=TTarget(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'function TTargets.GetTarget(const AName : String): TTarget;'#010+ 'begin'#010+ ' Result:=TTarget(ItemByName(AName));'#010+ 'end;'#010+ #010+ #010+ 'procedure TTargets.SetTargetItem(Index : Integer; const AValue: TTarge'+ 't);'#010+ 'begi','n'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddUnit(Const AUnitName : String) : TTarget;'#010+ 'begin'#010+ ' Result:=AddUnit(AUnitName,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddUnit(Const AUnitName : String;const OSes:TOSes) :'+ ' TTarget;'#010+ 'begin',#010+ ' Result:=AddUnit(AUnitName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TTargets.AddUnit(Const AUnitName : String;const CPUs:TCPUs) :'+ ' TTarget;'#010+ 'begin'#010+ ' Result:=AddUnit(AUnitName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}',#010+ #010+ #010+ 'Function TTargets.AddUnit(Const AUnitName : String;const CPUs:TCPUs;co'+ 'nst OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.Name:=AUnitName;'#010+ ' Result.TargetType:=TTUnit;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ 'end;'#010+ #010+ #010+ 'Func','tion TTargets.AddImplicitUnit(Const AUnitName : String;InstallUn'+ 'it:boolean=true) : TTarget;'#010+ 'begin'#010+ ' Result:=AddImplicitUnit(AUnitName,AllCPUs,AllOSes,InstallUnit);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddImplicitUnit(Const AUnitName : String;const OSes', ':TOSes;InstallUnit:boolean=true) : TTarget;'#010+ 'begin'#010+ ' Result:=AddImplicitUnit(AUnitName,AllCPUs,OSes,InstallUnit);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddImplicitUnit(Const AUnitName : String;const CPUs:'+ 'TCPUs;InstallUnit:boolean=true) : TTarget;'#010+ 'begin'#010+ ' ',' Result:=AddImplicitUnit(AUnitName,CPUs,AllOSes,InstallUnit);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddImplicitUnit(Const AUnitName : String;const CPUs:'+ 'TCPUs;const OSes:TOSes;InstallUnit:boolean=true) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.','Name:=AUnitName;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' if InstallUnit then'#010+ ' Result.TargetType:=TTImplicitUnit'#010+ ' else'#010+ ' Result.TargetType:=TTCleanOnlyUnit;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddProgram(Const AProgramName : String) : TTarget',';'+ #010+ 'begin'#010+ ' Result:=AddProgram(AProgramName,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddProgram(Const AProgramName : String;const OSes:TO'+ 'Ses) : TTarget;'#010+ 'begin'#010+ ' Result:=AddProgram(AProgramName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overload','s}'#010+ 'Function TTargets.AddProgram(Const AProgramName : String;const CPUs:TC'+ 'PUs) : TTarget;'#010+ 'begin'#010+ ' Result:=AddProgram(AProgramName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TTargets.AddProgram(Const AProgramName : String;cons','t CPUs:'+ 'TCPUs;const OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.Name:=AProgramName;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.TargetType:=ttProgram;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleUnit(Const AUnitName : Strin','g) : TTarget'+ ';'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleUnit(Const AUnitName : String;const OSes:T'+ 'OSes) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cp','u_only_overloads}'#010+ 'Function TTargets.AddExampleUnit(Const AUnitName : String;const CPUs:T'+ 'CPUs) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TTargets.AddExampleUnit(Const AUnit','Name : String;const CPUs'+ ':TCPUs;const OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.Name:=AUnitName;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.TargetType:=ttExampleUnit;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleProgram(C','onst AProgramName : String) : T'+ 'Target;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AProgramName,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleProgram(Const AProgramName : String;const '+ 'OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AP','rogramName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TTargets.AddExampleProgram(Const AProgramName : String;const '+ 'CPUs:TCPUs) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AProgramName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_ov','erloads}'#010+ #010+ #010+ 'Function TTargets.AddExampleProgram(Const AProgramName : String;const '+ 'CPUs:TCPUs;const OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.Name:=AProgramName;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.TargetT','ype:=ttExampleProgram;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TSources'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TSo','urces.GetSourceItem(Index : Integer): TSource;'#010+ 'begin'#010+ ' Result:=TSource(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TSources.SetSourceItem(Index : Integer; const AValue: TSourc'+ 'e);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddDoc (const AFil','es : String) : TSource;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceType:=stDoc;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddSrc(const AFiles : String) : TSource;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FS','ourceType:=stSrc;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddExample(const AFiles : String) : TSource;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceType:=stExample;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddTest(const AFiles : String) : TSourc','e;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceType:=stTest;'#010+ 'end;'#010+ #010+ #010+ 'procedure TSources.AddDocFiles(const AFileMask: string; Recursive: boo'+ 'lean);'#010+ 'var'#010+ ' List : TStrings;'#010+ ' i: integer;'#010+ 'begin'#010+ ' List := TStringList.Cre','ate;'#010+ ' SearchFiles(AFileMask, Recursive, List);'#010+ ' for i:= 0 to Pred(List.Count) do'#010+ ' AddDoc(List[i]);'#010+ ' List.Free;'#010+ 'end;'#010+ #010+ #010+ 'procedure TSources.AddSrcFiles(const AFileMask: string; Recursive: boo'+ 'lean);'#010+ 'var'#010+ ' List : TStrings;'#010+ ' i: integer;'#010+ 'be','gin'#010+ ' List := TStringList.Create;'#010+ ' SearchFiles(AFileMask, Recursive, List);'#010+ ' for i:= 0 to Pred(List.Count) do'#010+ ' AddSrc(List[i]);'#010+ ' List.Free;'#010+ 'end;'#010+ #010+ #010+ 'procedure TSources.AddExampleFiles(const AFileMask: string; Recursive:'+ ' boolean);'#010+ 'var'#010+ ' ','List : TStrings;'#010+ ' i: integer;'#010+ 'begin'#010+ ' List := TStringList.Create;'#010+ ' SearchFiles(AFileMask, Recursive, List);'#010+ ' for i:= 0 to Pred(List.Count) do'#010+ ' AddExample(List[i]);'#010+ ' List.Free;'#010+ 'end;'#010+ #010+ #010+ 'procedure TSources.AddTestFiles(const AFileMask: s','tring; Recursive: '+ 'boolean);'#010+ 'var'#010+ ' List : TStrings;'#010+ ' i: integer;'#010+ 'begin'#010+ ' List := TStringList.Create;'#010+ ' SearchFiles(AFileMask, Recursive, List);'#010+ ' for i:= 0 to Pred(List.Count) do'#010+ ' AddTest(List[i]);'#010+ ' List.Free;'#010+ 'end;'#010+ #010+ #010+ '{******************','*************************************************'+ '*********'#010+ ' TPackage'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TPackage.Create(ACollection: TCollection);'#010+ 'begin'#010+ ' i','nherited Create(ACollection);'#010+ ' FVersion:=TFPVersion.Create;'#010+ ' FTargets:=TTargets.Create(TTarget);'#010+ ' FSources:=TSources.Create(TSource);'#010+ ' FDependencies:=TDependencies.Create(TDependency);'#010+ ' FInstallFiles:=TConditionalStrings.Create(TCondit','ionalString);'#010+ ' FCleanFiles:=TConditionalStrings.Create(TConditionalString);'#010+ ' FUnitPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FObjectPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FIncludePath:=TConditionalStrings.Cre','ate(TConditionalString);'#010+ ' FSourcePath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FExamplePath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FTestPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FCommands:=TCommands.Crea','te(TCommand);'#010+ ' FCPUs:=AllCPUs;'#010+ ' FOSes:=AllOSes;'#010+ ' FInstalledChecksum:=$ffffffff;'#010+ ' // Implicit dependency on RTL'#010+ ' FDependencies.Add('#039'rtl'#039');'#010+ 'end;'#010+ #010+ #010+ 'destructor TPackage.destroy;'#010+ 'begin'#010+ ' FreeAndNil(FDependencies);'#010+ ' FreeAndNil(FInstallFiles',');'#010+ ' FreeAndNil(FCleanFiles);'#010+ ' FreeAndNil(FIncludePath);'#010+ ' FreeAndNil(FSourcePath);'#010+ ' FreeAndNil(FExamplePath);'#010+ ' FreeAndNil(FTestPath);'#010+ ' FreeAndNil(FObjectPath);'#010+ ' FreeAndNil(FUnitPath);'#010+ ' FreeAndNil(FSources);'#010+ ' FreeAndNil(FTargets);'#010+ ' ','FreeAndNil(FVersion);'#010+ ' inherited destroy;'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.SetName(const AValue: String);'#010+ 'begin'#010+ ' inherited SetName(AValue);'#010+ ' // RTL should not have any dependencies'#010+ ' if AValue='#039'rtl'#039' then'#010+ ' FDependencies.Clear;'#010+ 'end;'#010+ #010+ #010+ 'Function',' TPackage.GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;'#010+ 'begin'#010+ ' Result:='#039'units'#039'+PathDelim+MakeTargetString(ACPU,AOS);'#010+ 'end;'#010+ #010+ #010+ 'Function TPackage.GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;'#010+ 'begin'#010+ ' Result:='#039'bin'#039'+PathDelim+MakeTargetStrin','g(ACPU,AOS);'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.GetCleanFiles(List: TStrings; ACPU:TCPU; AOS : TOS)'+ ';'#010+ 'Var'#010+ ' OB,OU : String;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(Defaults.CPU,Defaul'+ 'ts.OS));'#010+ ' OU:=IncludeTrailingPathD','elimiter(GetUnitsOutputDir(Defaults.CPU,De'+ 'faults.OS));'#010+ ' AddConditionalStrings(List,CleanFiles,ACPU,AOS);'#010+ ' For I:=0 to FTargets.Count-1 do'#010+ ' FTargets.TargetItems[I].GetCleanFiles(List, OU, OB, ACPU, AOS);'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.GetIns','tallFiles(List: TStrings;Types : TTargetTyp'+ 'es;ACPU:TCPU; AOS : TOS);'#010+ 'Var'#010+ ' OB,OU : String;'#010+ ' I : Integer;'#010+ ' T : TTarget;'#010+ 'begin'#010+ ' OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(Defaults.CPU,Defaul'+ 'ts.OS));'#010+ ' OU:=IncludeTrailingPathDelimiter','(GetUnitsOutputDir(Defaults.CPU,De'+ 'faults.OS));'#010+ ' AddConditionalStrings(List,InstallFiles,ACPU,AOS);'#010+ ' For I:=0 to FTargets.Count-1 do'#010+ ' begin'#010+ ' T:=FTargets.TargetItems[I];'#010+ ' if (T.TargetType in Types) and (T.Install) then'#010+ ' ','T.GetInstallFiles(List, OU, OB, ACPU, AOS);'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.GetArchiveFiles(List: TStrings; ACPU:TCPU; AOS : TO'+ 'S);'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' // Targets only'#010+ ' For I:=0 to FTargets.Count-1 do'#010+ ' FTargets.TargetItems[I].G','etArchiveFiles(List,ACPU,AOS);'#010+ 'end;'#010+ #010+ #010+ 'Function TPackage.GetDescription : string;'#010+ 'Var'#010+ ' FN : String;'#010+ ' L : TStringList;'#010+ 'begin'#010+ ' If (FDescription<>'#039#039') then'#010+ ' Result:=FDescription'#010+ ' else'#010+ ' If (FDescriptionFile<>'#039#039') then'#010+ ' begin'#010+ ' ',' // Always relative to binary name.'#010+ ' FN:=ExtractFilePath(ParamStr(0));'#010+ ' FN:=FN+FDescriptionFile;'#010+ ' If FileExists(FN) then'#010+ ' begin'#010+ ' L:=TStringList.Create;'#010+ ' Try'#010+ ' L.LoadFromFile(FN',');'#010+ ' Result:=L.Text;'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Function TPackage.GetVersion : string;'#010+ 'begin'#010+ ' result:=FVersion.AsString;'#010+ 'end;'#010+ #010+ #010+ 'Procedure TPackage.SetVersion(cons','t V : string);'#010+ 'begin'#010+ ' FVersion.AsString:=V;'#010+ 'end;'#010+ #010+ #010+ 'Function TPackage.GetFileName : string;'#010+ 'begin'#010+ ' If (FFileName<>'#039#039') then'#010+ ' Result:=FFileName'#010+ ' else'#010+ ' if not FVersion.Empty then'#010+ ' Result := Name + '#039'-'#039' + FVersion.AsString'#010+ ' else'#010, ' Result := Name;'#010+ 'end;'#010+ #010+ #010+ 'Procedure TPackage.GetManifest(Manifest : TStrings);'#010+ #010+ ' procedure AddOSes(const AIndent:string;AOSes:TOSes);'#010+ ' var'#010+ ' IOS : TOS;'#010+ ' begin'#010+ ' if (AOSes=AllOSes) then'#010+ ' exit;'#010+ ' Manifest.Add(AIndent+'#039''#039,');'#010+ ' for IOS:=low(TOSes) to high(TOSes) do'#010+ ' if IOS in AOSes then'#010+ ' Manifest.Add(Format(AIndent+'#039' '#039',[OSToSt'+ 'ring(IOS)]));'#010+ ' Manifest.Add(AIndent+'#039''#039');'#010+ ' end;'#010+ #010+ ' procedure AddCPUs(const AIndent:string;ACPUs:','TCPUs);'#010+ ' var'#010+ ' ICPU : TCPU;'#010+ ' begin'#010+ ' if (ACPUs=AllCPUs) then'#010+ ' exit;'#010+ ' Manifest.Add(AIndent+'#039''#039');'#010+ ' for ICPU:=low(TCPUs) to high(TCPUs) do'#010+ ' if ICPU in ACPUs then'#010+ ' Manifest.Add(Format(AIndent+'#039' ',#039',[CPUTo'+ 'String(ICPU)]));'#010+ ' Manifest.Add(AIndent+'#039''#039');'#010+ ' end;'#010+ #010+ 'Var'#010+ ' S : String;'#010+ ' i : Integer;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' With Manifest do'#010+ ' begin'#010+ ' Add(Format('#039''#039',[QuoteXml(Name)]));'#010+ ' Add(Format('#039' '#039',[FVersion.Major,FVersion.Minor,FVersion.Micro,FVersion.Bu'+ 'ild]));'#010+ ' AddOSes('#039' '#039',OSes);'#010+ ' AddCPUs('#039' '#039',CPUs);'#010+ ' Add(Format('#039' %s'#039',[QuoteXml(FileName +'+ ' ZipExt)]));'#010+ ' Add','(Format('#039' %s'#039',[QuoteXml(Author)]));'#010+ ' Add(Format('#039' %s'#039',[QuoteXml(License)]));'+ #010+ ' if HomepageURL<>'#039#039' then'#010+ ' Add(Format('#039' %s'#039',[QuoteXml(Ho'+ 'mepageURL)]));'#010+ ' if DownloadURL<','>'#039#039' then'#010+ ' Add(Format('#039' %s'#039',[QuoteXml(Do'+ 'wnloadURL)]));'#010+ ' Add(Format('#039' %s'#039',[QuoteXMl(Email)]));'#010+ ' S:=Description;'#010+ ' If (S<>'#039#039') then'#010+ ' Add(Format('#039' %s'#039',[QuoteX','ML('+ 'S)]));'#010+ ' If (Dependencies.Count>0) then'#010+ ' begin'#010+ ' Add('#039' '#039');'#010+ ' for I:=0 to Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=Dependencies[i];'#010+ ' Add('#039' '#039');'#010+ ' Add(Format('#039,' '#039',[Quot'+ 'eXML(D.Value)]));'#010+ ' if not D.FVersion.Empty then'#010+ ' Add(Format('#039' '#039',[D.FVersion.Major,D.FVersion.Minor,D.FVersion.M'+ 'icro,D.FVers','ion.Build]));'#010+ ' AddOSes('#039' '#039',D.OSes);'#010+ ' AddCPUs('#039' '#039',D.CPUs);'#010+ ' Add('#039' '#039');'#010+ ' end;'#010+ ' Add('#039' '#039');'#010+ ' end;'#010+ ' Add('#039''#039');'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.Loa','dUnitConfigFromFile(Const AFileName: String);'#010+ 'var'#010+ ' L,L2 : TStrings;'#010+ ' VOS : TOS;'#010+ ' VCPU : TCPU;'#010+ ' i,k : Integer;'#010+ ' DepChecksum : Cardinal;'#010+ ' DepName : String;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' L:=TStringList.Create;'#010+ ' Try'#010+ ' ReadIniFile(AFileNam','e,L);'#010+ ' With L do'#010+ ' begin'#010+ ' Version:=Values[KeyVersion];'#010+ ' InstalledChecksum:=Cardinal(StrToInt64Def(Values[KeyChecksum],'+ '$ffffffff));'#010+ ' VCPU:=StringToCPU(Values[KeyCPU]);'#010+ ' VOS:=StringToOS(Values[KeyOS]);'#010+ ' ',' OSes:=[VOS];'#010+ ' CPUs:=[VCPU];'#010+ ' L2:=TStringList.Create;'#010+ ' L2.CommaText:=Values[KeyDepends];'#010+ ' for i:=0 to L2.Count-1 do'#010+ ' begin'#010+ ' DepName:=L2[i];'#010+ ' k:=Pos('#039'|'#039',DepName);'#010+ ' if k>','0 then'#010+ ' begin'#010+ ' DepChecksum:=StrToInt(Copy(DepName,k+1,Length(DepName)'+ '-k));'#010+ ' DepName:=Copy(DepName,1,k-1);'#010+ ' end'#010+ ' else'#010+ ' DepChecksum:=$ffffffff;'#010+ ' D:=Dep','endencies.Add(DepName,CPUs,OSes);'#010+ ' D.RequireChecksum:=DepChecksum;'#010+ ' end;'#010+ ' FreeAndNil(L2);'#010+ ' NeedLibC:=Upcase(Values[KeyNeedLibC])='#039'Y'#039';'#010+ ' end;'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TPackage.SaveUn','itConfigToFile(Const AFileName: String;ACPU'+ ':TCPU;AOS:TOS);'#010+ 'Var'#010+ ' F : TFileStream;'#010+ ' L : TStringList;'#010+ ' Deps : String;'#010+ ' i : integer;'#010+ ' D : TDependency;'#010+ ' p : TPackage;'#010+ 'begin'#010+ ' F:=TFileStream.Create(AFileName,fmCreate);'#010+ ' L:=TStringList.Crea','te;'#010+ ' try'#010+ ' With L do'#010+ ' begin'#010+ ' Values[KeyName]:=Name;'#010+ ' Values[KeyVersion]:=Version;'#010+ ' // TODO Generate checksum based on PPUs'#010+ ' Values[KeyChecksum]:=IntToStr(DateTimeToFileDate(Now));'#010+ ' Values[KeyCPU]:=','CPUToString(ACPU);'#010+ ' Values[KeyOS]:=OSToString(AOS);'#010+ ' Deps:='#039#039';'#010+ ' for i:=0 to Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=Dependencies[i];'#010+ ' if (ACPU in D.CPUs) and (AOS in D.OSes) then'#010+ ' ','begin'#010+ ' if Deps<>'#039#039' then'#010+ ' Deps:=Deps+'#039','#039';'#010+ ' Deps:=Deps+D.Value;'#010+ ' P:=TPackage(D.Target);'#010+ ' if assigned(P) and (P.InstalledChecksum<>$ffffffff) th'+ 'en'#010+ ' D','eps:=Deps+'#039'|'#039'+IntToStr(P.InstalledChecksu'+ 'm);'#010+ ' end;'#010+ ' end;'#010+ ' Values[KeyDepends]:=Deps;'#010+ ' if NeedLibC then'#010+ ' Values[KeyNeedLibC]:='#039'Y'#039#010+ ' else'#010+ ' Values[KeyNeedLibC]:='#039'N'#039';'#010+ ' end;'#010+ ' L.S','aveToStream(F);'#010+ ' Finally'#010+ ' L.Free;'#010+ ' F.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TPackages'#010+ '*********************************************************','***********'+ '********}'#010+ #010+ 'function TPackages.GetPackage(const AName : String): TPackage;'#010+ 'begin'#010+ ' Result:=TPackage(ItemByName(AName))'#010+ 'end;'#010+ #010+ 'function TPackages.GetPackageItem(AIndex : Integer): TPackage;'#010+ 'begin'#010+ ' Result:=TPackage(Items[AIndex]);'#010+ 'e','nd;'#010+ #010+ #010+ 'procedure TPackages.SetPackageItem(AIndex : Integer; const AValue: TPa'+ 'ckage);'#010+ 'begin'#010+ ' Items[AIndex]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'function TPackages.AddPackage(const AName: String): TPackage;'#010+ 'begin'#010+ ' Result:=Add as TPackage;'#010+ ' Result.Name:=AName;'#010+ 'e','nd;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TCustomDefaults'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'procedure TCustomDefaults.SetCPU','(const AValue: TCPU);'#010+ 'begin'#010+ ' FCPU:=AValue;'#010+ ' RecalcTarget;'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetBaseInstallDir: String;'#010+ 'begin'#010+ ' If (FBaseInstallDir<>'#039#039') then'#010+ ' Result:=FBaseInstallDir'#010+ ' else'#010+ ' if UnixPaths then'#010+ ' Result:=Prefix +'#039'lib',#039' + PathDelim + '#039'fpc'#039' + Path'+ 'Delim'#010+ ' else'#010+ ' Result:=Prefix;'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetBinInstallDir: String;'#010+ 'begin'#010+ ' If (FBinInstallDir<>'#039#039') then'#010+ ' Result:=FBinInstallDir'#010+ ' else'#010+ ' If UnixPaths then'#010+ ' Result:=BaseInstal','lDir+'#039'bin'#039#010+ ' else'#010+ ' Result:=BaseInstallDir+'#039'bin'#039';'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetCompiler: String;'#010+ 'begin'#010+ ' If (FCompiler<>'#039#039') then'#010+ ' Result:=FCompiler'#010+ ' else'#010+ ' Result:='#039'fpc'#039';'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetDocInstallDir: S','tring;'#010+ 'begin'#010+ ' If (FBinInstallDir<>'#039#039') then'#010+ ' Result:=FBinInstallDir'#010+ ' else'#010+ ' If UnixPaths then'#010+ ' Result:=Prefix+'#039'share'#039'+PathDelim+'#039'doc'#039#010+ ' else'#010+ ' Result:=BaseInstallDir+'#039'docs'#039';'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetExamplesInstal','lDir: String;'#010+ 'begin'#010+ ' If (FExamplesInstallDir<>'#039#039') then'#010+ ' Result:=FExamplesInstallDir'#010+ ' else'#010+ ' If UnixPaths then'#010+ ' Result:=Prefix+'#039'share'#039'+PathDelim+'#039'docs'#039'+PathDeli'+ 'm+'#039'examples'#039#010+ ' else'#010+ ' Result:=BaseInstallDir+'#039'examples'#039';'#010+ 'end;'#010+ #010, #010+ 'function TCustomDefaults.GetUnitInstallDir: String;'#010+ 'begin'#010+ ' If (FUnitInstallDir<>'#039#039') then'#010+ ' Result:=FUnitInstallDir'#010+ ' else'#010+ ' If UnixPaths then'#010+ ' Result:=BaseInstallDir+'#039'units'#039'+PathDelim+Target'#010+ ' else'#010+ ' Result:=BaseInstallDir+',#039'units'#039'+PathDelim+Target;'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetLocalUnitDir: String;'#010+ 'begin'#010+ ' Result:=FLocalUnitDir;'#010+ 'end;'#010+ #010+ #010+ 'function TCustomDefaults.GetGlobalUnitDir: String;'#010+ 'begin'#010+ ' If (FGlobalUnitDir<>'#039#039') then'#010+ ' Result:=FGlobalUnitDir'#010+ ' el','se'#010+ ' Result:=UnitInstallDir;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SetLocalUnitDir(const AValue: String);'#010+ 'begin'#010+ ' // Use ExpandFileName to support ~/ expansion'#010+ ' if AValue<>'#039#039' then'#010+ ' FLocalUnitDir:=IncludeTrailingPathDelimiter(ExpandFileName','(AValu'+ 'e))'#010+ ' else'#010+ ' FLocalUnitDir:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SetGlobalUnitDir(const AValue: String);'#010+ 'begin'#010+ ' // Use ExpandFileName to support ~/ expansion'#010+ ' if AValue<>'#039#039' then'#010+ ' FGlobalUnitDir:=IncludeTrailingPathDelimiter(Exp','andFileName(AVal'+ 'ue))'#010+ ' else'#010+ ' FGlobalUnitDir:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SetBaseInstallDir(const AValue: String);'#010+ 'begin'#010+ ' // Use ExpandFileName to support ~/ expansion'#010+ ' if AValue<>'#039#039' then'#010+ ' FBaseInstallDir:=IncludeTrailingPat','hDelimiter(ExpandFileName(AVa'+ 'lue))'#010+ ' else'#010+ ' FBaseInstallDir:='#039#039';'#010+ ' UnitInstallDir:='#039#039';'#010+ ' BinInstallDir:='#039#039';'#010+ ' ExamplesInstallDir:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SetOS(const AValue: TOS);'#010+ 'begin'#010+ ' FOS:=AValue;'#010+ ' Recalctarget;'#010+ 'end;'#010+ #010+ #010+ 'p','rocedure TCustomDefaults.SetPrefix(const AValue: String);'#010+ 'begin'#010+ ' if FPrefix=AValue then exit;'#010+ ' FPrefix:=IncludeTrailingPathDelimiter(AValue);'#010+ ' BaseInstallDir:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SetTarget(const AValue: String);'#010+ 'Var'#010+ ' P ',': Integer;'#010+ 'begin'#010+ ' if FTarget<>AValue then'#010+ ' begin'#010+ ' P:=Pos('#039'-'#039',AValue);'#010+ ' If (P<>0) then'#010+ ' begin'#010+ ' FOS:=StringToOS(System.Copy(Avalue,P+1,Length(AValue)-P));'#010+ ' FCPU:=StringToCPU(System.Copy(Avalue,1,P-1));'#010+ ' ',' end'#010+ ' else'#010+ ' FOS:=StringToOS(AValue);'#010+ ' FTarget:=AValue;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.RecalcTarget;'#010+ 'begin'#010+ ' Ftarget:=CPUToString(FCPU)+'#039'-'#039'+OStoString(FOS);'#010+ 'end;'#010+ #010+ #010+ 'constructor TCustomDefaults.Create;'#010+ 'begin'#010+ ' ',' InitDefaults;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.InitDefaults;'#010+ 'begin'#010+ '{$ifdef unix}'#010+ ' UnixPaths:=True;'#010+ '{$else}'#010+ ' UnixPaths:=False;'#010+ '{$endif}'#010+ ' FNoFPCCfg:=False;'#010+ ' FCPU:=cpuNone;'#010+ ' FOS:=osNone;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.LocalInit(Const A','FileName : String);'#010+ 'Var'#010+ ' FN : String;'#010+ 'begin'#010+ ' FN:=AFileName;'#010+ ' If (FN='#039#039') then'#010+ ' begin'#010+ ' // Environment variable.'#010+ ' FN:=GetEnvironmentVariable('#039'FPMAKECFG'#039');'#010+ ' If (FN<>'#039#039') then'#010+ ' If not FileExists(FN) then'#010+ ' FN:='#039#039';'#010+ ' //',' User config file fpmake.cfg'#010+ ' If (FN='#039#039') then'#010+ ' begin'#010+ ' FN:=GetAppConfigFile(False);'#010+ ' If Not FileExists(FN) then'#010+ ' FN:='#039#039';'#010+ ' end;'#010+ ' // Global config file fpmake.cfg'#010+ ' If (FN='#039#039') then'#010+ ' begin'#010+ ' FN:=GetAp','pConfigFile(True);'#010+ ' If Not FileExists(FN) then'#010+ ' FN:='#039#039';'#010+ ' end;'#010+ ' end;'#010+ ' If (FN<>'#039#039') and FileExists(FN) then'#010+ ' LoadFromFile(FN);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.CompilerDefaults;'#010+ '{$ifdef HAS_UNIT_PROCESS}'#010+ 'var'#010+ ' infoSL : ','TStringList;'#010+ '{$endif HAS_UNIT_PROCESS}'#010+ 'begin'#010+ ' if (CPU=cpuNone) or (OS=osNone) or (FCompilerVersion='#039#039') then'#010+ ' begin'#010+ '{$ifdef HAS_UNIT_PROCESS}'#010+ ' // Detect compiler version/target from -i option'#010+ ' infosl:=TStringList.Create;'#010+ ' ','infosl.Delimiter:='#039' '#039';'#010+ ' infosl.DelimitedText:=GetCompilerInfo(GetCompiler,'#039'-iVTPTO'#039+ ');'#010+ ' if infosl.Count<>3 then'#010+ ' Raise EInstallerError.Create(SErrInvalidFPCInfo);'#010+ ' if FCompilerVersion='#039#039' then'#010+ ' FCompilerVersion:=i','nfosl[0];'#010+ ' if CPU=cpuNone then'#010+ ' CPU:=StringToCPU(infosl[1]);'#010+ ' if OS=osNone then'#010+ ' OS:=StringToOS(infosl[2]);'#010+ '{$else HAS_UNIT_PROCESS}'#010+ ' // Defaults taken from compiler used to build fpmake'#010+ ' if CPU=cpuNone the','n'#010+ ' CPU:=StringToCPU({$I %FPCTARGETCPU%});'#010+ ' if OS=osNone then'#010+ ' OS:=StringToOS({$I %FPCTARGETOS%});'#010+ ' if FCompilerVersion='#039#039' then'#010+ ' FCompilerVersion:={$I %FPCVERSION%};'#010+ '{$endif HAS_UNIT_PROCESS}'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'pr','ocedure TCustomDefaults.LoadFromFile(Const AFileName: String);'#010+ 'Var'#010+ ' F : TFileStream;'#010+ 'begin'#010+ ' F:=TFileStream.Create(AFileName,fmOpenRead);'#010+ ' Try'#010+ ' LoadFromStream(F);'#010+ ' Finally'#010+ ' F.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SaveToFile','(Const AFileName: String);'#010+ 'Var'#010+ ' F : TFileStream;'#010+ 'begin'#010+ ' F:=TFileStream.Create(AFileName,fmCreate);'#010+ ' Try'#010+ ' SaveToStream(F);'#010+ ' Finally'#010+ ' F.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomDefaults.SaveToStream(S : TStream);'#010+ 'Var'#010+ ' L : TStringList;'#010, 'begin'#010+ ' L:=TStringList.Create;'#010+ ' try'#010+ ' With L do'#010+ ' begin'#010+ ' Values[KeyArchive]:=FArchive;'#010+ ' Values[KeyCompiler]:=FCompiler;'#010+ ' Values[KeyCopy]:=FCopy;'#010+ ' Values[KeyMkDir]:=FMkDir;'#010+ ' Values[KeyMove]:=FMove;'#010+ ' Value','s[KeyOptions]:=FOptions;'#010+ ' Values[KeyCPU]:=CPUToString(FCPU);'#010+ ' Values[KeyOS]:=OSToString(FOS);'#010+ ' Values[KeyMode]:=ModeToString(FMode);'#010+ ' Values[KeyLocalUnitDir]:=FLocalUnitDir;'#010+ ' Values[KeyGlobalUnitDir]:=FGlobalUnitDir',';'#010+ ' Values[KeyPrefix]:=FPrefix;'#010+ ' Values[KeyBaseInstallDir]:=FBaseInstallDir;'#010+ ' Values[KeyUnitInstallDir]:=FUnitInstallDir;'#010+ ' Values[KeyBinInstallDir]:=FBinInstallDir;'#010+ ' Values[KeyDocInstallDir]:=FDocInstallDir;'#010+ ' Va','lues[KeyExamplesInstallDir]:=FExamplesInstallDir;'#010+ ' Values[KeyRemove]:=FRemove;'#010+ ' Values[KeyTarget]:=FTarget;'#010+ ' if FNoFPCCfg then'#010+ ' Values[KeyNoFPCCfg]:='#039'Y'#039';'#010+ ' end;'#010+ ' L.SaveToStream(S);'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ 'e','nd;'#010+ #010+ #010+ 'procedure TCustomDefaults.LoadFromStream(S: TStream);'#010+ 'Var'#010+ ' L : TStrings;'#010+ ' Line : String;'#010+ ' I,P,PC : Integer;'#010+ 'begin'#010+ ' L:=TStringList.Create;'#010+ ' Try'#010+ ' L.LoadFromStream(S);'#010+ ' // Fix lines.'#010+ ' For I:=L.Count-1 downto 0 do'#010+ ' begi','n'#010+ ' Line:=L[I];'#010+ ' P:=Pos('#039'='#039',Line);'#010+ ' PC:=Pos('#039';'#039',Line); // Comment line.'#010+ ' If (P=0) or ((PC<>0) and (PC'#039#039') then'#010+ ' FCPU:=StringToCPU(Line);'#010+ ' Line:=Values[KeyOS];'#010+ ' If (Line<>'#039#039') then'#010+ ' FOS:=StringToOS(Line);'#010+ ' Line:=Values[KeyMo','de];'#010+ ' If (Line<>'#039#039') then'#010+ ' FMode:=StringToMode(Line);'#010+ ' FTarget:=Values[KeyTarget];'#010+ ' FLocalUnitDir:=Values[KeyLocalUnitDir];'#010+ ' FGlobalUnitDir:=Values[KeyGlobalUnitDir];'#010+ ' FPrefix:=Values[KeyPrefix];'#010+ ' FBaseIn','stallDir:=Values[KeyBaseInstallDir];'#010+ ' FUnitInstallDir:=Values[KeyUnitInstallDir];'#010+ ' FBinInstallDir:=Values[KeyBinInstallDir];'#010+ ' FDocInstallDir:=Values[KeyDocInstallDir];'#010+ ' FExamplesInstallDir:=Values[KeyExamplesInstallDir];',#010+ ' FNoFPCCfg:=(Upcase(Values[KeyNoFPCCfg])='#039'Y'#039');'#010+ ' end;'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TFPCDefaults'#010+ '********************','************************************************'+ '********}'#010+ #010+ 'procedure TFPCDefaults.CompilerDefaults;'#010+ 'var'#010+ ' BD : String;'#010+ 'begin'#010+ ' inherited CompilerDefaults;'#010+ #010+ ' // Use the same algorithm as the compiler, see options.pas'#010+ '{$ifdef Unix}'#010+ ' BD:=Fix','Path(GetEnvironmentVariable('#039'FPCDIR'#039'));'#010+ ' if BD='#039#039' then'#010+ ' begin'#010+ ' BD:='#039'/usr/local/lib/fpc/'#039'+FCompilerVersion;'#010+ ' if not DirectoryExists(BD) and'#010+ ' DirectoryExists('#039'/usr/lib/fpc/'#039'+FCompilerVersion) the'+ 'n'#010+ ' BD:='#039'/usr/lib/f','pc/'#039'+FCompilerVersion;'#010+ ' end;'#010+ '{$else unix}'#010+ ' BD:=FixPath(GetEnvironmentVariable('#039'FPCDIR'#039'));'#010+ ' if BD='#039#039' then'#010+ ' begin'#010+ ' BD:=ExtractFilePath(FCompiler)+'#039'..'#039';'#010+ ' if not(DirectoryExists(BD+'#039'/units'#039')) and'#010+ ' not(DirectoryExists(B','D+'#039'/rtl'#039')) then'#010+ ' BD:=FBaseInstallDir+'#039'..'#039';'#010+ ' end;'#010+ '{$endif unix}'#010+ #010+ ' // Where to install by default'#010+ ' if (FBaseInstallDir='#039#039') and (FPrefix='#039#039') then'#010+ ' BaseInstallDir:=BD;'#010+ #010+ ' // Where to find the units by default'#010+ ' if (FGlobalUnitDir','='#039#039') then'#010+ ' GlobalUnitDir:=IncludeTrailingPathDelimiter(BD)+'#039'units'#039'+Pa'+ 'thDelim+Target;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TCustomInstaller'#010+ '**********************','**********************************************'+ '********}'#010+ #010+ 'constructor TCustomInstaller.Create(AOwner: TComponent);'#010+ 'begin'#010+ ' Dictionary:=DictionaryClass.Create(Nil);'#010+ ' AnalyzeOptions;'#010+ ' CreatePackages;'#010+ 'end;'#010+ #010+ #010+ 'destructor TCustomInstaller.Destro','y;'#010+ 'begin'#010+ ' FreeAndNil(Defaults);'#010+ ' FreeAndNil(Dictionary);'#010+ ' inherited destroy;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Log(Level: TVerboseLevel; const Msg: String'+ ');'#010+ 'begin'#010+ ' If Level in FLogLevels then'#010+ ' Writeln(StdOut,Msg);'#010+ 'end;'#010+ #010+ #010+ 'procedure TC','ustomInstaller.CreatePackages;'#010+ 'begin'#010+ ' FPAckages:=TPackages.Create(TPackage);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.CreateBuildEngine;'#010+ 'begin'#010+ ' FBuildEngine:=TBuildEngine.Create(Self);'#010+ '// FBuildEngine.Defaults:=Defaults;'#010+ ' FBuildEngine.ListMode',':=FListMode;'#010+ ' FBuildEngine.OnLog:=@Self.Log;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Error(const Msg: String);'#010+ 'begin'#010+ ' Raise EInstallerError.Create(Msg);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Error(const Fmt: String; Args: array of con'+ 'st);'#010+ 'begin'#010+ ' R','aise EInstallerError.CreateFmt(Fmt,Args);'#010+ 'end;'#010+ #010+ #010+ 'Function TCustomInstaller.AddPackage(const AName: String) : TPackage;'#010+ 'begin'#010+ ' result:=FPackages.AddPackage(AName);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.AnalyzeOptions;'#010+ #010+ ' Function CheckOption(In','dex : Integer;const Short,Long : String): B'+ 'oolean;'#010+ ' var'#010+ ' O : String;'#010+ ' begin'#010+ ' O:=Paramstr(Index);'#010+ ' Result:=(O='#039'-'#039'+short) or (O='#039'--'#039'+long) or (copy(O,'+ '1,Length(Long)+3)=('#039'--'#039'+long+'#039'='#039'));'#010+ ' end;'#010+ #010+ ' Function CheckCommand(Index : Integ','er;const Short,Long : String): '+ 'Boolean;'#010+ ' var'#010+ ' O : String;'#010+ ' begin'#010+ ' O:=Paramstr(Index);'#010+ ' Result:=(O='#039'-'#039'+short) or (O=long);'#010+ ' end;'#010+ #010+ ' Function OptionArg(Var Index : Integer) : String;'#010+ ' Var'#010+ ' P : Integer;'#010+ ' begin'#010+ ' if (Length(P','aramStr(Index))>1) and (Paramstr(Index)[2]<>'#039'-'#039+ ') then'#010+ ' begin'#010+ ' If Index2 then'#010+ ' begin'#010+ ' P:=Pos('#039'='#039',Paramstr(Index));'#010+ ' If (P=0) then'#010+ ' Error(SErrNeedArgument,[Index,ParamStr(Index)])'#010+ ' else'#010+ ' begin'#010+ ' Result:=Paramstr(Index);'#010+ ' ',' Delete(Result,1,P);'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ #010+ 'Var'#010+ ' I : Integer;'#010+ ' DefaultsFileName : string;'#010+ 'begin'#010+ ' I:=0;'#010+ ' FListMode:=False;'#010+ ' FLogLevels:=DefaultMessages;'#010+ ' While (I'#039#039' then'#010+ ' Defaults.LocalInit(DefaultsFileName);'#010+ ' Defaults.CompilerDefaults;'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Usage(const FMT: String; Args: array of con'+ 'st);'#010+ #010+ ' Procedure LogCmd(const LC,Msg : String);'#010+ ' begin'#010+ ' Log(vlInfo,Format('#039' %','-12s %s'#039',[LC,MSG]));'#010+ ' end;'#010+ #010+ ' Procedure LogOption(const C,LC,Msg : String);'#010+ ' begin'#010+ ' Log(vlInfo,Format('#039' -%s --%-16s %s'#039',[C,LC,MSG]));'#010+ ' end;'#010+ #010+ ' Procedure LogArgOption(const C,LC,Msg : String);'#010+ ' begin'#010+ ' Log(vlInfo,Format('#039' -%s --%-20','s %s'#039',[C,LC+'#039'='#039'+SV'+ 'alue,MSG]));'#010+ ' end;'#010+ #010+ 'begin'#010+ ' // Force the Usage to be displayed'#010+ ' Include(FLogLevels,vlInfo);'#010+ ' If (FMT<>'#039#039') then'#010+ ' Log(vlInfo,Format(Fmt,Args));'#010+ ' Log(vlInfo,Format(SHelpUsage,[Paramstr(0)]));'#010+ ' Log(vlInfo,SHelpCommand)',';'#010+ ' LogCmd('#039'compile'#039',SHelpCompile);'#010+ ' LogCmd('#039'build'#039',SHelpBuild);'#010+ ' LogCmd('#039'install'#039',SHelpInstall);'#010+ ' LogCmd('#039'clean'#039',SHelpClean);'#010+ ' LogCmd('#039'archive'#039',SHelpArchive);'#010+ ' LogCmd('#039'manifest'#039',SHelpManifest);'#010+ ' Log(vlInfo,SHelpCmdOptions);'#010+ ' LogOpti','on('#039'h'#039','#039'help'#039',SHelpHelp);'#010+ ' LogOption('#039'l'#039','#039'list-commands'#039',SHelpList);'#010+ ' LogOption('#039'n'#039','#039'nofpccfg'#039',SHelpNoFPCCfg);'#010+ ' LogOption('#039'v'#039','#039'verbose'#039',SHelpVerbose);'#010+ ' LogArgOption('#039'C'#039','#039'cpu'#039',SHelpCPU);'#010+ ' LogArgOption('#039'O'#039','#039'os'#039',SHelpOS);'#010+ ' LogArgOption('#039,'t'#039','#039'target'#039',SHelpTarget);'#010+ ' LogArgOption('#039'P'#039','#039'prefix'#039',SHelpPrefix);'#010+ ' LogArgOption('#039'B'#039','#039'baseinstalldir'#039',SHelpBaseInstalldi'+ 'r);'#010+ ' LogArgOption('#039'UL'#039','#039'localunitdir'#039',SHelpLocalUnitdir);'+ #010+ ' LogArgOption('#039'UG'#039','#039'globalunitdir'#039',SHelpGlobalUnitdir'+ ');'#010+ ' ','LogArgOption('#039'r'#039','#039'compiler'#039',SHelpCompiler);'#010+ ' LogArgOption('#039'f'#039','#039'config'#039',SHelpConfig);'#010+ ' Log(vlInfo,'#039#039');'#010+ ' If (FMT<>'#039#039') then'#010+ ' halt(1)'#010+ ' else'#010+ ' halt(0);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Compile(Force: Boolean);'#010+ 'begin'#010+ ' FBuildEngine.Forc','eCompile:=Force;'#010+ ' FBuildEngine.Compile(FPackages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Clean;'#010+ 'begin'#010+ ' BuildEngine.Clean(FPackages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Install;'#010+ 'begin'#010+ ' BuildEngine.Install(FPackages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomIn','staller.Archive;'#010+ 'begin'#010+ ' // Force generation of manifest.xml, this is required for the reposi'+ 'tory'#010+ ' BuildEngine.Manifest(FPackages);'#010+ ' BuildEngine.Archive(FPackages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.Manifest;'#010+ 'begin'#010+ ' BuildEngine.Manifest(','FPackages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.CheckPackages;'#010+ 'begin'#010+ ' If (FPackages.Count=0) then'#010+ ' Error(SErrNoPackagesDefined);'#010+ ' // Check for other obvious errors ?'#010+ 'end;'#010+ #010+ #010+ 'Function TCustomInstaller.Run : Boolean;'#010+ 'begin'#010+ ' Result:=True;'#010+ ' ',' try'#010+ ' CheckPackages;'#010+ ' CreateBuildEngine;'#010+ ' Case RunMode of'#010+ ' rmCompile : Compile(False);'#010+ ' rmBuild : Compile(True);'#010+ ' rmInstall : Install;'#010+ ' rmArchive : Archive;'#010+ ' rmClean : Clean;'#010+ ' rmManifest : Manifes','t;'#010+ ' end;'#010+ ' except'#010+ ' On E : Exception do'#010+ ' begin'#010+ ' Log(vlError,SErrInstaller);'#010+ ' Log(vlError,E.Message);'#010+ ' Result:=False;'#010+ ' end;'#010+ ' end;'#010+ ' // Force returning an exitcode to the shell'#010+ ' if not Result then'#010+ ' ExitCode:','=1;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TFPCInstaller'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TFPCInstaller.','Create(AOwner: TComponent);'#010+ 'begin'#010+ ' if assigned(Defaults) then'#010+ ' Error(SErrAlreadyInitialized);'#010+ ' Defaults:=TFPCDefaults.Create;'#010+ ' inherited Create(AOwner);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '****','***'#010+ ' TBasicInstaller'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TBasicInstaller.Create(AOwner: TComponent);'#010+ 'begin'#010+ ' if assigned(Defaults) then'#010+ ' Error(SErrAlr','eadyInitialized);'#010+ ' Defaults:=TBasicDefaults.Create;'#010+ ' inherited Create(AOwner);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TBuildEngine'#010+ '****************************','****************************************'+ '********}'#010+ #010+ 'constructor TBuildEngine.Create(AOwner: TComponent);'#010+ 'begin'#010+ ' inherited Create(AOwner);'#010+ ' // Maybe this should be the current directory ?'#010+ ' // Or have it as a command-line option.'#010+ ' // Would',' allow to put all '#039'installers'#039' in one dir and call'+ ' them'#010+ ' // With --start-dir=/path/to/sources.'#010+ ' FStartDir:=includeTrailingPathDelimiter(GetCurrentDir);'#010+ ' FExternalPackages:=TPackages.Create(TPackage);'#010+ 'end;'#010+ #010+ #010+ 'destructor TBuildEngine.Destro','y;'#010+ 'begin'#010+ ' FreeAndNil(FExternalPackages);'#010+ ' inherited Destroy;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Error(const Msg: String);'#010+ 'begin'#010+ ' Raise EInstallerError.Create(Msg);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Error(const Fmt: String; const Args: array of c'+ 'o','nst);'#010+ 'begin'#010+ ' Raise EInstallerError.CreateFmt(Fmt,Args);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.ExecuteCommand(const Cmd,Args : String; IgnoreE'+ 'rror : Boolean = False);'#010+ 'Var'#010+ ' E : Integer;'#010+ 'begin'#010+ ' Log(vlInfo,SInfoExecutingCommand,[Cmd,Args]);'#010+ ' if Lis','tMode then'#010+ ' Log(vlCommand,'#039'%s %s'#039',[Cmd,Args])'#010+ ' else'#010+ ' begin'#010+ ' // We should check cmd for spaces, and move all after first spac'+ 'e to args.'#010+ ' E:=ExecuteProcess(cmd,args);'#010+ ' If (E<>0) and (not IgnoreError) then'#010+ ' Error(S','ErrExternalCommandFailed,[Cmd,E]);'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.SysDirectoryExists(const ADir:string):Boolean;'#010+ 'begin'#010+ ' result:=SysUtils.DirectoryExists(ADir);'#010+ ' if result then'#010+ ' Log(vlDebug,SDbgDirectoryExists,[ADir,SDbgFound])'#010+ ' ',' else'#010+ ' Log(vlDebug,SDbgDirectoryExists,[ADir,SDbgNotFound]);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.SysFileExists(const AFileName:string):Boolean;'#010+ 'begin'#010+ ' result:=SysUtils.FileExists(AFileName);'#010+ ' if result then'#010+ ' Log(vlDebug,SDbgFileExists,[AFi','leName,SDbgFound])'#010+ ' else'#010+ ' Log(vlDebug,SDbgFileExists,[AFileName,SDbgNotFound]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.SysCopyFile(Const Src,Dest : String);'#010+ 'Var'#010+ ' D,S : String;'#010+ ' Fin,FOut : TFileStream;'#010+ ' Count : Int64;'#010+ ' A : Integer;'#010+ 'begin'#010+ ' Lo','g(vlInfo,SInfoCopyingFile,[Src,Dest]);'#010+ ' FIn:=TFileStream.Create(Src,fmopenRead);'#010+ ' Try'#010+ ' D:=IncludeTrailingPathDelimiter(Dest);'#010+ ' If DirectoryExists(D) then'#010+ ' S:=D+ExtractFileName(Src)'#010+ ' else'#010+ ' S:=Dest;'#010+ ' FOut:=TFileStream.','Create(S,fmCreate);'#010+ ' Try'#010+ ' Count:=Fout.CopyFrom(FIn,0);'#010+ ' If (Count<>Fin.Size) then'#010+ ' Error(SErrCopyingFile,[Src,S]);'#010+ ' Finally'#010+ ' FreeAndNil(Fout);'#010+ ' end;'#010+ ' A:=FileGetDate(FIn.Handle);'#010+ ' If (A=-1) then'#010+ ' log','(vlWarning,SWarnFailedToGetTime,[Src])'#010+ ' else'#010+ ' if FileSetDate(S,A)<>0 then'#010+ ' Log(vlWarning,SWarnFailedToSetTime,[S]);'#010+ ' finally'#010+ ' FreeAndNil(Fin);'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.SysMoveFile(Const Src,Dest : String);'#010+ 'Var',#010+ ' S : String;'#010+ 'begin'#010+ ' If DirectoryExists(IncludeTrailingPathDelimiter(Dest)) then'#010+ ' S:=IncludeTrailingPathDelimiter(Dest)+ExtractFileName(Src)'#010+ ' else'#010+ ' S:=Dest;'#010+ ' If Not RenameFile(Src,S) then'#010+ ' begin'#010+ ' Try'#010+ ' SysCopyFile(Sr','c,S);'#010+ ' SysDeleteFile(Src);'#010+ ' Except'#010+ ' On E : Exception Do'#010+ ' Error(SErrMovingFile,[Src,S]);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.SysDeleteFile(Const AFileName : String);'#010+ 'begin'#010+ ' if not FileExists(AFileNa','me) then'#010+ ' Log(vlWarning,SWarnFileDoesNotExist,[AFileName])'#010+ ' else If Not DeleteFile(AFileName) then'#010+ ' Error(SErrDeletingFile,[AFileName]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.SysArchiveFiles(List: TStrings;Const AFileName:'+ ' String);'#010+ 'begin'#010+ ' I','f Not (Assigned(OnArchivefiles) or Assigned(ArchiveFilesProc)) th'+ 'en'#010+ ' Raise EInstallerError.Create(SErrNoArchiveSupport);'#010+ ' If Assigned(ArchiveFilesProc) then'#010+ ' ArchiveFilesProc(AFileName,List)'#010+ ' else'#010+ ' OnArchiveFiles(AFileName,List);',#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.LogIndent;'#010+ 'begin'#010+ ' FLogPrefix:=FLogPrefix+'#039' '#039';'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.LogUnIndent;'#010+ 'begin'#010+ ' Delete(FLogPrefix,1,2);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Log(Level: TVerboseLevel; const Msg: String);'#010+ 'begin'#010+ ' If',' Assigned(FOnLog) then'#010+ ' begin'#010+ ' if Level in [vlInfo,vlDebug] then'#010+ ' FOnLog(Level,FLogPrefix+Msg)'#010+ ' else'#010+ ' FOnLog(Level,Msg);'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Log(Level: TVerboseLevel; const Fmt: String;con'+ 'st Arg','s: array of const);'#010+ 'begin'#010+ ' Log(Level,Format(Fmt,Args));'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.EnterDir(ADir: String);'#010+ 'Var'#010+ ' D : String;'#010+ 'begin'#010+ ' D:=FStartDir;'#010+ ' D:=D+ADir;'#010+ ' Log(vlDebug,SDbgEnterDir,[D]);'#010+ ' If Not SetCurrentDir(D) then'#010+ ' Error(SE','rrChangeDirFailed,[D]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CmdCopyFiles(List: TStrings; Const DestDir: Str'+ 'ing);'#010+ #010+ 'Var'#010+ ' Args : String;'#010+ ' I : Integer;'#010+ #010+ 'begin'#010+ ' CmdCreateDir(DestDir);'#010+ ' If (Defaults.Copy<>'#039#039') then'#010+ ' begin'#010+ ' Args:=FileListToSt','ring(List,'#039#039');'#010+ ' Args:=Args+'#039' '#039'+DestDir;'#010+ ' ExecuteCommand(Defaults.Copy,Args);'#010+ ' end'#010+ ' else'#010+ ' For I:=0 to List.Count-1 do'#010+ ' SysCopyFile(List[i],DestDir);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CmdCreateDir(const DestDir: String);'#010+ 'beg','in'#010+ ' If (Defaults.MkDir<>'#039#039') then'#010+ ' ExecuteCommand(Defaults.MkDir,DestDir)'#010+ ' else'#010+ ' If not ForceDirectories(DestDir) then'#010+ ' Error(SErrCreatingDirectory,[DestDir]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CmdMoveFiles(List: TStrings; Const Des','tDir: S'+ 'tring);'#010+ 'Var'#010+ ' Args : String;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' CmdCreateDir(DestDir);'#010+ ' If (Defaults.Move<>'#039#039') then'#010+ ' begin'#010+ ' Args:=FileListToString(List,'#039#039');'#010+ ' Args:=Args+'#039' '#039'+DestDir;'#010+ ' ExecuteCommand(Defaults.Move,Args);'#010+ ' end',#010+ ' else'#010+ ' For I:=0 to List.Count-1 do'#010+ ' SysMoveFile(List[i],DestDir);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CmdDeleteFiles(List: TStrings);'#010+ 'Var'#010+ ' Args : String;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' If (Defaults.Remove<>'#039#039') then'#010+ ' begin'#010+ ' Args:=FileLi','stToString(List,'#039#039');'#010+ ' ExecuteCommand(Defaults.Remove,Args);'#010+ ' end'#010+ ' else'#010+ ' For I:=0 to List.Count-1 do'#010+ ' SysDeleteFile(List[i]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CmdArchiveFiles(List: TStrings; Const ArchiveFi'+ 'le: String);'#010+ 'Var'#010+ ' S,','C,O : String;'#010+ 'begin'#010+ ' If (Defaults.Archive='#039#039') then'#010+ ' SysArchiveFiles(List,ArchiveFile)'#010+ ' else'#010+ ' begin'#010+ ' S:=FileListToString(List,'#039#039');'#010+ ' SplitCommand(Defaults.Archive,C,O);'#010+ ' If (O='#039#039') then'#010+ ' O:=ArchiveFile+'#039' '#039'+S'#010+ ' ',' else'#010+ ' O:=Substitute(O,['#039'ARCHIVE'#039',ArchiveFile,'#039'FILESORDIR'+ 'S'#039']);'#010+ ' ExecuteCommand(C,O);'#010+ ' end;'#010+ 'end;'#010+ #010+ 'Function TBuildEngine.FileNewer(const Src,Dest : String) : Boolean;'#010+ #010+ 'Var'#010+ ' DS,DD : Longint;'#010+ ' D1,D2 : TDateTime;'#010+ #010+ 'begin'#010+ ' DS:=Fi','leAge(Src);'#010+ ' DD:=FileAge(Dest);'#010+ ' D1:=FileDateToDateTime(DS);'#010+ ' D2:=FileDateToDateTime(DD);'#010+ ' Log(vlDebug,SDbgComparingFileTimes,[Src,DateTimeToStr(D1),Dest,DateT'+ 'imeToStr(D2)]);'#010+ ' Result:=D1>=D2;'#010+ ' If Result then'#010+ ' Log(vlInfo,SInfoSource','NewerDest,[Src,DateTimeToStr(D1),Dest,Date'+ 'TimeToStr(D2)]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.ExecuteCommands(Commands: TCommands; At: TComma'+ 'ndAt);'#010+ 'Var'#010+ ' C : TCommand;'#010+ ' I : Integer;'#010+ ' Cmd,O : String;'#010+ ' E : Boolean;'#010+ 'begin'#010+ ' For I:=0 to Commands.','Count-1 do'#010+ ' begin'#010+ ' C:=Commands.CommandItems[i];'#010+ ' if (C.At=At) then'#010+ ' begin'#010+ ' E:=True;'#010+ ' If (C.SourceFile<>'#039#039') and (C.DestFile<>'#039#039') then'+ #010+ ' E:=FileNewer(C.SourceFile,IncludeTrailingPathDelimiter(D','i'+ 'ctionary.GetValue('#039'OUTPUTDIR'#039'))+C.DestFile);'#010+ ' If E then'#010+ ' begin'#010+ ' If Assigned(C.BeforeCommand) then'#010+ ' C.BeforeCommand(C);'#010+ ' O:=Substitute(C.Options,['#039'SOURCE'#039',C.SourceFile,'#039+ 'DEST'#039',C.DestFile',']);'#010+ ' Cmd:=C.Command;'#010+ ' If (ExtractFilePath(Cmd)='#039#039') then'#010+ ' Cmd:=ExeSearch(Cmd,GetEnvironmentvariable('#039'PATH'#039+ '));'#010+ ' ExecuteCommand(Cmd,O,C.IgnoreResult);'#010+ ' If Assigned(C.AfterCommand) then'#010, ' C.AfterCommand(C);'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Procedure TBuildEngine.LogSearchPath(const ASearchPathName:string;Path'+ ':TConditionalStrings; ACPU:TCPU;AOS:TOS);'#010+ 'var'#010+ ' S : String;'#010+ ' I : Integer;'#010+ ' C : TCondition','alString;'#010+ 'begin'#010+ ' S:='#039#039';'#010+ ' for i:=0 to Path.Count-1 do'#010+ ' begin'#010+ ' C:=Path[I];'#010+ ' if (ACPU in C.CPUs) and (AOS in C.OSes) then'#010+ ' begin'#010+ ' if S<>'#039#039' then'#010+ ' S:=S+PathSeparator;'#010+ ' S:=S+Dictionary.ReplaceStr','ings(C.Value)'#010+ ' end;'#010+ ' end;'#010+ ' if S<>'#039#039' then'#010+ ' Log(vlDebug,SDbgSearchPath,[ASearchPathName,S]);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.FindFileInPath(Path:TConditionalStrings; AFileNa'+ 'me:String; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean',';'#010+ 'var'#010+ ' I : Integer;'#010+ ' C : TConditionalString;'#010+ 'begin'#010+ ' Result:=false;'#010+ ' for i:=0 to Path.Count-1 do'#010+ ' begin'#010+ ' C:=Path[I];'#010+ ' if (ACPU in C.CPUs) and (AOS in C.OSes) then'#010+ ' begin'#010+ ' FoundPath:=IncludeTrailingPathDelimit','er(Dictionary.Replace'+ 'Strings(C.Value));'#010+ ' if FileExists(FoundPath+AFileName) then'#010+ ' begin'#010+ ' result:=true;'#010+ ' exit;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' FoundPath:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'Procedure TBuildEngin','e.ResolveFileNames(APackage : TPackage; ACPU:TC'+ 'PU;AOS:TOS;DoChangeDir:boolean=true);'#010+ #010+ ' procedure FindMainSource(T:TTarget);'#010+ ' var'#010+ ' SD,SF : String;'#010+ ' begin'#010+ ' LogSearchPath('#039'package source'#039',APackage.SourcePath,ACPU,AO'+ 'S);'#010+ ' SD:=Dictio','nary.ReplaceStrings(T.Directory);'#010+ ' SF:=Dictionary.ReplaceStrings(T.SourceFileName);'#010+ ' if SD='#039#039' then'#010+ ' FindFileInPath(APackage.SourcePath,SF,SD,ACPU,AOS);'#010+ ' if SD<>'#039#039' then'#010+ ' SD:=IncludeTrailingPathDelimiter(SD);'#010+ ' T.FTargetS','ourceFileName:=SD+SF;'#010+ ' if FileExists(T.TargetSourceFileName) then'#010+ ' Log(vlDebug,SDbgResolvedSourceFile,[T.SourceFileName,T.TargetSou'+ 'rceFileName])'#010+ ' else'#010+ ' begin'#010+ ' Log(vlWarning,SWarnSourceFileNotFound,[T.SourceFileName,Ma','ke'+ 'TargetString(ACPU,AOS)]);'#010+ ' T.FTargetSourceFileName:='#039#039';'#010+ ' end;'#010+ ' end;'#010+ #010+ ' procedure FindIncludeSources(T:TTarget);'#010+ ' var'#010+ ' SD,SF : String;'#010+ ' D : TDependency;'#010+ ' j : integer;'#010+ ' begin'#010+ ' LogSearchPath('#039'target include'#039',T.Inc','ludePath,ACPU,AOS);'#010+ ' LogSearchPath('#039'package include'#039',APackage.IncludePath,ACPU,'+ 'AOS);'#010+ ' for j:=0 to T.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=T.Dependencies[j];'#010+ ' if (D.DependencyType=depInclude) then'#010+ ' begin'#010+ ' ',' D.TargetFileName:='#039#039';'#010+ ' if (ACPU in D.CPUs) and (AOS in D.OSes) then'#010+ ' begin'#010+ ' if ExtractFilePath(D.Value)='#039#039' then'#010+ ' begin'#010+ ' SF:=Dictionary.ReplaceStrings(D.Value);',#010+ ' SD:='#039#039';'#010+ ' // first check the target specific path'#010+ ' if not FindFileInPath(T.IncludePath,SF,SD,ACPU,AOS'+ ') then'#010+ ' FindFileInPath(APackage.IncludePath,SF,SD,ACPU,A'+ 'OS);',#010+ ' if SD<>'#039#039' then'#010+ ' SD:=IncludeTrailingPathDelimiter(SD);'#010+ ' D.TargetFileName:=SD+SF;'#010+ ' end'#010+ ' else'#010+ ' D.TargetFileName:=D.Value;'#010+ ' ',' if FileExists(D.TargetFileName) then'#010+ ' Log(vlDebug,SDbgResolvedIncludeFile,[D.Value,D.Targe'+ 'tFileName])'#010+ ' else'#010+ ' begin'#010+ ' Log(vlWarning,SWarnIncludeFileNotFound,[D.Value,','M'+ 'akeTargetString(ACPU,AOS)]);'#010+ ' D.TargetFileName:='#039#039';'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ #010+ ' procedure FindExampleSource(T:TTarget);'#010+ ' var'#010+ ' SD,SF : String;'#010+ ' begin'#010+ ' LogSearchPa','th('#039'package example'#039',APackage.ExamplePath,ACP'+ 'U,AOS);'#010+ ' SD:=Dictionary.ReplaceStrings(T.Directory);'#010+ ' SF:=Dictionary.ReplaceStrings(T.SourceFileName);'#010+ ' if SD='#039#039' then'#010+ ' FindFileInPath(APackage.ExamplePath,SF,SD,ACPU,AOS);'#010+ ' if SD','<>'#039#039' then'#010+ ' SD:=IncludeTrailingPathDelimiter(SD);'#010+ ' T.FTargetSourceFileName:=SD+SF;'#010+ ' if FileExists(T.TargetSourceFileName) then'#010+ ' Log(vlDebug,SDbgResolvedSourceFile,[T.SourceFileName,T.TargetSou'+ 'rceFileName])'#010+ ' else'#010+ ' begi','n'#010+ ' Log(vlWarning,SWarnSourceFileNotFound,[T.SourceFileName,MakeTa'+ 'rgetString(ACPU,AOS)]);'#010+ ' T.FTargetSourceFileName:='#039#039';'#010+ ' end;'#010+ ' end;'#010+ #010+ 'var'#010+ ' T : TTarget;'#010+ ' i : Integer;'#010+ 'begin'#010+ ' if not((ACPU in APackage.CPUs) and (AOS in APa','ckage.OSes)) then'#010+ ' exit;'#010+ ' try'#010+ ' if DoChangeDir and (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APackage.Directory);'#010+ ' Dictionary.AddVariable('#039'CPU'#039',CPUToString(ACPU));'#010+ ' Dictionary.AddVariable('#039'OS'#039',OSToString(AOS));'#010+ ' For I:=0 t','o APackage.Targets.Count-1 do'#010+ ' begin'#010+ ' T:=APackage.FTargets.TargetItems[I];'#010+ ' if (ACPU in T.CPUs) and (AOS in T.OSes) then'#010+ ' begin'#010+ ' // Debug information'#010+ ' Log(vlDebug,SDbgResolvingSourcesOfTarge','t,[T.Name,MakeTar'+ 'getString(ACPU,AOS)]);'#010+ ' LogIndent;'#010+ #010+ ' case T.TargetType of'#010+ ' ttProgram,'#010+ ' ttUnit,'#010+ ' ttImplicitUnit :'#010+ ' begin'#010+ ' FindMainSource(T);'#010+ ' ',' if T.Dependencies.Count>0 then'#010+ ' FindIncludeSources(T);'#010+ ' end;'#010+ ' ttExampleUnit,'#010+ ' ttExampleProgram :'#010+ ' begin'#010+ ' FindExampleSource(T);'#010+ ' ',' end;'#010+ ' end;'#010+ #010+ ' LogUnIndent;'#010+ ' end;'#010+ ' end;'#010+ ' finally'#010+ ' If DoChangeDir and (APackage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'function TBuildEngine.GetUnitDir(APackage:TPackage):String;'#010+ 'be','gin'#010+ ' // Retrieve Full directory name where to find the units.'#010+ ' // The search order is:'#010+ ' // - Package in this fpmake.pp'#010+ ' // - LocalUnitDir'#010+ ' // - GlobalUnitDir'#010+ ' if (APackage.UnitDir='#039#039') and'#010+ ' (APackage.State=tsCompiled) then'#010+ ' b','egin'#010+ ' APackage.UnitDir:=IncludeTrailingPathDelimiter(FStartDir)+Includ'+ 'eTrailingPathDelimiter(APackage.Directory)+APackage.GetUnitsOutputDir('+ 'Defaults.CPU,Defaults.OS);'#010+ ' end;'#010+ ' if (APackage.UnitDir='#039#039') and'#010+ ' (Defaults.LocalUnitDir<','>'#039#039') then'#010+ ' begin'#010+ ' APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.LocalUni'+ 'tDir)+APackage.Name;'#010+ ' if not SysDirectoryExists(APackage.UnitDir) then'#010+ ' APackage.UnitDir:='#039#039';'#010+ ' end;'#010+ ' if APackage.UnitDir='#039#039' then'#010+ ' b','egin'#010+ ' APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.GlobalUn'+ 'itDir)+APackage.Name;'#010+ ' if not SysDirectoryExists(APackage.UnitDir) then'#010+ ' APackage.UnitDir:=DirNotFound;'#010+ ' end;'#010+ ' // Special error marker to prevent sea','rches in case of error'#010+ ' if APackage.UnitDir=DirNotFound then'#010+ ' Result:='#039#039#010+ ' else'#010+ ' Result:=APackage.UnitDir;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.AddDependencyIncludePaths(L:TStrings;ATarget: T'+ 'Target);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' D : TDependency;'#010+ ' ','SD : String;'#010+ 'begin'#010+ ' For I:=0 to ATarget.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=ATarget.Dependencies[i];'#010+ ' if (D.DependencyType=depInclude) and'#010+ ' (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then'#010+ ' begin'#010+ ' ',' SD:=ExcludeTrailingPathDelimiter(ExtractFilePath(D.TargetF'+ 'ileName));'#010+ ' if SD<>'#039#039' then'#010+ ' L.Add(SD);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.AddDependencyUnitPaths(L:TStrings;APackage: TPa'+ 'ckage);'#010+ 'Var'#010+ ' I : Int','eger;'#010+ ' P : TPackage;'#010+ ' D : TDependency;'#010+ ' S : String;'#010+ 'begin'#010+ ' For I:=0 to APackage.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=APackage.Dependencies[i];'#010+ ' if (D.DependencyType=depPackage) and'#010+ ' (Defaults.CPU in D.CPUs) and (Defau','lts.OS in D.OSes) then'#010+ ' begin'#010+ ' P:=TPackage(D.Target);'#010+ ' If Assigned(P) then'#010+ ' begin'#010+ ' // Already processed?'#010+ ' S:=GetUnitDir(P);'#010+ ' if L.IndexOf(S)=-1 then'#010+ ' ','begin'#010+ ' // Add this package and then dependencies'#010+ ' L.Add(S);'#010+ ' AddDependencyUnitPaths(L,P);'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.GetCompile','rCommand(APackage : TPackage; ATarge'+ 't : TTarget) : String;'#010+ 'Var'#010+ ' L,Args : TStringList;'#010+ ' i : Integer;'#010+ 'begin'#010+ ' Args:=TStringList.Create;'#010+ ' Args.Duplicates:=dupIgnore;'#010+ #010+ ' Result := '#039#039';'#010+ #010+ ' //compiler configuration'#010+ ' if Defaults.NoFPCCfg then'#010+ ' ',' Args.Add('#039'-n'#039');'#010+ #010+ ' // Target OS'#010+ ' Args.Add('#039'-T'#039'+OSToString(Defaults.OS));'#010+ #010+ ' // Compile mode'#010+ ' If ATarget.Mode<>cmFPC then'#010+ ' Args.Add('#039'-M'#039'+ModeToString(ATarget.Mode))'#010+ ' else If Defaults.Mode<>cmFPC then'#010+ ' Args.Add('#039'-M'#039'+ModeToString(D','efaults.Mode));'#010+ ' // Output file paths'#010+ ' If ATarget.TargetType in ProgramTargets then'#010+ ' Args.Add('#039'-FE'#039'+APackage.GetBinOutputDir(Defaults.CPU,Defau'+ 'lts.OS));'#010+ ' Args.Add('#039'-FU'#039'+APackage.GetUnitsOutputDir(Defaults.CPU,Defau'+ 'lts.OS));'#010+ ' // Objec','t Path'#010+ ' L:=TStringList.Create;'#010+ ' L.Sorted:=true;'#010+ ' L.Duplicates:=dupIgnore;'#010+ ' AddConditionalStrings(L,APackage.ObjectPath,Defaults.CPU,Defaults.OS'+ ');'#010+ ' AddConditionalStrings(L,ATarget.ObjectPath,Defaults.CPU,Defaults.OS)'+ ';'#010+ ' for i:=0 to L.Co','unt-1 do'#010+ ' Args.Add('#039'-Fo'#039'+L[i]);'#010+ ' FreeAndNil(L);'#010+ ' // Unit Dirs'#010+ ' L:=TStringList.Create;'#010+ ' L.Sorted:=true;'#010+ ' L.Duplicates:=dupIgnore;'#010+ ' AddDependencyUnitPaths(L,APackage);'#010+ ' AddConditionalStrings(L,APackage.UnitPath,Defaults.CPU,Defaults','.OS'+ ');'#010+ ' AddConditionalStrings(L,ATarget.UnitPath,Defaults.CPU,Defaults.OS);'#010+ ' for i:=0 to L.Count-1 do'#010+ ' Args.Add('#039'-Fu'#039'+L[i]);'#010+ ' FreeAndNil(L);'#010+ ' // Include Path'#010+ ' L:=TStringList.Create;'#010+ ' L.Sorted:=true;'#010+ ' L.Duplicates:=dupIgnore;'#010+ ' AddD','ependencyIncludePaths(L,ATarget);'#010+ ' AddConditionalStrings(L,APackage.IncludePath,Defaults.CPU,Defaults.O'+ 'S);'#010+ ' AddConditionalStrings(L,ATarget.IncludePath,Defaults.CPU,Defaults.OS'+ ');'#010+ ' for i:=0 to L.Count-1 do'#010+ ' Args.Add('#039'-Fi'#039'+L[i]);'#010+ ' Free','AndNil(L);'#010+ ' // Custom Options'#010+ ' If (Defaults.Options<>'#039#039') then'#010+ ' Args.Add(Defaults.Options);'#010+ ' If (APackage.Options<>'#039#039') then'#010+ ' Args.Add(APackage.Options);'#010+ ' If (ATarget.Options<>'#039#039') then'#010+ ' Args.Add(ATarget.Options);'#010+ ' // Add Filenam','e to compile'#010+ ' Args.Add(ATarget.TargetSourceFileName);'#010+ ' // Convert to string'#010+ ' Result:='#039#039';'#010+ ' for i:=0 to Args.Count-1 do'#010+ ' Result:=Result+'#039' '#039'+maybequoted(Args[i]);'#010+ ' Delete(result,1,1);'#010+ ' Args.Free;'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.GetCompil','er : String;'#010+ 'Var'#010+ ' S : String;'#010+ 'begin'#010+ ' // Cache in FCompiler for speed.'#010+ ' If (FCompiler='#039#039') then'#010+ ' begin'#010+ ' FCompiler:=Defaults.Compiler;'#010+ ' If (ExtractFilePath(FCompiler)='#039#039') then'#010+ ' begin'#010+ ' S:=ExeSearch(FCompiler,GetEnvironmen','tVariable('#039'PATH'#039')'+ ');'#010+ ' If (S<>'#039#039') then'#010+ ' FCompiler:=S;'#010+ ' end;'#010+ ' end;'#010+ ' Result:=FCompiler;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CreateOutputDir(APackage: TPackage);'#010+ 'Var'#010+ ' D : String;'#010+ ' i: integer;'#010+ 'begin'#010+ ' //create a units directory'#010, ' D:=APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);'#010+ ' If not SysDirectoryExists(D) then'#010+ ' begin'#010+ ' Log(vlInfo,SInfoCreatingOutputDir,[D]);'#010+ ' CmdCreateDir(D);'#010+ ' end;'#010+ #010+ ' //also create a bin directory for programtargets'#010+ ' For',' i := 0 to Pred(APackage.Targets.Count) do'#010+ ' begin'#010+ ' if APackage.Targets.TargetItems[i].TargetType in ProgramTargets '+ 'then'#010+ ' begin'#010+ ' D:=APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS);'#010+ ' If not SysDirectoryExis','ts(D) then'#010+ ' begin'#010+ ' Log(vlInfo,SInfoCreatingOutputDir,[D]);'#010+ ' CmdCreateDir(D);'#010+ ' end;'#010+ ' //do not continue loop, directory is made anyway'#010+ ' break;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Func','tion TBuildEngine.DependencyOK(ADependency : TDependency) : Bool'+ 'ean;'#010+ 'begin'#010+ ' Result:=(Defaults.CPU in ADependency.CPUs) and (Defaults.OS in ADepe'+ 'ndency.OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.TargetOK(ATarget : TTarget) : Boolean;'#010+ 'begin'#010+ ' Resul','t:=(Defaults.CPU in ATarget.CPUs) and (Defaults.OS in ATarget'+ '.OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.PackageOK(APackage : TPackage) : Boolean;'#010+ 'begin'#010+ ' Result:=(Defaults.CPU in APackage.CPUs) and (Defaults.OS in APackage'+ '.OSes);'#010+ 'end;'#010+ #010+ #010+ 'procedure',' TBuildEngine.DoBeforeCompile(APackage: TPackage);'#010+ 'begin'#010+ ' ExecuteCommands(APackage.Commands,caBeforeCompile);'#010+ ' If Assigned(APackage.BeforeCompile) then'#010+ ' APackage.BeforeCompile(APackage);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoAfterCompile(APa','ckage: TPackage);'#010+ 'begin'#010+ ' If Assigned(APackage.AfterCompile) then'#010+ ' APackage.AfterCompile(APackage);'#010+ ' ExecuteCommands(APackage.Commands,caAfterCompile);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.NeedsCompile(APackage:TPackage;ATarget: TTarget)'+ ': Boole','an;'#010+ 'Var'#010+ ' I : Integer;'#010+ ' D : TDependency;'#010+ ' T : TTarget;'#010+ ' OD,OFN : String;'#010+ 'begin'#010+ ' Result:=False;'#010+ #010+ ' // Forced recompile?'#010+ ' if FForceCompile then'#010+ ' Result:=true;'#010+ #010+ ' // Check output file'#010+ ' if not result then'#010+ ' begin'#010+ ' if ATarget.Tar','getType in ProgramTargets then'#010+ ' OD:=APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS)'#010+ ' else'#010+ ' OD:=APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS);'#010+ ' If (OD<>'#039#039') then'#010+ ' OD:=IncludeTrailingPathDelimiter(OD);'#010, ' OFN:=OD+ATarget.GetOutPutFileName(Defaults.OS);'#010+ ' Result:=Not FileExists(OFN);'#010+ ' if Result then'#010+ ' Log(vlDebug,SDbgOutputNotYetAvailable,[OFN]);'#010+ ' end;'#010+ #010+ ' // Check main source'#010+ ' If not Result then'#010+ ' begin'#010+ ' if Fil','eExists(ATarget.TargetSourceFileName) then'#010+ ' Result:=FileNewer(ATarget.TargetSourceFileName,OFN)'#010+ ' end;'#010+ #010+ ' // Check unit and include dependencies'#010+ ' If not Result then'#010+ ' begin'#010+ ' ResolveDependencies(ATarget.Dependencies,ATarget.','Collection as'+ ' TTargets);'#010+ ' I:=0;'#010+ ' for i:=0 to ATarget.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=ATarget.Dependencies[i];'#010+ ' if (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then'+ #010+ ' begin'#010+ ' ',' case D.DependencyType of'#010+ ' depUnit :'#010+ ' begin'#010+ ' T:=TTarget(D.Target);'#010+ ' If (T=Nil) then'#010+ ' Error(SErrDepUnknownTarget,[ATarget.Name,D.Value'+ ']);'#010+ ' ',' // If a dependent package is compiled we always '+ 'need to recompile'#010+ ' Log(vldebug, SDbgDependencyOnUnit, [ATarget.Name,T'+ '.Name]);'#010+ ' Result:=(T.State=tsCompiled);'#010+ ' if Result then'#010+ ' ',' Log(vldebug, SDbgDependencyUnitRecompiled, [T.'+ 'Name]);'#010+ ' end;'#010+ ' depInclude :'#010+ ' begin'#010+ ' if D.TargetFileName<>'#039#039' then'#010+ ' Result:=FileNewer(','D.TargetFileName,OFN)'#010+ ' end;'#010+ ' end;'#010+ ' if result then'#010+ ' break;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ #010+ ' if result then'#010+ ' Log(vlDebug,SDbgMustCompile,[ATarget.Name]);'#010+ 'end;'#010+ #010+ #010+ 'procedure T','BuildEngine.Compile(APackage: TPackage; ATarget: TTarget)'+ ';'#010+ 'Var'#010+ ' S : String;'#010+ 'begin'#010+ ' Log(vlInfo,SInfoCompilingTarget,[ATarget.Name]);'#010+ ' LogIndent;'#010+ ' ExecuteCommands(ATarget.Commands,caBeforeCompile);'#010+ ' If Assigned(ATarget.BeforeCompile) the','n'#010+ ' ATarget.BeforeCompile(ATarget);'#010+ ' S:=GetCompilerCommand(APackage,ATarget);'#010+ ' ExecuteCommand(GetCompiler,S);'#010+ ' If Assigned(ATarget.AfterCompile) then'#010+ ' ATarget.AfterCompile(ATarget);'#010+ ' ExecuteCommands(ATarget.Commands,caAfterCompile)',';'#010+ ' LogUnIndent;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CompileDependencies(APackage:TPackage; ATarget:'+ ' TTarget);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' T : TTarget;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' Log(vlDebug, Format(SDbgCompilingDependenciesOfTarget, [ATarget.Name'+ ']));'#010+ ' ',' LogIndent;'#010+ ' For I:=0 to ATarget.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=ATarget.Dependencies[i];'#010+ ' if (D.DependencyType=depUnit) and'#010+ ' (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then'#010+ ' begin'#010+ ' T:=TTar','get(D.Target);'#010+ ' if Assigned(T) and (T<>ATarget) then'#010+ ' begin'#010+ ' if TargetOK(T) then'#010+ ' begin'#010+ ' // We don'#039't need to compile implicit units, they'+ ' are only'#010+ ' // used fo','r dependency checking'#010+ ' if (T.TargetType<>ttImplicitUnit) then'#010+ ' begin'#010+ ' case T.State of'#010+ ' tsNeutral :'#010+ ' MaybeCompile(APackage,T);'#010+ ' ',' tsConsidering :'#010+ ' Log(vlWarning,SWarnCircularTargetDependency,'+ '[ATarget.Name,T.Name]);'#010+ ' end;'#010+ ' end;'#010+ ' end'#010+ ' else'#010+ ' Log(vlWa','rning, Format(SWarnDepUnitNotFound, [T.Name,'+ ' MakeTargetString(Defaults.CPU,Defaults.OS)]));'#010+ ' end'#010+ ' else'#010+ ' Error(SErrDepUnknownTarget,[ATarget.Name,D.Value]);'#010+ ' end;'#010+ ' end;'#010+ ' LogUnIndent;'#010+ 'end;'#010+ #010+ #010+ 'procedure',' TBuildEngine.MaybeCompile(APackage: TPackage; ATarget: TTa'+ 'rget);'#010+ 'begin'#010+ ' if ATarget.State<>tsNeutral then'#010+ ' Error(SErrInvalidState,[ATarget.Name]);'#010+ ' Log(vlDebug, Format(SDbgConsideringTarget, [ATarget.Name]));'#010+ ' LogIndent;'#010+ ' ATarget.FTa','rgetState:=tsConsidering;'#010+ ' ResolveDependencies(ATarget.Dependencies,ATarget.Collection as TTarg'+ 'ets);'#010+ ' CompileDependencies(APackage, ATarget);'#010+ ' if NeedsCompile(APackage, ATarget) then'#010+ ' begin'#010+ ' Compile(APackage,ATarget);'#010+ ' ATarg','et.FTargetState:=tsCompiled;'#010+ ' end'#010+ ' else'#010+ ' ATarget.FTargetState:=tsNoCompile;'#010+ ' LogUnIndent;'#010+ 'end;'#010+ #010+ #010+ 'function TBuildEngine.NeedsCompile(APackage: TPackage): Boolean;'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' Result:=','False;'#010+ #010+ ' // Forced recompile?'#010+ ' if FForceCompile then'#010+ ' Result:=true;'#010+ #010+ ' // Recompile because of Package Dependencies?'#010+ ' if not Result then'#010+ ' begin'#010+ ' I:=0;'#010+ ' For I:=0 to APackage.Dependencies.Count-1 do'#010+ ' begin'#010+ ' ',' D:=APackage.Dependencies[i];'#010+ ' if (D.DependencyType=depPackage) and'#010+ ' (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) the'+ 'n'#010+ ' begin'#010+ ' P:=TPackage(D.Target);'#010+ ' if Assigned(P) ','then'#010+ ' begin'#010+ ' Result:=(P.State=tsCompiled);'#010+ ' if Result then'#010+ ' break;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ ' end;'#010+ #010+ ' // Recompile a Target of this packa','ge?'#010+ ' If Not Result then'#010+ ' begin'#010+ ' try'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APackage.Directory);'#010+ ' for i:=0 to APackage.Targets.Count-1 do'#010+ ' begin'#010+ ' Result:=NeedsCompile(APackage,APackage','.Targets.TargetIte'+ 'ms[i]);'#010+ ' if Result then'#010+ ' break;'#010+ ' end;'#010+ ' Finally'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end;'#010+ ' end;'#010+ #010+ ' if result then'#010+ ' Log(vlDebug,SDbgMustCompile,[A','Package.Name]);'#010+ 'end;'#010+ #010+ #010+ 'function TBuildEngine.CheckExternalPackage(Const APackageName : String'+ '):TPackage;'#010+ 'var'#010+ ' S : String;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' // Already checked?'#010+ ' I:=ExternalPackages.IndexOfName(APackageName);'#010+ ' if I<>-1 then'#010+ ' begin',#010+ ' result:=ExternalPackages.PackageItems[I];'#010+ ' exit;'#010+ ' end;'#010+ ' // Create new external package'#010+ ' Result:=ExternalPackages.AddPackage(APackageName);'#010+ ' Result.FTargetState:=tsNotFound;'#010+ ' // Load unit config'#010+ ' S:=GetUnitDir(Result);'#010+ ' ','if S<>'#039#039' then'#010+ ' begin'#010+ ' Log(vldebug, SDbgExternalDependency, [APackageName,S]);'#010+ ' Result.FTargetState:=tsInstalled;'#010+ ' // Load unit config if it exists'#010+ ' S:=IncludeTrailingPathDelimiter(S)+UnitConfigFile;'#010+ ' if FileExist','s(S) then'#010+ ' begin'#010+ ' Log(vlDebug, Format(SDbgLoading, [S]));'#010+ ' Result.LoadUnitConfigFromFile(S);'#010+ ' end;'#010+ ' // Check recursive implicit dependencies'#010+ ' CompileDependencies(Result);'#010+ ' end'#010+ ' else'#010+ ' Error(SE','rrDependencyNotFound,[APackageName]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.CompileDependencies(APackage: TPackage);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' For I:=0 to APackage.Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=APack','age.Dependencies[i];'#010+ ' if (D.DependencyType=depPackage) and'#010+ ' (Defaults.CPU in D.CPUs) and (Defaults.OS in D.OSes) then'#010+ ' begin'#010+ ' P:=TPackage(D.Target);'#010+ ' If Assigned(P) then'#010+ ' begin'#010+ ' ','case P.State of'#010+ ' tsNeutral :'#010+ ' MaybeCompile(P);'#010+ ' tsConsidering :'#010+ ' Log(vlWarning,SWarnCircularPackageDependency,[APacka'+ 'ge.Name,P.Name]);'#010+ ' end;'#010+ ' end'#010+ ' ',' else'#010+ ' begin'#010+ ' D.Target:=CheckExternalPackage(D.Value);'#010+ ' P:=TPackage(D.Target);'#010+ ' end;'#010+ ' if (D.RequireChecksum<>$ffffffff) and'#010+ ' (P.InstalledChecksum<>$ffffffff) and'#010+ ' ',' (P.InstalledChecksum<>D.RequireChecksum) then'#010+ ' Log(vlDebug,SDbgPackageChecksumChanged,[P.Name]);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Compile(APackage: TPackage);'#010+ 'Var'#010+ ' T : TTarget;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' Tr','y'#010+ ' Log(vlInfo,SInfoCompilingPackage,[APackage.Name]);'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APackage.Directory);'#010+ ' CreateOutputDir(APackage);'#010+ ' Dictionary.AddVariable('#039'UNITSOUTPUTDIR'#039',APackage.GetUnitsO'+ 'utputDir(Defaults','.CPU,Defaults.OS));'#010+ ' Dictionary.AddVariable('#039'BINOUTPUTDIR'#039',APackage.GetBinOutpu'+ 'tDir(Defaults.CPU,Defaults.OS));'#010+ ' DoBeforeCompile(APackage);'#010+ ' For I:=0 to APackage.Targets.Count-1 do'#010+ ' begin'#010+ ' T:=APackage.Targets.TargetItem','s[i];'#010+ ' if (T.TargetType in [ttUnit,ttProgram]) then'#010+ ' begin'#010+ ' if TargetOK(T) then'#010+ ' begin'#010+ ' if T.State=tsNeutral then'#010+ ' MaybeCompile(APackage,T);'#010+ ' end'#010+ ' ',' else'#010+ ' begin'#010+ ' if not(Defaults.CPU in T.CPUs) then'#010+ ' Log(vldebug, Format(SDbgSkippingTargetWrongCPU, [T.N'+ 'ame, CPUsToString(T.CPUs)]));'#010+ ' if not(Defaults.OS in T.OSes) then'#010+ ' ',' Log(vldebug, Format(SDbgSkippingTargetWrongOS, [T.'+ 'Name, OSesToString(T.OSes)]));'#010+ ' end;'#010+ ' end'#010+ ' else'#010+ ' log(vldebug, SDbgTargetIsNotAUnitOrProgram,[T.Name]);'#010+ ' end;'#010+ ' DoAfterCompile(APackage);',#010+ ' Finally'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.MaybeCompile(APackage: TPackage);'#010+ 'begin'#010+ ' if APackage.State<>tsNeutral then'#010+ ' Error(SErrInvalidState,[APackage.Name]);'#010+ ' Log(vlDebug,','SDbgConsideringPackage,[APackage.Name]);'#010+ ' LogIndent;'#010+ ' APackage.FTargetState:=tsConsidering;'#010+ ' ResolveDependencies(APackage.Dependencies,(APackage.Collection as TP'+ 'ackages));'#010+ ' CompileDependencies(APackage);'#010+ ' ResolveFileNames(APackage,Defa','ults.CPU,Defaults.OS);'#010+ ' If NeedsCompile(APackage) then'#010+ ' begin'#010+ ' Compile(APackage);'#010+ ' APackage.FTargetState:=tsCompiled;'#010+ ' end'#010+ ' else'#010+ ' APackage.FTargetState:=tsNoCompile;'#010+ ' LogUnIndent;'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.InstallPa','ckageFiles(APAckage : TPackage; tt : '+ 'TTargetType; Const Dest : String):Boolean;'#010+ 'Var'#010+ ' List : TStringList;'#010+ 'begin'#010+ ' Result:=False;'#010+ ' List:=TStringList.Create;'#010+ ' Try'#010+ ' APackage.GetInstallFiles(List,[tt],Defaults.CPU, Defaults.OS);'#010+ ' if (Li','st.Count>0) then'#010+ ' begin'#010+ ' Result:=True;'#010+ ' CmdCopyFiles(List,Dest);'#010+ ' end;'#010+ ' Finally'#010+ ' List.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoBeforeInstall(APackage: TPackage);'#010+ 'begin'#010+ ' ExecuteCommands(APackage.Commands,caBe','foreInstall);'#010+ ' If Assigned(APackage.BeforeInstall) then'#010+ ' APackage.BeforeInstall(APackage);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoAfterInstall(APackage: TPackage);'#010+ 'begin'#010+ ' If Assigned(APackage.AfterInstall) then'#010+ ' APackage.AfterInstall(APack','age);'#010+ ' ExecuteCommands(APackage.Commands,caAfterInstall);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Install(APackage: TPackage);'#010+ 'Var'#010+ ' UC,D : String;'#010+ ' B : Boolean;'#010+ 'begin'#010+ ' If (Apackage.State<>tsCompiled) then'#010+ ' MaybeCompile(APackage);'#010+ ' try'#010+ ' Log','(vlInfo,SInfoInstallingPackage,[APackage.Name]);'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APackage.Directory);'#010+ ' DoBeforeInstall(APackage);'#010+ ' // units'#010+ ' B:=false;'#010+ ' D:=IncludeTrailingPathDelimiter(Defaults.UnitInstallDir)','+APackag'+ 'e.Name;'#010+ ' if InstallPackageFiles(APAckage,ttUnit,D) then'#010+ ' B:=true;'#010+ ' if InstallPackageFiles(APAckage,ttImplicitUnit,D) then'#010+ ' B:=true;'#010+ ' // Unit (dependency) configuration if there were units installed'#010+ ' if B then'#010+ ' ',' begin'#010+ ' UC:=IncludeTrailingPathDelimiter(D)+UnitConfigFile;'#010+ ' Log(vlInfo, Format(SDbgGenerating, [UC]));'#010+ ' APackage.SaveUnitConfigToFile(UC,Defaults.CPU,Defaults.OS);'#010+ ' end;'#010+ ' // Programs'#010+ ' D:=IncludeTrailingP','athDelimiter(Defaults.BinInstallDir);'#010+ ' InstallPackageFiles(APAckage,ttProgram,D);'#010+ ' // Done.'#010+ ' APackage.FTargetState:=tsInstalled;'#010+ ' DoAfterInstall(APackage);'#010+ ' Finally'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end',';'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoBeforeArchive(APackage: TPackage);'#010+ 'begin'#010+ ' ExecuteCommands(APackage.Commands,caBeforeArchive);'#010+ ' If Assigned(APackage.BeforeArchive) then'#010+ ' APackage.BeforeArchive(APackage);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.','DoAfterArchive(APackage: TPackage);'#010+ 'begin'#010+ ' If Assigned(APackage.AfterArchive) then'#010+ ' APackage.AfterArchive(APackage);'#010+ ' ExecuteCommands(APackage.Commands,caAfterArchive);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Archive(APackage: TPackage);'#010+ 'Var'#010+ ' L',' : TStringList;'#010+ ' A : String;'#010+ ' i: integer;'#010+ ' ICPU : TCPU;'#010+ ' IOS : TOS;'#010+ 'begin'#010+ ' A:=FStartDir+ APackage.FileName + ZipExt;'#010+ ' Log(vlInfo,SInfoArchivingPackage,[APackage.Name,A]);'#010+ ' try'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APac','kage.Directory);'#010+ ' DoBeforeArchive(Apackage);'#010+ ' L:=TStringList.Create;'#010+ ' L.Sorted:=true;'#010+ ' L.Duplicates:=dupIgnore;'#010+ ' Try'#010+ ' // Add fpmake.pp & manifest.xml always'#010+ ' L.Add(FPMakePPFile);'#010+ ' L.Add(ManifestFile);'#010+ ' //g','et all files from all targets'#010+ ' for ICPU:=Low(TCPU) to high(TCPU) do'#010+ ' for IOS:=Low(TOS) to high(TOS) do'#010+ ' if OSCPUSupported[IOS,ICPU] then'#010+ ' begin'#010+ ' ResolveFileNames(APackage,ICPU,IOS,false);'#010+ ' ',' APackage.GetArchiveFiles(L, ICPU, IOS);'#010+ ' end;'#010+ ' //from sources'#010+ ' for i := 0 to APackage.Sources.Count-1 do'#010+ ' L.Add(APackage.Sources[i].Name);'#010+ #010+ ' //show all files'#010+ ' for i := 0 to L.Count-1 do'#010+ ' L','og(vlDebug, Format(SDbgArchivingFile, [L[i]]));'#010+ #010+ '{$ifdef HAS_UNIT_ZIPPER}'#010+ ' if not Assigned(ArchiveFilesProc) then'#010+ ' begin'#010+ ' FZipFile := TZipper.Create;'#010+ ' FZipFile.ZipFiles(A, L);'#010+ ' end'#010+ ' else'#010+ '{$endif HAS','_UNIT_ZIPPER}'#010+ ' CmdArchiveFiles(L,A);'#010+ ' Finally'#010+ ' L.Free;'#010+ #010+ '{$ifdef HAS_UNIT_ZIPPER}'#010+ ' if not Assigned(ArchiveFilesProc) then'#010+ ' FreeAndNil(FZipFile);'#010+ '{$endif HAS_UNIT_ZIPPER}'#010+ ' end;'#010+ ' DoAfterArchive(Apackage);'#010+ ' Fin','ally'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoBeforeClean(APackage: TPackage);'#010+ 'begin'#010+ ' ExecuteCommands(APackage.Commands,caBeforeClean);'#010+ ' If Assigned(APackage.BeforeClean) then'#010+ ' APa','ckage.BeforeClean(APackage);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.DoAfterClean(APackage: TPackage);'#010+ 'begin'#010+ ' If Assigned(APackage.AfterClean) then'#010+ ' APackage.AfterClean(APackage);'#010+ ' ExecuteCommands(APackage.Commands,caAfterClean);'#010+ 'end;'#010+ #010+ #010+ 'procedur','e TBuildEngine.Clean(APackage: TPackage);'#010+ 'Var'#010+ ' List : TStringList;'#010+ 'begin'#010+ ' Log(vlInfo,SInfoCleaningPackage,[APackage.Name]);'#010+ ' try'#010+ ' If (APackage.Directory<>'#039#039') then'#010+ ' EnterDir(APackage.Directory);'#010+ ' DoBeforeClean(Apackage);'#010+ ' Li','st:=TStringList.Create;'#010+ ' try'#010+ ' APackage.GetCleanFiles(List,Defaults.CPU,Defaults.OS);'#010+ ' if (List.Count>0) then'#010+ ' CmdDeleteFiles(List);'#010+ ' Finally'#010+ ' List.Free;'#010+ ' end;'#010+ ' DoAfterClean(Apackage);'#010+ ' Finally'#010+ ' If (APac','kage.Directory<>'#039#039') then'#010+ ' EnterDir('#039#039');'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Procedure TBuildEngine.Manifest(APackage : TPackage);'#010+ 'Var'#010+ ' L : TStrings;'#010+ ' PD,'#010+ ' MF : String;'#010+ 'begin'#010+ ' L:=TStringList.Create;'#010+ ' Try'#010+ ' Log(vlInfo, Format(SInfoManifestPackage,[APac','kage.Name]));'#010+ ' PD:=APackage.Directory;'#010+ ' if PD<>'#039#039' then'#010+ ' PD:=IncludeTrailingPathDelimiter(PD);'#010+ ' MF:=PD+ManifestFile;'#010+ ' Log(vlDebug, Format(SDbgGenerating, [MF]));'#010+ ' L.Add('#039''#039');'#010+ ' L.Add('#039''#039');'#010+ ' ',' APackage.GetManifest(L);'#010+ ' L.Add('#039''#039');'#010+ ' L.SaveToFile(MF);'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Compile(Packages: TPackages);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ 'begin'#010+ ' If Assigned(BeforeCompile) then'#010, ' BeforeCompile(Self);'#010+ ' For I:=0 to Packages.Count-1 do'#010+ ' begin'#010+ ' P:=Packages.PackageItems[i];'#010+ ' If PackageOK(P) then'#010+ ' MaybeCompile(P);'#010+ ' end;'#010+ ' If Assigned(AfterCompile) then'#010+ ' AfterCompile(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure T','BuildEngine.Install(Packages: TPackages);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ 'begin'#010+ ' If Assigned(BeforeInstall) then'#010+ ' BeforeInstall(Self);'#010+ ' For I:=0 to Packages.Count-1 do'#010+ ' begin'#010+ ' P:=Packages.PackageItems[i];'#010+ ' If PackageOK(','P) then'#010+ ' Install(P);'#010+ ' end;'#010+ ' If Assigned(AfterInstall) then'#010+ ' AfterInstall(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Archive(Packages: TPackages);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ 'begin'#010+ ' If Assigned(BeforeArchive) then'#010+ ' BeforeA','rchive(Self);'#010+ ' Log(vlDebug, SDbgBuildEngineArchiving);'#010+ ' For I:=0 to Packages.Count-1 do'#010+ ' begin'#010+ ' P:=Packages.PackageItems[i];'#010+ ' Archive(P);'#010+ ' end;'#010+ ' If Assigned(AfterArchive) then'#010+ ' AfterArchive(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBui','ldEngine.Manifest(Packages: TPackages);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ 'begin'#010+ ' If Assigned(BeforeManifest) then'#010+ ' BeforeManifest(Self);'#010+ ' Log(vlDebug, SDbgBuildEngineGenerateManifests);'#010+ ' For I:=0 to Packages.Count-1 do'#010+ ' begin'#010+ ' ',' P:=Packages.PackageItems[i];'#010+ ' Manifest(P);'#010+ ' end;'#010+ ' If Assigned(AfterManifest) then'#010+ ' AfterManifest(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.Clean(Packages: TPackages);'#010+ 'Var'#010+ ' I : Integer;'#010+ ' P : TPackage;'#010+ 'begin'#010+ ' If Assigned(BeforeCle','an) then'#010+ ' BeforeClean(Self);'#010+ ' Log(vldebug, SDbgBuildEngineCleaning);'#010+ ' For I:=0 to Packages.Count-1 do'#010+ ' begin'#010+ ' P:=Packages.PackageItems[i];'#010+ ' If PackageOK(P) then'#010+ ' Clean(P);'#010+ ' end;'#010+ ' If Assigned(AfterClean) then'#010+ ' After','Clean(Self);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TFPVersion'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TFPVersion.G','etAsString: String;'#010+ 'begin'#010+ ' if Empty then'#010+ ' Result:='#039''#039#010+ ' else'#010+ ' Result:=Format('#039'%d.%d.%d-%d'#039',[Major,Minor,Micro,Build]);'#010+ 'end;'#010+ #010+ 'function TFPVersion.GetEmpty: Boolean;'#010+ 'begin'#010+ ' Result:=(Major=0) and (Minor=0) and (Micro=0) and (Build','=0);'#010+ 'end;'#010+ #010+ 'procedure TFPVersion.SetAsString(const AValue: String);'#010+ #010+ ' Function NextDigit(sep : Char; var V : string) : integer;'#010+ #010+ ' Var'#010+ ' P : Integer;'#010+ #010+ ' begin'#010+ ' P:=Pos(Sep,V);'#010+ ' If (P=0) then'#010+ ' P:=Length(V)+1;'#010+ ' Result:=StrToInt','Def(Copy(V,1,P-1),-1);'#010+ ' If Result<>-1 then'#010+ ' Delete(V,1,P)'#010+ ' else'#010+ ' Result:=0;'#010+ ' end;'#010+ #010+ 'Var'#010+ ' V : String;'#010+ 'begin'#010+ ' Clear;'#010+ ' // Special support for empty version string'#010+ ' if (AValue='#039#039') or (AValue='#039''#039') then'#010+ ' exit;'#010+ ' V:=AVa','lue;'#010+ ' Major:=NextDigit('#039'.'#039',V);'#010+ ' Minor:=NextDigit('#039'.'#039',V);'#010+ ' Micro:=NextDigit('#039'-'#039',V);'#010+ ' Build:=NextDigit(#0,V);'#010+ 'end;'#010+ #010+ 'procedure TFPVersion.Clear;'#010+ 'begin'#010+ ' Micro:=0;'#010+ ' Major:=0;'#010+ ' Minor:=0;'#010+ ' Build:=0;'#010+ 'end;'#010+ #010+ 'procedure TFPVersion.Assign(Source',': TPersistent);'#010+ #010+ 'Var'#010+ ' V : TFPVersion;'#010+ #010+ 'begin'#010+ ' if Source is TFPVersion then'#010+ ' begin'#010+ ' V:=Source as TFPVersion;'#010+ ' Major:=V.Major;'#010+ ' Minor:=V.Minor;'#010+ ' Micro:=V.Micro;'#010+ ' Build:=V.Build;'#010+ ' end'#010+ ' else'#010+ ' inherited Assign(Source);',#010+ 'end;'#010+ #010+ 'function TFPVersion.CompareVersion(AVersion: TFPVersion): Integer;'#010+ 'begin'#010+ ' Result:=Major-AVersion.Major;'#010+ ' If (Result=0) then'#010+ ' begin'#010+ ' Result:=Minor-AVersion.Minor;'#010+ ' if (Result=0) then'#010+ ' begin'#010+ ' Result:=Micr','o-AVersion.Micro;'#010+ ' If (Result=0) then'#010+ ' Result:=Build-AVersion.Build;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ 'function TFPVersion.SameVersion(AVersion: TFPVersion): Boolean;'#010+ 'begin'#010+ ' Result:=CompareVersion(AVersion)=0;'#010+ 'end;'#010+ #010+ #010+ '{*******','************************************************************'+ '*********'#010+ ' TTarget'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TTarget.Create(ACollection: TCollectio','n);'#010+ 'begin'#010+ ' inherited Create(ACollection);'#010+ ' FInstall:=True;'#010+ ' FCPUs:=AllCPUs;'#010+ ' FOSes:=AllOSes;'#010+ ' FUnitPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FIncludePath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FObjectPath:=TCo','nditionalStrings.Create(TConditionalString);'#010+ ' FDependencies:=TDependencies.Create(TDependency);'#010+ ' FCommands:=TCOmmands.Create(TCommand);'#010+ 'end;'#010+ #010+ #010+ 'destructor TTarget.Destroy;'#010+ 'begin'#010+ ' FreeAndNil(FUnitPath);'#010+ ' FreeAndNil(FObjectPath);'#010+ ' FreeAnd','Nil(FIncludePath);'#010+ ' FreeAndNil(FDependencies);'#010+ ' FreeAndNil(FCommands);'#010+ ' inherited Destroy;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetSourceFileName: String;'#010+ 'begin'#010+ ' Result:=Name+FExtension;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetUnitFileName: String;'#010+ 'begin'#010+ ' Resul','t:=Name+UnitExt;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetObjectFileName: String;'#010+ 'begin'#010+ ' Result:=Name+ObjExt;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetRSTFileName: String;'#010+ 'begin'#010+ ' Result:=Name+RSText;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetProgramFileName(AOS : TOS): String;'#010+ 'beg','in'#010+ ' if AOS in [Go32v2,Win32,Win64,OS2] then'#010+ ' Result:=Name+ExeExt'#010+ ' else'#010+ ' Result:=Name;'#010+ 'end;'#010+ #010+ #010+ 'function TTarget.GetOutputFileName(AOs: TOS): String;'#010+ 'begin'#010+ ' if TargetType in UnitTargets then'#010+ ' Result:=GetUnitFileName'#010+ ' else'#010+ ' Resu','lt:=GetProgramFileName(AOs);'#010+ 'end;'#010+ #010+ #010+ 'procedure TTarget.SetName(const AValue: String);'#010+ 'Var'#010+ ' D,N,E : String;'#010+ 'begin'#010+ ' N:=FixPath(AValue);'#010+ ' D:=ExtractFilePath(N);'#010+ ' E:=ExtractFileExt(N);'#010+ ' N:=ExtractFileName(N);'#010+ ' inherited SetName(Copy(N,1,Le','ngth(N)-Length(E)));'#010+ ' FExtension:=E;'#010+ ' FDirectory:=D;'#010+ 'end;'#010+ #010+ #010+ 'procedure TTarget.GetCleanFiles(List: TStrings; const APrefixU, APrefi'+ 'xB : String; ACPU: TCPU; AOS : TOS);'#010+ 'begin'#010+ ' If not(ACPU in CPUs) or not(AOS in OSes) then'#010+ ' exit;'#010+ ' List.','Add(APrefixU + ObjectFileName);'#010+ ' If (TargetType in [ttUnit,ttImplicitUnit,ttExampleUnit, ttCleanOnlyU'+ 'nit]) then'#010+ ' List.Add(APrefixU + UnitFileName)'#010+ ' else If (TargetType in [ttProgram,ttExampleProgram]) then'#010+ ' List.Add(APrefixB + GetPr','ogramFileName(AOS));'#010+ ' If ResourceStrings then'#010+ ' List.Add(APrefixU + RSTFileName);'#010+ ' // Maybe add later ? AddConditionalStrings(List,CleanFiles);'#010+ 'end;'#010+ #010+ #010+ 'procedure TTarget.GetInstallFiles(List: TStrings; const APrefixU, APre'+ 'fixB: String; ','ACPU: TCPU; AOS : TOS);'#010+ 'begin'#010+ ' If not(ACPU in CPUs) or not(AOS in OSes) then'#010+ ' exit;'#010+ ' If Not (TargetType in [ttProgram,ttExampleProgram]) then'#010+ ' List.Add(APrefixU + ObjectFileName);'#010+ ' If (TargetType in [ttUnit,ttImplicitUnit,ttExample','Unit]) then'#010+ ' List.Add(APrefixU + UnitFileName)'#010+ ' else If (TargetType in [ttProgram,ttExampleProgram]) then'#010+ ' List.Add(APrefixB + GetProgramFileName(AOS));'#010+ ' If ResourceStrings then'#010+ ' List.Add(APrefixU + RSTFileName);'#010+ ' // Maybe add l','ater ? AddConditionalStrings(List,InstallFiles);'#010+ 'end;'#010+ #010+ #010+ 'procedure TTarget.GetArchiveFiles(List: TStrings; ACPU: TCPU; AOS : TO'+ 'S);'#010+ 'var'#010+ ' i : integer;'#010+ ' D : TDependency;'#010+ 'begin'#010+ ' If not(ACPU in CPUs) or not(AOS in OSes) then'#010+ ' exit;'#010+ ' // Ma','in source'#010+ ' if TargetSourceFileName<>'#039#039' then'#010+ ' List.Add(TargetSourceFileName);'#010+ ' // Includes'#010+ ' for i:=0 to Dependencies.Count-1 do'#010+ ' begin'#010+ ' D:=Dependencies[i];'#010+ ' if (D.DependencyType=depInclude) and'#010+ ' (D.TargetFileName<>',#039#039') then'#010+ ' List.Add(D.TargetFileName);'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TSource'#010+ '************************************************************','********'+ '********}'#010+ #010+ 'constructor TSource.Create(ACollection: TCollection);'#010+ 'begin'#010+ ' inherited Create(ACollection);'#010+ 'end;'#010+ #010+ #010+ 'destructor TSource.Destroy;'#010+ 'begin'#010+ ' inherited Destroy;'#010+ 'end;'#010+ #010+ #010+ '{**********************************************************','*********'+ '*********'#010+ ' TCommands'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TCommands.GetCommand(const Dest : String): TCommand;'#010+ 'begin'#010+ ' Result:=TCommand(ItemByName(D','est));'#010+ 'end;'#010+ #010+ 'function TCommands.GetCommandItem(Index : Integer): TCommand;'#010+ 'begin'#010+ ' Result:=TCommand(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCommands.SetCommandItem(Index : Integer; const AValue: TCom'+ 'mand);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Func','tion TCommands.AddCommand(const Cmd: String) : TCommand;'#010+ 'begin'#010+ ' Result:=AddCommand(fdefaultAt,Cmd,'#039#039','#039#039','#039#039');'#010+ 'end;'#010+ #010+ #010+ 'function TCommands.AddCommand(const Cmd, Options: String): TCommand;'#010+ 'begin'#010+ ' Result:=AddCommand(fdefaultAt,Cmd,Options,'#039#039','#039,#039');'#010+ 'end;'#010+ #010+ #010+ 'function TCommands.AddCommand(const Cmd, Options, Dest, Source: String'+ ' ): TCommand;'#010+ 'begin'#010+ ' Result:=AddCommand(fdefaultAt,Cmd,options,Dest,Source);'#010+ 'end;'#010+ #010+ #010+ 'Function TCommands.AddCommand(At: TCommandAt; const Cmd: String) : TCo'+ 'mman','d;'#010+ 'begin'#010+ ' Result:=AddCommand(At,Cmd,'#039#039','#039#039','#039#039');'#010+ 'end;'#010+ #010+ #010+ 'function TCommands.AddCommand(At: TCommandAt; const Cmd, Options: Stri'+ 'ng ): TCommand;'#010+ 'begin'#010+ ' Result:=AddCommand(At,Cmd,Options,'#039#039','#039#039');'#010+ 'end;'#010+ #010+ #010+ 'function TCommands.AddCommand(At: TComman','dAt; const Cmd, Options, De'+ 'st, Source: String): TCommand;'#010+ 'begin'#010+ ' Result:=Add as TCommand;'#010+ ' Result.Command:=Cmd;'#010+ ' Result.Options:=Options;'#010+ ' Result.At:=At;'#010+ ' Result.SourceFile:=Source;'#010+ ' Result.DestFile:=Dest;'#010+ 'end;'#010+ #010+ #010+ '{********************','***********************************************'+ '*********'#010+ ' TConditionalString'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'Constructor TConditionalString.Create;'#010+ 'begin'#010+ ' inherited C','reate;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TConditionalStrings'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'Constructor TCondition','alStrings.Create(AClass:TConditionalStringClas'+ 's);'#010+ 'begin'#010+ ' inherited Create;'#010+ ' FCSClass:=AClass;'#010+ 'end;'#010+ #010+ #010+ 'function TConditionalStrings.GetConditionalString(Index : Integer): TC'+ 'onditionalString;'#010+ 'begin'#010+ ' Result:=TConditionalString(Items[Index]);',#010+ 'end;'#010+ #010+ #010+ 'procedure TConditionalStrings.SetConditionalString(Index : Integer; co'+ 'nst AValue: TConditionalString);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Function TConditionalStrings.Add(Const Value : String) : TConditionalS'+ 'tring;'#010+ 'begin'#010+ ' result:','=Add(Value,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TConditionalStrings.Add(Const Value : String;const CPUs:TCPUs'+ ') : TConditionalString;'#010+ 'begin'#010+ ' result:=Add(Value,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Functi','on TConditionalStrings.Add(Const Value : String;const OSes:TOS'+ 'es) : TConditionalString;'#010+ 'begin'#010+ ' result:=Add(Value,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TConditionalStrings.Add(Const Value : String;const CPUs:TCPUs'+ ';const OSes:TOSes) : TConditionalS','tring;'#010+ 'begin'#010+ ' Result:=FCSClass.Create;'#010+ ' Result.Value:=Value;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.CPUs:=CPUs;'#010+ ' inherited Add(Result);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' ',' TDependency'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'Constructor TDependency.Create;'#010+ 'begin'#010+ ' inherited Create;'#010+ ' FVersion:=TFPVersion.Create;'#010+ 'end;'#010+ #010+ #010+ 'Destructor TDependency.Destroy;'#010+ 'begin'#010+ ' FreeAn','dNil(FVersion);'#010+ 'end;'#010+ #010+ #010+ 'Function TDependency.GetVersion : string;'#010+ 'begin'#010+ ' result:=FVersion.AsString;'#010+ 'end;'#010+ #010+ #010+ 'Procedure TDependency.SetVersion(const V : string);'#010+ 'begin'#010+ ' FVersion.AsString:=V;'#010+ 'end;'#010+ #010+ #010+ '{*******************************************','************************'+ '*********'#010+ ' TDependencies'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TDependencies.GetDependency(Index : Integer): TDependency;'#010+ 'begin'#010+ ' Resul','t:=TDependency(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TDependencies.SetDependency(Index : Integer; const AValue: T'+ 'Dependency);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.Add(Const Value : String) : TDependency;'#010+ 'begin'#010+ ' result:=Add','(Value,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TDependencies.Add(Const Value : String;const CPUs:TCPUs) : TD'+ 'ependency;'#010+ 'begin'#010+ ' result:=Add(Value,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TDependencies.','Add(Const Value : String;const OSes:TOSes) : '+ 'TDependency;'#010+ 'begin'#010+ ' result:=Add(Value,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.Add(Const Value : String;const CPUs:TCPUs;const'+ ' OSes:TOSes) : TDependency;'#010+ 'begin'#010+ ' Result:=inherited Add(Value,','CPUs,OSes) as TDependency;'#010+ ' Result.Target:=nil;'#010+ ' Result.FDependencyType:=depPackage;'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.AddUnit(Const Value : String) : TDependency;'#010+ 'begin'#010+ ' result:=AddUnit(Value,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overlo','ads}'#010+ 'Function TDependencies.AddUnit(Const Value : String;const CPUs:TCPUs) '+ ': TDependency;'#010+ 'begin'#010+ ' result:=AddUnit(Value,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TDependencies.AddUnit(Const Value : String;const OSes:TOSes) ', ': TDependency;'#010+ 'begin'#010+ ' result:=AddUnit(Value,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.AddUnit(Const Value : String;const CPUs:TCPUs;c'+ 'onst OSes:TOSes) : TDependency;'#010+ 'begin'#010+ ' Result:=inherited Add(Value,CPUs,OSes) as TDependency;'#010+ ' Result','.Target:=nil;'#010+ ' Result.FDependencyType:=depUnit;'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.AddInclude(Const Value : String) : TDependency;'+ #010+ 'begin'#010+ ' result:=AddInclude(Value,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TDependencies.AddI','nclude(Const Value : String;const CPUs:TC'+ 'PUs) : TDependency;'#010+ 'begin'#010+ ' result:=AddInclude(Value,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TDependencies.AddInclude(Const Value : String;const OSes:TOSe'+ 's) : TDependency;'#010+ 'begin'#010+ ' ','result:=AddInclude(Value,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TDependencies.AddInclude(Const Value : String;const CPUs:TCPU'+ 's;const OSes:TOSes) : TDependency;'#010+ 'Var'#010+ ' N : String;'#010+ 'begin'#010+ ' N:=FixPath(Value);'#010+ ' if ExtractFileExt(N)='#039#039' then'#010+ ' ChangeFi','leExt(N,IncExt);'#010+ ' Result:=inherited Add(N,CPUs,OSes) as TDependency;'#010+ ' Result.FDependencyType:=depInclude;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TValueItem'#010+ '*****','***************************************************************'+ '********}'#010+ #010+ 'constructor TValueItem.Create(AValue: String);'#010+ 'begin'#010+ ' FValue:=AValue;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' ',' TFunctionItem'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TFunctionItem.Create(AFunc: TReplaceFunction);'#010+ 'begin'#010+ ' FFunc:=AFunc;'#010+ 'end;'#010+ #010+ #010+ '{**************************************','*****************************'+ '*********'#010+ ' TDictionary'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor TDictionary.Create(AOwner: TComponent);'#010+ 'begin'#010+ ' inherited Create(','AOwner);'#010+ ' FList:=TStringList.Create;'#010+ ' FList.Sorted:=True;'#010+ ' FList.Duplicates:=dupError;'#010+ 'end;'#010+ #010+ #010+ 'destructor TDictionary.Destroy;'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' For I:=0 to Flist.Count-1 do'#010+ ' FList.Objects[i].Free;'#010+ ' FreeAndNil(FList);'#010+ ' inher','ited Destroy;'#010+ 'end;'#010+ #010+ #010+ 'procedure TDictionary.AddVariable(const AName, Value: String);'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=Flist.IndexOf(AName);'#010+ ' If I=-1 then'#010+ ' I:=FList.Add(Aname)'#010+ ' else'#010+ ' Flist.Objects[i].Free;'#010+ ' Flist.Objects[i]:=TValueItem.','Create(Value);'#010+ 'end;'#010+ #010+ #010+ 'procedure TDictionary.AddFunction(const AName: String; FReplacement: T'+ 'ReplaceFunction);'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=Flist.IndexOf(AName);'#010+ ' If I=-1 then'#010+ ' I:=Flist.Add(AName)'#010+ ' else'#010+ ' Flist.Objects[i].Free;'#010+ ' Fli','st.Objects[i]:=TFunctionItem.Create(FReplacement);'#010+ 'end;'#010+ #010+ #010+ 'procedure TDictionary.RemoveItem(const AName: String);'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=Flist.IndexOf(AName);'#010+ ' If (I<>-1) then'#010+ ' begin'#010+ ' FList.Objects[i].Free;'#010+ ' FList.Delete(I);',#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'function TDictionary.GetValue(const AName: String): String;'#010+ 'begin'#010+ ' Result:=GetValue(AName,'#039#039');'#010+ 'end;'#010+ #010+ #010+ 'function TDictionary.GetValue(const AName,Args: String): String;'#010+ 'Var'#010+ ' O : TObject;'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=Flist.Inde','xOf(AName);'#010+ ' If (I=-1) then'#010+ ' Raise EDictionaryError.CreateFmt(SErrNoDictionaryItem,[AName]);'#010+ ' O:=Flist.Objects[I];'#010+ ' If O is TValueItem then'#010+ ' Result:=TValueItem(O).FValue'#010+ ' else'#010+ ' Result:=TFunctionItem(O).FFunc(AName,Args);'#010+ 'end;'#010+ #010, #010+ 'function TDictionary.ReplaceStrings(Const ASource: String): String;'#010+ 'Var'#010+ ' S,FN,FV : String;'#010+ ' P: Integer;'#010+ 'begin'#010+ ' Result:='#039#039';'#010+ ' S:=ASource;'#010+ ' P:=Pos('#039'$('#039',S);'#010+ ' While (P<>0) do'#010+ ' begin'#010+ ' Result:=Result+Copy(S,1,P-1);'#010+ ' Delete(S,1,','P+1);'#010+ ' P:=Pos('#039')'#039',S);'#010+ ' FN:=Copy(S,1,P-1);'#010+ ' Delete(S,1,P);'#010+ ' P:=Pos('#039' '#039',FN);'#010+ ' If (P<>0) then // function arguments ?'#010+ ' begin'#010+ ' FV:=FN;'#010+ ' FN:=Copy(FN,1,P);'#010+ ' System.Delete(FV,1,P);'#010+ ' end'#010+ ' ',' else'#010+ ' FV:='#039#039';'#010+ ' Result:=Result+GetValue(FN,FV);'#010+ ' P:=Pos('#039'$('#039',S);'#010+ ' end;'#010+ ' Result:=Result+S;'#010+ 'end;'#010+ #010+ #010+ 'Function Substitute(Const Source : String; Macros : Array of string) :'+ ' String;'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=0;'#010+ ' Whil','e I