{$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+ ' FExternalURL: String;'#010+ ' FVersion: TFPVersion;'#010+ ' FEmail : String;'#010+ ' FNeedL','ibC : Boolean;'#010+ ' FCommands : TCommands;'#010+ ' FDescriptionFile : String;'#010+ ' FDescription : String;'#010+ ' FInstalledChecksum : Cardinal;'#010+ ' // Cached directory of installed packages'#010+ ' FUnitDir : String;'#010+ ' Function 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 LoadUnitConfigFromFile(Const AFileName: Strin','g);'#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 GetUnitsOutputDir(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;ACPU'+ ':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 : String Read GetFileName Write',' FFileName;'#010+ ' Property ExternalURL : String Read FExternalURL Write FExternalURL'+ ';'#010+ ' Property Email : String Read FEmail Write FEmail;'#010+ ' Property Author : String Read FAuthor Write FAuthor;'#010+ ' Property License : String Read FLicense W','rite FLicense;'#010+ ' Property Directory : String Read FDirectory Write FDirectory;'#010+ ' Property Description : String Read GetDescription Write FDescripti'+ 'on;'#010+ ' Property DescriptionFile : String Read FDescriptionFile Write FDes'+ 'criptionFile;'#010+ ' ',' Property InstalledChecksum : Cardinal Read FInstalledChecksum Wr'+ 'ite 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 Incl','udePath : TConditionalStrings Read FIncludePath;'#010+ ' Property SourcePath : TConditionalStrings Read FSourcePath;'#010+ ' Property ExamplePath : TConditionalStrings Read FExamplePath;'#010+ ' Property TestPath : TConditionalStrings Read FTestPath;'#010+ ' ',' // Targets and dependencies'#010+ ' Property InstallFiles : TConditionalStrings Read FInstallFiles;'#010+ ' Property CleanFiles : TConditionalStrings Read FCleanFiles;'#010+ ' Property Dependencies : TDependencies Read FDependencies;'#010+ ' Property Co','mmands : TCommands Read FCommands;'#010+ ' Property State : TTargetState Read FTargetState;'#010+ ' Property Targets : TTargets Read FTargets;'#010+ ' Property 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 Read FAfterCompile Write FAft'+ 'erCompile;'#010+ ' Property BeforeInstall : TNotifyEvent Read FBeforeInsta','ll Write '+ 'FBeforeInstall;'#010+ ' Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAft'+ 'erInstall;'#010+ ' Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBefor'+ 'eClean;'#010+ ' Property AfterClean : TNotifyEvent Read FAfterClean ','Write FAfter'+ 'Clean;'#010+ ' Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FB'+ 'eforeArchive;'#010+ ' Property AfterArchive : TNotifyEvent Read FAfterArchive Write FAft'+ 'erArchive;'#010+ ' Property BeforeManifest : TNotifyEvent Read FBeforeM','anifest Writ'+ 'e 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): TPack','age;'#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 ; D'+ 'efault;'#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 : TCompilerMode;'#010+ ' FCompilerVersion : String;'#010+ ' FPrefix: String;'#010+ ' FLocalUnitDir,'#010+ ' FGlobalUn','itDir,'#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 GetLocalUnitD','ir: String;'#010+ ' function GetGlobalUnitDir: String;'#010+ ' function GetBaseInstallDir: String;'#010+ ' function GetBinInstallDir: String;'#010+ ' function GetCompiler: String;'#010+ ' function GetDocInstallDir: String;'#010+ ' function GetExamplesInstallDir: S','tring;'#010+ ' function GetUnitInstallDir: String;'#010+ ' procedure SetLocalUnitDir(const AValue: String);'#010+ ' procedure SetGlobalUnitDir(const AValue: String);'#010+ ' procedure SetBaseInstallDir(const AValue: String);'#010+ ' procedure SetCPU(const AVal','ue: 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 InitDefa','ults;'#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 : TStre','am);virtual;'#010+ ' procedure LoadFromStream(S : TStream);virtual;'#010+ ' // Compile Information'#010+ ' Property Target : String Read FTarget Write SetTarget;'#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 Options : String Read FOptions Write FOptions; // Defa'+ 'ult 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 SetGlo'+ 'balUnitDir;'#010+ ' Property Prefi','x : String Read FPrefix Write SetPrefix;'#010+ ' Property BaseInstallDir : String Read GetBaseInstallDir Write SetB'+ 'aseInstallDir;'#010+ ' Property UnitInstallDir : String Read GetUnitInstallDir Write FUni'+ 'tInstallDir;'#010+ ' Property BinInstallDir : St','ring Read GetBinInstallDir Write FBin'+ 'InstallDir;'#010+ ' Property DocInstallDir : String Read GetDocInstallDir Write FDocIn'+ 'stallDir;'#010+ ' Property ExamplesInstallDir : String Read GetExamplesInstallDir Wr'+ 'ite FExamplesInstallDir;'#010+ ' // Command t','ools. If not set, internal commands will be used.'#010+ ' Property Compiler : String Read GetCompiler Write FCompiler; // Co'+ 'mpiler. Defaults to fpc'#010+ ' Property Copy : String Read FCopy Write FCopy; // copy'+ ' $(FILES) to $(DEST)'#010+ ' ','Property Move : String Read FMove Write FMove; // Mo'+ 've $(FILES) to $(DEST)'#010+ ' Property Remove : String Read FRemove Write FRemove; // Dele'+ 'te $(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+ ' TBasicDefaults = Class(TCustomDefaults)'#010+ ' end;'#010+ #010+ ' { TFPCDefaults }'#010+ #010+ ' TFPCDefaults = Class(TCustomD','efaults)'#010+ ' public'#010+ ' procedure CompilerDefaults; override;'#010+ ' end;'#010+ #010+ ' { TBuildEngine }'#010+ #010+ ' TBuildEngine = Class(TComponent)'#010+ ' private'#010+ ' // general variables'#010+ ' FCompiler : String;'#010+ ' FStartDir : String;'#010+ ' FForceCompile : Boolean;'#010+ ' F','ListMode : 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+ ' FBeforeArchive: TNotifyEvent;'#010+ ' FBeforeClean: TNotifyEvent;'#010+ ' FBeforeCompile: TNotifyEvent;'#010+ ' FBefore','Install: 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+ ' Fu','nction 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); virtual;'#010+ ' procedure LogIndent;'#010+ ' procedure LogUnIndent;'#010+ ' Procedure Log(Level : TVerboseLevel; Co','nst Msg : String);'#010+ ' Procedure Log(Level : TVerboseLevel; Const Fmt : String; const Arg'+ 's : Array Of Const);'#010+ ' Procedure EnterDir(ADir : String);'#010+ ' Function GetCompiler : String;'#010+ ' Function InstallPackageFiles(APAckage : TPackage; tt',' : TTargetTy'+ 'pe; Const Dest : String):Boolean;'#010+ ' Function FileNewer(const Src,Dest : String) : Boolean;'#010+ ' Procedure LogSearchPath(const ASearchPathName:string;Path:TConditi'+ 'onalStrings; ACPU:TCPU;AOS:TOS);'#010+ ' Function FindFileInPath(Path',':TConditionalStrings; AFileName:Stri'+ 'ng; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;'#010+ #010+ ' //package commands'#010+ ' Procedure ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;'+ 'DoChangeDir:boolean=true);'#010+ ' function GetUnitDir(APack','age:TPackage):String;'#010+ ' procedure AddDependencyIncludePaths(L:TStrings;ATarget: TTarget);'#010+ ' procedure AddDependencyUnitPaths(L:TStrings;APackage: 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 : Bo'+ 'olean = 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 CmdDeleteFiles(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 : TDependency) : Boolean;'#010+ ' // Target commands'#010+ ' Function GetCompilerCommand(APackage : TPackage; ','ATarget : TTar'+ 'get) : String;'#010+ ' Function TargetOK(ATarget : TTarget) : Boolean;'#010+ ' Function NeedsCompile(APackage:TPackage; ATarget : TTarget) : Boo'+ 'lean;'#010+ ' Procedure Compile(APackage:TPackage; ATarget : TTarget); virtual;'+ #010+ ' Procedu','re MaybeCompile(APackage:TPackage; ATarget: TTarget);'#010+ ' Procedure CompileDependencies(APackage:TPackage; ATarget: TTarget)'+ ';'#010+ ' // Package commands'#010+ '{ Function GetPackageDir(APackage : TPackage; AbsolutePath : Boole'+ 'an = False) : String',';'#010+ ' Function GetUnitsOutputDir(APackage : TPackage; AbsolutePath : Bo'+ 'olean = False) : String;'#010+ ' Function GetBinOutputDir(APackage : TPackage; AbsolutePath : Bool'+ 'ean = False) : String; }'#010+ ' Function PackageOK(APackage : TPackage) : ','Boolean; virtual;'#010+ ' Procedure DoBeforeCompile(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterCompile(APackage : TPackage);virtual;'#010+ ' Procedure DoBeforeInstall(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterInstall(APackage : TPa','ckage);virtual;'#010+ ' Procedure DoBeforeArchive(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterArchive(APackage : TPackage);virtual;'#010+ ' Procedure DoBeforeClean(APackage : TPackage);virtual;'#010+ ' Procedure DoAfterClean(APackage : TPackage)',';virtual;'#010+ ' Function NeedsCompile(APackage : TPackage) : Boolean; virtual;'#010+ ' Procedure Compile(APackage : TPackage);'#010+ ' Procedure MaybeCompile(APackage:TPackage);'#010+ ' Procedure Install(APackage : TPackage);'#010+ ' Procedure Archive(APack','age : TPackage);'#010+ ' Procedure Manifest(APackage : TPackage);'#010+ ' Procedure Clean(APackage : TPackage);'#010+ ' Procedure CompileDependencies(APackage : TPackage);'#010+ ' Function CheckExternalPackage(Const APackageName : String):TPacka'+ 'ge;'#010+ ' pr','ocedure CreateOutputDir(APackage: TPackage);'#010+ ' // Packages commands'#010+ ' Procedure Compile(Packages : TPackages);'#010+ ' Procedure Install(Packages : TPackages);'#010+ ' Procedure Archive(Packages : TPackages);'#010+ ' procedure Manifest(Packages: TP','ackages);'#010+ ' Procedure Clean(Packages : TPackages);'#010+ ' Property ListMode : Boolean Read FListMode Write FListMode;'#010+ ' Property ForceCompile : Boolean Read FForceCompile Write FForceCom'+ 'pile;'#010+ ' Property ExternalPackages: TPackages Read F','ExternalPackages;'#010+ ' // Events'#010+ ' Property BeforeCompile : TNotifyEvent Read FBeforeCompile Write FB'+ 'eforeCompile;'#010+ ' Property AfterCompile : TNotifyEvent Read FAfterCompile Write FAft'+ 'erCompile;'#010+ ' Property BeforeInstall : TNotifyEvent R','ead FBeforeInstall Write '+ 'FBeforeInstall;'#010+ ' Property AfterInstall : TNotifyEvent Read FAfterInstall Write FAft'+ 'erInstall;'#010+ ' Property BeforeClean : TNotifyEvent Read FBeforeClean Write FBefor'+ 'eClean;'#010+ ' Property AfterClean : TNotifyEvent R','ead FAfterClean Write FAfter'+ 'Clean;'#010+ ' Property BeforeArchive : TNotifyEvent Read FBeforeArchive Write FB'+ 'eforeArchive;'#010+ ' Property AfterArchive : TNotifyEvent Read FAfterArchive Write FAft'+ 'erArchive;'#010+ ' Property BeforeManifest : TNotifyEve','nt Read FBeforeManifest Writ'+ 'e FBeforeManifest;'#010+ ' Property AfterManifest : TNotifyEvent Read FAfterManifest Write FA'+ 'fterManifest;'#010+ ' Property 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+ ' FLogLevels : 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+ ' Procedure Clean; virtual;'#010+ ' Procedure Install; virtual;'#010+ ' Procedure Archive; virtual;'#010+ ' Procedure Ma','nifest; 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+ ' Funct','ion 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(T','CustomInstaller)'#010+ ' public'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' end;'#010+ #010+ ' { TBasicInstaller }'#010+ ' TBasicInstaller = class(TCustomInstaller)'#010+ ' Constructor Create(AOwner : TComponent); override;'#010+ ' end;'#010+ #010+ ' TReplaceFunction = F','unction (Const AName,Args : String) : String o'+ 'f 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 Destro','y;override;'#010+ ' Procedure AddVariable(Const AName,Value : String);'#010+ ' Procedure AddFunction(Const AName : String; FReplacement : TReplac'+ 'eFunction);'#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; virtual;'+ #010+ ' end;'#010+ #010+ ' ECollectionError = Class(Exception);'#010+ ' EDictionaryError = Class(Exception);'#010+ ' EI','nstallerError = Class(Exception);'#010+ #010+ ' TInstallerClass = Class of TCustomInstaller;'#010+ ' TDictionaryClass = Class of TDictionary;'#010+ #010+ 'Type'#010+ ' TArchiveEvent = Procedure (Const AFileName : String; List : TStrings'+ ') of Object;'#010+ ' TArchiveProc = Procedure',' (Const AFileName : String; List : TString'+ 's);'#010+ #010+ 'Var'#010+ ' DictionaryClass : TDictionaryClass = TDictionary;'#010+ ' OnArchiveFiles : TArchiveEvent = Nil;'#010+ ' ArchiveFilesProc : TArchiveProc = Nil;'#010+ #010+ ' Defaults : TCustomDefaults; // Set by installer.'#010+ ' Di','ctionary : TDictionary;'#010+ #010+ #010+ 'Function CurrentOS : String;'#010+ 'Function CurrentCPU : String;'#010+ #010+ 'Function Installer(InstallerClass: TInstallerClass) : TCustomInstaller'+ '; 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) : String;'#010+ 'Function StringToOS(const S : String) : TOS;'#010+ 'Function OSesToString(const S : String) : TOSe','s;'#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) : String;'#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+ 'ResourceString'#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 collect'+ 'ion.'#039';'#010+ ' SErrNoSuchName = '#039'Could not find item',' with name "%s" in'+ ' the 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 arg'+ 'ument'#039';'#010+ ' SErrNoPackagesDefined = '#039'No action possible: No p','ackages were '+ 'defined.'#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+ ' SErrMovingFile = '#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 Substitute'#039';'#010+ ' SErrNoArchiveSupport = '#039'This binary contains no archive support'+ '. Please recompile wi','th archive support'#039';'#010+ ' SErrNoDictionaryItem = '#039'No item called "%s" in the dictionary'#039+ ';'#010+ ' SErrNoDictionaryValue = '#039'The item "%s" in the dictionary is not '+ '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 directory for depe'+ 'ndency package "%s"'#039';'#010+ ' SErrAlreadyInitialized = '#039'Installer can only be initializ','ed on'+ 'ce'#039';'#010+ ' SErrInvalidState = '#039'Invalid state for target %s'#039';'#010+ #010+ ' SWarnCircularTargetDependency = '#039'Warning: Circular dependency de'+ 'tected when compiling target %s with target %s'#039';'#010+ ' SWarnCircularPackageDependency = '#039'Warning: Circular dep','endency'+ ' detected when compiling package %s with package %s'#039';'#010+ ' SWarnFailedToSetTime = '#039'Warning: Failed to set timestamp on f'+ 'ile "%s"'#039';'#010+ ' SWarnFailedToGetTime = '#039'Warning: Failed to get timestamp from'+ ' 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+ ' SWarnIncludeFileNotF','ound = '#039'Warning: Include file "%s" not fou'+ 'nd 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+ ' SInfoCl','eaningPackage = '#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'Compiling dependencies of t'+ 'arget %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'Depende','ncy 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+ ' SDbgSkippingTargetW','rongOS = '#039'Skipping target %s, different OS'+ ' (%s)'#039';'#010+ ' SDbgTargetIsNotAUnitOrProgram = '#039'Skipping Target %s, not an unit'+ ' or program'#039';'#010+ ' SDbgConsideringTarget = '#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+ ' SDbgBuildEngineGenerateManifests = '#039'Build engine generating mani'+ 'fests'#039';'#010+ ' SDbgBuildEngineCleaning = '#039'Build e','ngine 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 path "%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 in '+ 'repository.'#039';'#010+ ' SHelpCmdOptions = '#039'Where option','s is one or more of the fol'+ 'lowing:'#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 in','stead of actually execu'+ 'ting them.'#039';'#010+ ' SHelpPrefix = '#039'Use indicated prefix directory for all co'+ 'mmands.'#039';'#010+ ' SHelpNoFPCCfg = '#039'Compiler 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 di'+ 'r.'#039';'#010+ ' SHelpCompiler = '#039'Use indicated binary as compiler'#039';'#010+ ' SHelpConfig = '#039'Use in','dicated config file when compilin'+ 'g.'#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+ ' KeyL','ocalUnitDir = '#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'Doc','InstallDir'#039';'#010+ ' KeyExamplesInstallDir = '#039'ExamplesInstallDir'#039';'#010+ ' // Keys for unit config'#010+ ' KeyName = '#039'Name'#039';'#010+ ' KeyVersion = '#039'Version'#039';'#010+ ' KeyChecksum = '#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+ ' For 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 spe'+ 'c 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+ 'en','d;'#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 : integer;'#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+ ' maybequoted:=s1+'#039'"'#039#010+ ' else'#010+ ' maybequoted:=s;'#010+ 'end;'#010+ #010+ #010+ 'procedure ReadIniFile(Const AFileName: String;L:TSt','rings);'#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.LoadFromStream(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 (A','Prefix<>'#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 AP','refix : String) :'+ ' String;'#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 (result<>'#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+ 'begin'#010+ ' if Not SetCurrentDir(APath) then'#010+ ' Raise EInstallerError.CreateFmt(SErrChangeDirFailed,[A','Path]);'#010+ 'end;'#010+ #010+ #010+ 'procedure SearchFiles(const AFileName: string; Recursive: boolean; var'+ ' List: TStrings);'#010+ #010+ ' procedure AddRecursiveFiles(const SearchDir, FileMask: string; Recur'+ 'sive: 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+ ' repeat'#010+ ' if ((Info.Attr and faDirectory) = faDirectory) and (Info.Nam'+ 'e <> '#039'.'#039') and (Info.Name <','> '#039'..'#039') and (Recursive) th'+ 'en'#010+ ' AddRecursiveFiles(SearchDir + Info.Name + PathDelim, FileM'+ 'ask, Recursive);'#010+ ' if ((Info.Attr and faDirectory) <> faDirectory) and IsWild(I'+ 'nfo.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: integer;'#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(IncludeTrailingPathDelimiter(CurrDi'+ 'r), 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+ ' LastQuote : 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]=LastQuote);'#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(B','uf,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.Crea','teFmt(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,A'+ 'Name)<>0) do'#010+ ' Dec(Result);'#010+ 'end;'#010+ #010+ 'function TNamedCo','llection.ItemByName(const AName: String): TNamedIte'+ 'm;'#010+ #010+ 'Var'#010+ ' I : Integer;'#010+ #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+ ' 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): In','teger;'#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:=IndexOfN','ame(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): TTarget;'#010+ 'begin'#010+ ' Result:=TTarget(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'function TTargets.GetTarget(const AName : Strin','g): TTarget;'#010+ 'begin'#010+ ' Result:=TTarget(ItemByName(AName));'#010+ 'end;'#010+ #010+ #010+ 'procedure TTargets.SetTargetItem(Index : Integer; const AValue: TTarge'+ 't);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddUnit(Const AUnitName : String) : TTarget;'#010+ 'be','gin'#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.A','ddUnit(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+ 'Function TTargets.AddImplicitUnit(Const AUnitName : String;InstallUnit'+ ':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.AddImplicit','Unit(Const AUnitName : String;const CPU'+ 's: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.Target','Type:=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(Co','nst AProgramName : String;const OSes:'+ 'TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=AddProgram(AProgramName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TTargets.AddProgram(Const AProgramName : String;const CPUs:TC'+ 'PUs) : TTarget;'#010+ 'begin'#010+ ' R','esult:=AddProgram(AProgramName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TTargets.AddProgram(Const AProgramName : String;const CPUs:TC'+ 'PUs;const OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Result.Name:=AProgramN','ame;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.TargetType:=ttProgram;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleUnit(Const AUnitName : String) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,AllCPUs,AllOSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.','AddExampleUnit(Const AUnitName : String;const OSes'+ ':TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TTargets.AddExampleUnit(Const AUnitName : String;const CPUs:T'+ 'CPUs) : TT','arget;'#010+ 'begin'#010+ ' Result:=AddExampleUnit(AUnitName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#010+ #010+ #010+ 'Function TTargets.AddExampleUnit(Const AUnitName : String;const CPUs:T'+ 'CPUs;const OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=Add as TTarget;'#010+ ' Resu','lt.Name:=AUnitName;'#010+ ' Result.CPUs:=CPUs;'#010+ ' Result.OSes:=OSes;'#010+ ' Result.TargetType:=ttExampleUnit;'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleProgram(Const AProgramName : String) : TTa'+ 'rget;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AProgramName,AllCPUs,AllO','Ses);'#010+ 'end;'#010+ #010+ #010+ 'Function TTargets.AddExampleProgram(Const AProgramName : String;const '+ 'OSes:TOSes) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AProgramName,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#010+ 'Function TTargets.AddExampleProgram(C','onst AProgramName : String;cons'+ 't CPUs:TCPUs) : TTarget;'#010+ 'begin'#010+ ' Result:=AddExampleProgram(AProgramName,CPUs,AllOSes);'#010+ 'end;'#010+ '{$endif cpu_only_overloads}'#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.TargetType:=ttExampleProgram;'#010+ 'end;'#010+ #010+ #010+ '{*******************************************************************','*'+ '********'#010+ ' TSources'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'function TSources.GetSourceItem(Index : Integer): TSource;'#010+ 'begin'#010+ ' Result:=TSource(Items[Index]);'#010+ 'end;'#010+ #010+ #010+ 'proce','dure TSources.SetSourceItem(Index : Integer; const AValue: TSou'+ 'rce);'#010+ 'begin'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddDoc (const AFiles : String) : TSource;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceTyp','e:=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.FSourceType:=stSrc;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddExample(const AFiles : String) : TSource;'#010+ 'begin'#010+ ' Re','sult:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceType:=stExample;'#010+ 'end;'#010+ #010+ #010+ 'function TSources.AddTest(const AFiles : String) : TSource;'#010+ 'begin'#010+ ' Result:=Add as TSource;'#010+ ' Result.Name:=AFiles;'#010+ ' Result.FSourceType:=stTest;'#010+ 'end;'#010+ #010+ #010+ 'pro','cedure TSources.AddDocFiles(const AFileMask: string; Recursive: b'+ 'oolean);'#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+ ' 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+ 'begin'#010+ ' List := TStringList.Create;'#010+ ' SearchFiles(AFileMask, Recursive, List);'#010+ ' for i:= 0 to Pred(L','ist.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, Recurs','ive, 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: string; Recursive: bo'+ 'olean);'#010+ 'var'#010+ ' List : TStrings;'#010+ ' i: integer;'#010+ 'begin'#010+ ' List := TStringList.Creat','e;'#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+ ' inherited 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(TConditionalString);'#010+ ' FCleanFiles:=TConditionalStrings.Create(TConditionalString);'#010+ ' FUnitPath:=TConditi','onalStrings.Create(TConditionalString);'#010+ ' FObjectPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FIncludePath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FSourcePath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FExample','Path:=TConditionalStrings.Create(TConditionalString);'#010+ ' FTestPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FCommands:=TCommands.Create(TCommand);'#010+ ' FCPUs:=AllCPUs;'#010+ ' FOSes:=AllOSes;'#010+ ' FInstalledChecksum:=$ffffffff;'#010+ ' // Implicit d','ependency 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+MakeTa','rgetString(ACPU,AOS);'#010+ 'end;'#010+ #010+ #010+ 'Function TPackage.GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;'#010+ 'begin'#010+ ' Result:='#039'bin'#039'+PathDelim+MakeTargetString(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:=IncludeTrailingPathDelimiter(GetUnitsOutputDir(Defaults.CPU,Defa'+ 'ults.OS));'#010+ ' AddConditionalStrings(List,CleanFiles,ACP','U,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.GetInstallFiles(List: TStrings;Types : TTargetTypes'+ ';ACPU:TCPU; AOS : TOS);'#010+ 'Var'#010+ ' OB,OU : String;'#010+ ' I : I','nteger;'#010+ ' T : TTarget;'#010+ 'begin'#010+ ' OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(Defaults.CPU,Defaul'+ 'ts.OS));'#010+ ' OU:=IncludeTrailingPathDelimiter(GetUnitsOutputDir(Defaults.CPU,Defa'+ 'ults.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(Lis','t: TStrings; ACPU:TCPU; AOS : '+ 'TOS);'#010+ 'Var'#010+ ' I : Integer;'#010+ 'begin'#010+ ' // Targets only'#010+ ' For I:=0 to FTargets.Count-1 do'#010+ ' FTargets.TargetItems[I].GetArchiveFiles(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+FDesc','riptionFile;'#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(const 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 Add','OSes(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(Forma','t(AIndent+'#039' '#039',[OSTo'+ 'String(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(AI','ndent+'#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 : Inte','ger;'#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,FVers','ion.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',[Quot','eXml(License)])'+ ');'#010+ ' if ExternalURL<>'#039#039' then'#010+ ' Add(Format('#039' %s'#039',[QuoteXml(Ex'+ 'ternalURL)]));'#010+ ' Add(Format('#039' %s'#039',[QuoteXMl(Email)]));'#010+ ' S:=Description;'#010+ ' If (S<>'#039#039') then'#010+ ' Add(Format('#039' <','description>%s'#039',[QuoteXML('+ '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',[Quote'+ 'XML(D.Value)]));'#010+ ' if not D.FVersion.Empty then'#010+ ' Add(Format('#039' '#039',[D.FVersion.Major,D.FV','ersion.Minor,D.FVersion'+ '.Micro,D.FVersion.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.LoadUnitConfigFromFile(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.C','reate;'#010+ ' Try'#010+ ' ReadIniFile(AFileName,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+ ' DepCh','ecksum:=$ffffffff;'#010+ ' D:=Dependencies.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.SaveUnitConfigToFile(Const AFileName: String;ACPU:T'+ 'CPU;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(AFile','Name,fmCreate);'#010+ ' L:=TStringList.Create;'#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(DateTimeToFil','eDate(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) an','d (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) '+ 'then'#010+ ' Deps:=Deps+'#039'|'#039'+IntToStr(P.InstalledChecksum)'+ ';'#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.SaveToStream(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+ 'end;'#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+ 'end;'#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 Unix','Paths 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 Un','ixPaths then'#010+ ' Result:=BaseInstallDir+'#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+ 'functio','n TCustomDefaults.GetDocInstallDir: String;'#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+ 'funct','ion TCustomDefaults.GetExamplesInstallDir: 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+ ' Resu','lt:=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+ ' else'#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:=Includ','eTrailingPathDelimiter(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+ ' FGlobalUnit','Dir:=IncludeTrailingPathDelimiter(ExpandFileName(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:=IncludeTrailingPathDelimiter(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+ 'procedure 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.SetT','arget(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:=Stri','ngToCPU(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+ 'constr','uctor 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+ 'proced','ure TCustomDefaults.LocalInit(Const AFileName : 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 FileE','xists(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:=GetAppConfigFile(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+ '{$if','def 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 FCompilerVersio','n='#039#039' then'#010+ ' FCompilerVersion:=infosl[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 then'#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+ 'procedure 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+ ' Values[KeyOptions]:=FOptions;'#010+ ' Values[KeyCPU]:=CPUToString(FCPU);'#010+ ' Values[KeyOS]:=OSToString(FOS);'#010+ ' Values[KeyMode]:=ModeToString(FMode);'#010+ ' Values[KeyLocalUnitDir]:=FLocalUnitDir;'#010+ ' Val','ues[KeyGlobalUnitDir]:=FGlobalUnitDir;'#010+ ' Values[KeyPrefix]:=FPrefix;'#010+ ' Values[KeyBaseInstallDir]:=FBaseInstallDir;'#010+ ' Values[KeyUnitInstallDir]:=FUnitInstallDir;'#010+ ' Values[KeyBinInstallDir]:=FBinInstallDir;'#010+ ' Values[KeyDoc','InstallDir]:=FDocInstallDir;'#010+ ' Values[KeyExamplesInstallDir]:=FExamplesInstallDir;'#010+ ' Values[KeyRemove]:=FRemove;'#010+ ' Values[KeyTarget]:=FTarget;'#010+ ' if FNoFPCCfg then'#010+ ' Values[KeyNoFPCCfg]:='#039'Y'#039';'#010+ ' end;'#010+ ' L.SaveToStre','am(S);'#010+ ' Finally'#010+ ' L.Free;'#010+ ' end;'#010+ 'end;'#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+ ' Fo','r 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'#039#039') then'#010+ ' FCPU:=StringToCPU(Line);'#010+ ' Line:=Values[KeyOS];'#010+ ' If (Line<>'#039#039') then'#010+ ' FOS:=Strin','gToOS(Line);'#010+ ' Line:=Values[KeyMode];'#010+ ' If (Line<>'#039#039') then'#010+ ' FMode:=StringToMode(Line);'#010+ ' FTarget:=Values[KeyTarget];'#010+ ' FLocalUnitDir:=Values[KeyLocalUnitDir];'#010+ ' FGlobalUnitDir:=Values[KeyGlobalUnitDir];'#010+ ' FPre','fix:=Values[KeyPrefix];'#010+ ' FBaseInstallDir:=Values[KeyBaseInstallDir];'#010+ ' FUnitInstallDir:=Values[KeyUnitInstallDir];'#010+ ' FBinInstallDir:=Values[KeyBinInstallDir];'#010+ ' FDocInstallDir:=Values[KeyDocInstallDir];'#010+ ' FExamplesInsta','llDir:=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, se','e options.pas'#010+ '{$ifdef Unix}'#010+ ' BD:=FixPath(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'+FCompiler','Version) t'+ 'hen'#010+ ' BD:='#039'/usr/lib/fpc/'#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(BD+'#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+ ' TC','ustomInstaller'#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.Destroy;'#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+ ' Wri','teln(StdOut,Msg);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.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.Defaul','ts:=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: Str','ing; Args: array of c'+ 'onst);'#010+ 'begin'#010+ ' Raise 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.Analy','zeOptions;'#010+ #010+ ' Function CheckOption(Index : Integer;const Short,Long : String): Boo'+ 'lean;'#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 : Integer;const Short,Long : String): Bo'+ 'olean;'#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(ParamStr(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+ ' begi','n'#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 : Strin','g);'#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+ ' beg','in'#010+ ' Log(vlInfo,Format('#039' -%s --%-20s %s'#039',[C,LC+'#039'='#039'+SVal'+ 'ue,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,[Param','str(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+ ' L','og(vlInfo,SHelpCmdOptions);'#010+ ' LogOption('#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+ ' LogArgOptio','n('#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'g','lobalunitdir'#039',SHelpGlobalUnitd'+ 'ir);'#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.ForceCompile:=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(F','Packages);'#010+ 'end;'#010+ #010+ #010+ 'procedure TCustomInstaller.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.Ma','nifest;'#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.R','un : 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 : Manifest;'#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 she','ll'#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 assi','gned(Defaults) then'#010+ ' Error(SErrAlreadyInitialized);'#010+ ' Defaults:=TBasicDefaults.Create;'#010+ ' inherited Create(AOwner);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TBui','ldEngine'#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 t'+ 'hem'#010+ ' // With --start-dir=/path/to/sources.'#010+ ' FStartDir:=includeTrailingPathDelimiter(GetCurrentDir);'#010+ ' FExternalPackages:=TPackages.Create(TPackage);'#010, 'end;'#010+ #010+ #010+ 'destructor TBuildEngine.Destroy;'#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'+ ' const);'#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,SInfoE','xecutingCommand,[Cmd,Args]);'#010+ ' if ListMode 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(SErrExternalCommandFailed,[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,SD','bgDirectoryExists,[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 the','n'#010+ ' Log(vlDebug,SDbgFileExists,[AFileName,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+ ' Cou','nt : Int64;'#010+ ' A : Integer;'#010+ 'begin'#010+ ' Log(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.SysM','oveFile(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+ ' b','egin'#010+ ' Try'#010+ ' SysCopyFile(Src,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 : Strin','g);'#010+ 'begin'#010+ ' if not FileExists(AFileName) 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: TString','s;Const AFileNam'+ 'e: String);'#010+ 'begin'#010+ ' If Not (Assigned(OnArchivefiles) or Assigned(ArchiveFilesProc)) then'+ #010+ ' Raise EInstallerError.Create(SErrNoArchiveSupport);'#010+ ' If Assigned(ArchiveFilesProc) then'#010+ ' ArchiveFilesProc(AFileName,List)'#010+ ' els','e'#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: TVerbose','Level; 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: TVerb','oseLevel; const Fmt: String;c'+ 'onst Args: 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 N','ot SetCurrentDir(D) then'#010+ ' Error(SErrChangeDirFailed,[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') th','en'#010+ ' begin'#010+ ' Args:=FileListToString(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.Cmd','CreateDir(const DestDir: String);'#010+ 'begin'#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.C','mdMoveFiles(List: TStrings; Const DestDir: 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+ ' Execut','eCommand(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:=FileListToString(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 Archive'+ 'File: 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') th','en'#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:=FileAge(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 R','esult then'#010+ ' Log(vlInfo,SInfoSourceNewerDest,[Src,DateTimeToStr(D1),Dest,DateTi'+ 'meToStr(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 : B','oolean;'#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.Sour','ceFile,IncludeTrailingPathDelimiter(D'+ 'ictionary.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'S','OURCE'#039',C.SourceFile,'#039+ 'DEST'#039',C.DestFile]);'#010+ ' Cmd:=C.Command;'#010+ ' If (ExtractFilePath(Cmd)='#039#039') then'#010+ ' Cmd:=FileSearch(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 : St','ring;'#010+ ' I : Integer;'#010+ ' C : TConditionalString;'#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.ReplaceStrings(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 FoundP','ath: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:=IncludeTrailingPathDelimiter(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+ ' FoundP','ath:='#039#039';'#010+ 'end;'#010+ #010+ #010+ 'Procedure TBuildEngine.ResolveFileNames(APackage : TPackage; ACPU:TCPU'+ ';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,'+ 'AOS);'#010+ ' SD:=Dictionary.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:=IncludeTrai','lingPathDelimiter(SD);'#010+ ' T.FTargetSourceFileName:=SD+SF;'#010+ ' if FileExists(T.TargetSourceFileName) then'#010+ ' Log(vlDebug,SDbgResolvedSourceFile,[T.SourceFileName,T.TargetSou'+ 'rceFileName])'#010+ ' else'#010+ ' begin'#010+ ' Log(vlWarning,SWarnSo','urceFileNotFound,[T.SourceFileName,Make'+ '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.IncludePath,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=de','pInclude) 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'+ ',AOS);'#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(vlWarni','ng,SWarnIncludeFileNotFound,[D.Value,'+ 'MakeTargetString(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+ ' LogSearchPath('#039'package example'#039',APackage.ExamplePath,ACPU,'+ 'AOS);'#010+ ' SD:=Dictionary.ReplaceStrings(T.Directory);'#010+ ' SF:=Dictionary.ReplaceStrings(T.SourceFileName);'#010+ ' if SD='#039#039' then'#010+ ' FindFileInPath(APackage.E','xamplePath,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.Targe','tS'+ 'ourceFileName])'#010+ ' else'#010+ ' begin'#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((A','CPU in APackage.CPUs) and (AOS in APackage.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 to 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+ ' Lo','g(vlDebug,SDbgResolvingSourcesOfTarget,[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.Get','UnitDir(APackage:TPackage):String;'#010+ 'begin'#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+ ' begin'#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+ ' begin'#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 searches 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.TargetFil'+ 'eName));'#010+ ' if SD<>'#039#039' then'#010+ ' L.Add(SD);'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.AddDependencyUnitPaths(L:TStrin','gs;APackage: T'+ 'Package);'#010+ 'Var'#010+ ' I : Integer;'#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 (Defaults.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+ 'en','d;'#010+ #010+ #010+ 'Function TBuildEngine.GetCompilerCommand(APackage : TPackage; ATarget '+ ': 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 config','uration'#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(Defaults.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(D','efaults.CPU,Def'+ 'aults.OS));'#010+ ' // Object 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.O'+ 'S);'#010+ ' for i:=0 to L.Count-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,AP','ackage.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:=tr','ue;'#010+ ' L.Duplicates:=dupIgnore;'#010+ ' AddDependencyIncludePaths(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+ ' FreeAndNil(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.A','dd(ATarget.Options);'#010+ ' // Add Filename 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+ 'e','nd;'#010+ #010+ #010+ 'Function TBuildEngine.GetCompiler : 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:=FileSearch(FCompiler,GetEnvironmentVariable('#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 b','in 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.O','S);'#010+ ' If not SysDirectoryExists(D) then'#010+ ' begin'#010+ ' Log(vlInfo,SInfoCreatingOutputDir,[D]);'#010+ ' CmdCreateDir(D);'#010+ ' end;'#010+ ' //do not continue loop, directory is made anyway'#010+ ' bre','ak;'#010+ ' end;'#010+ ' end;'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.DependencyOK(ADependency : TDependency) : Boolea'+ 'n;'#010+ 'begin'#010+ ' Result:=(Defaults.CPU in ADependency.CPUs) and (Defaults.OS in ADepe'+ 'ndency.OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.TargetOK(ATarge','t : TTarget) : Boolean;'#010+ 'begin'#010+ ' Result:=(Defaults.CPU in ATarget.CPUs) and (Defaults.OS in ATarget.O'+ 'Ses);'#010+ 'end;'#010+ #010+ #010+ 'Function TBuildEngine.PackageOK(APackage : TPackage) : Boolean;'#010+ 'begin'#010+ ' Result:=(Defaults.CPU in APackage.CPUs) and (Defaults.O','S in APacka'+ 'ge.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+ 'proc','edure TBuildEngine.DoAfterCompile(APackage: 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(APack','age:TPackage;ATarget: TTarge'+ 't): Boolean;'#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 resul','t then'#010+ ' begin'#010+ ' if ATarget.TargetType 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+ ' O','D:=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 n','ot Result then'#010+ ' begin'#010+ ' if FileExists(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+ ' ResolveDepen','dencies(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',') th'+ 'en'#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.Val'+ 'ue]);'#010+ ' // If a dependent package is compiled we always ne'+ 'ed to recompile'#010+ ' Log(vldebug, SDbgDependencyOnUnit, [ATarget.Name,T'+ '.Name]);'#010+ ' Result:=(T.State=tsCompiled);',#010+ ' if Result then'#010+ ' Log(vldebug, SDbgDependencyUnitRecompiled, [T.Na'+ 'me]);'#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,SDbgMustCompil','e,[ATarget.Name]);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.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+ ' I','f Assigned(ATarget.BeforeCompile) then'#010+ ' ATarget.BeforeCompile(ATarget);'#010+ ' S:=GetCompilerCommand(APackage,ATarget);'#010+ ' ExecuteCommand(GetCompiler,S);'#010+ ' If Assigned(ATarget.AfterCompile) then'#010+ ' ATarget.AfterCompile(ATarget);'#010+ ' ExecuteComm','ands(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(SDbgCompilingDepe','ndenciesOfTarget, [ATarget.Na'+ 'me]));'#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:=TTarget(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 for 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(vlWarning, Format(SWarnDepUnitNotFound, [T.Name, M'+ 'akeTargetString(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: TTarg'+ 'et);'#010+ 'begin'#010+ ' if ATarget.State<>tsNeutral then'#010+ ' Error(SErrInvalidState,[ATarget.Name]);'#010+ ' Log(vlDebug, Format(SDbgConsideringTarget, [ATarge','t.Name]));'#010+ ' LogIndent;'#010+ ' ATarget.FTargetState:=tsConsidering;'#010+ ' ResolveDependencies(ATarget.Dependencies,ATarget.Collection as TTarg'+ 'ets);'#010+ ' CompileDependencies(APackage, ATarget);'#010+ ' if NeedsCompile(APackage, ATarget) then'#010+ ' begin'#010+ ' C','ompile(APackage,ATarget);'#010+ ' ATarget.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.Dependenc','ies.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.Ta','rget);'#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 package?'#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+ ' R','esult:=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 th','en'#010+ ' Log(vlDebug,SDbgMustCompile,[APackage.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(APa','ckageName);'#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 un','it 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 FileExists(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(SErrDependencyNotFound,[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.Dependencie','s.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) 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.Ins','talledChecksum<>$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+ ' Try'#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.TargetItems[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(APa','ckage,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.Na'+ 'me, 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(SErrInvalidS','tate,[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(APacka','ge);'#010+ ' ResolveFileNames(APackage,Defaults.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+ 'e','nd;'#010+ #010+ #010+ 'Function TBuildEngine.InstallPackageFiles(APAckage : TPackage; tt : TT'+ 'argetType; 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],D','efaults.CPU, Defaults.OS);'#010+ ' if (List.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+ ' E','xecuteCommands(APackage.Commands,caBeforeInstall);'#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(APackage);'#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:=IncludeTrailingP','athDelimiter(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:=IncludeTrailingPathDelimiter(Defaults.BinInstallDir);'#010+ ' InstallPackageFiles(APAckage,ttProgram,D);'#010+ ' // Done.'#010+ ' APackage.FTargetState:=tsInstalled;'#010+ ' DoAfterInstall(APackage);'#010+ ' Finally'#010+ ' If (APackage.Director','y<>'#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(APac','kage);'#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.Di','rectory<>'#039#039') then'#010+ ' EnterDir(APackage.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+ ' //get 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+ ' ResolveFileNa','mes(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+ ' Log(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+ ' Finally'#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 Assign','ed(APackage.BeforeClean) then'#010+ ' APackage.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.Co','mmands,caAfterClean);'#010+ 'end;'#010+ #010+ #010+ 'procedure 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+ ' List:=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+ ' DoAfterCl','ean(Apackage);'#010+ ' Finally'#010+ ' If (APackage.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(vlIn','fo, Format(SInfoManifestPackage,[APackage.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+ 'beg','in'#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+ ' A','fterCompile(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.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 Ass','igned(BeforeArchive) then'#010+ ' BeforeArchive(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+ ' Afte','rArchive(Self);'#010+ 'end;'#010+ #010+ #010+ 'procedure TBuildEngine.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 : TP','ackage;'#010+ 'begin'#010+ ' If Assigned(BeforeClean) 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+ ' I','f Assigned(AfterClean) then'#010+ ' AfterClean(Self);'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TFPVersion'#010+ '***************************************************************','*****'+ '********}'#010+ #010+ 'function TFPVersion.GetAsString: 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) a','nd (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:=StrToIntDef(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 (AVa','lue='#039''#039') then'#010+ ' exit;'#010+ ' V:=AValue;'#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:=Micro-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:=Compar','eVersion(AVersion)=0;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TTarget'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'constructor T','Target.Create(ACollection: TCollection);'#010+ 'begin'#010+ ' inherited Create(ACollection);'#010+ ' FInstall:=True;'#010+ ' FCPUs:=AllCPUs;'#010+ ' FOSes:=AllOSes;'#010+ ' FUnitPath:=TConditionalStrings.Create(TConditionalString);'#010+ ' FIncludePath:=TConditionalStrings.Create(TC','onditionalString);'#010+ ' FObjectPath:=TConditionalStrings.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+ ' FreeAndNil(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.G','etUnitFileName: String;'#010+ 'begin'#010+ ' Result:=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.GetPr','ogramFileName(AOS : TOS): String;'#010+ 'begin'#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+ ' Re','sult:=GetUnitFileName'#010+ ' else'#010+ ' Result:=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:=ExtractFileNam','e(N);'#010+ ' inherited SetName(Copy(N,1,Length(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 no','t(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 + GetProgramFileName(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: TString','s; const APrefixU, AP'+ 'refixB: 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 (TargetTyp','e in [ttUnit,ttImplicitUnit,ttExampleUnit]) 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(APre','fixU + RSTFileName);'#010+ ' // Maybe add later ? 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 no','t(AOS in OSes) then'#010+ ' exit;'#010+ ' // Main 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=depIncl','ude) 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(Dest));'#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+ 'begi','n'#010+ ' Items[Index]:=AValue;'#010+ 'end;'#010+ #010+ #010+ 'Function 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:=A','ddCommand(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: TCo','mmandAt; const Cmd: String) : T'+ 'Command;'#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+ 'func','tion TCommands.AddCommand(At: TCommandAt; 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.DestFil','e:=Dest;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TConditionalString'#010+ '**********************************************************************'+ '******}'#010+ #010+ 'Constructor TConditio','nalString.Create;'#010+ 'begin'#010+ ' inherited Create;'#010+ 'end;'#010+ #010+ #010+ '{*********************************************************************'+ '*******'#010+ ' TConditionalStrings'#010+ '****************************************************************','****'+ '********}'#010+ #010+ 'Constructor TConditionalStrings.Create(AClass:TConditionalStringClass)'+ ';'#010+ 'begin'#010+ ' inherited Create;'#010+ ' FCSClass:=AClass;'#010+ 'end;'#010+ #010+ #010+ 'function TConditionalStrings.GetConditionalString(Index : Integer): TC'+ 'onditionalString;'#010+ 'begin'#010+ ' Resu','lt:=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) ',': TConditiona'+ 'lString;'#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+ 'Function TConditionalStrings.Add(Const Value : String;const OSes:TOSes'+ ') : TConditionalString;'#010+ 'begin'#010+ ' result:=Add(Value,AllCPUs,OSes);'#010+ 'end;'#010+ #010+ #010+ 'Function TConditionalStrings.Add(Const Value : String;const CPUs:TC','P'+ 'Us;const OSes:TOSes) : TConditionalString;'#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+ 'Destructo','r TDependency.Destroy;'#010+ 'begin'#010+ ' FreeAndNil(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+ ' Result:=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 : Strin','g) : 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) : TD'+ 'ependency;'#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,All','OSes);'#010+ 'end;'#010+ #010+ #010+ '{$ifdef cpu_only_overloads}'#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(Co','nst 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(Valu','e,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_o','verloads}'#010+ 'Function TDependencies.AddInclude(Const Value : String;const CPUs:TCPU'+ 's) : 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;cons','t OSes:TO'+ 'Ses) : 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 E','xtractFileExt(N)='#039#039' then'#010+ ' ChangeFileExt(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: T','Component);'#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+ ' inherited 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+ ' Flist.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.IndexOf(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:=TFunc','tionItem(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:=Re','sult+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+ 'Va','r'#010+ ' I : Integer;'#010+ 'begin'#010+ ' I:=0;'#010+ ' While I