|
@@ -203,6 +203,7 @@ Const
|
|
|
AllMessages = [vlError,vlWarning,vlCommand,vlInfo];
|
|
|
|
|
|
Type
|
|
|
+ TTargets = Class;
|
|
|
{ TNamedItem }
|
|
|
|
|
|
TNamedItem = Class(TCollectionItem)
|
|
@@ -218,10 +219,14 @@ Type
|
|
|
TNamedCollection = Class(TCollection)
|
|
|
private
|
|
|
FUniqueNames: Boolean;
|
|
|
+ private
|
|
|
+ function GetItem(Index: Integer): TNamedItem;
|
|
|
+ procedure SetItem(Index: Integer; AValue: TNamedItem);
|
|
|
Public
|
|
|
Function IndexOfName(const AName : String) : Integer;
|
|
|
Function ItemByName(const AName : String) : TNamedItem;
|
|
|
Property UniqueNames : Boolean Read FUniqueNames;
|
|
|
+ property Items[Index: Integer]: TNamedItem read GetItem write SetItem;
|
|
|
end;
|
|
|
|
|
|
{ TNamedItemList }
|
|
@@ -392,8 +397,11 @@ Type
|
|
|
{ TPackageDictionary }
|
|
|
|
|
|
TPackageDictionary = Class(TDictionary)
|
|
|
+ private
|
|
|
+ FMasterDictionary: TDictionary;
|
|
|
Public
|
|
|
Function GetValue(const AName,Args : String) : String; override;
|
|
|
+ property MasterDictionary: TDictionary read FMasterDictionary write FMasterDictionary;
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -419,6 +427,45 @@ Type
|
|
|
Property RequireChecksum : Cardinal Read FRequireChecksum Write FRequireChecksum;
|
|
|
end;
|
|
|
|
|
|
+ { TPackageVariant }
|
|
|
+
|
|
|
+ TPackageVariant = class(TNamedItem)
|
|
|
+ private
|
|
|
+ FOptions: TStrings;
|
|
|
+ FTargets: TTargets;
|
|
|
+ public
|
|
|
+ constructor Create(ACollection: TCollection); override;
|
|
|
+ destructor Destroy; override;
|
|
|
+ property Options: TStrings read FOptions;
|
|
|
+ property Targets: TTargets read FTargets;
|
|
|
+ end;
|
|
|
+
|
|
|
+ { TPackageVariants }
|
|
|
+
|
|
|
+ TPackageVariants = class(TNamedCollection)
|
|
|
+ private
|
|
|
+ FActivePackageVariantName: string;
|
|
|
+ FDefaultPackageVariantName: string;
|
|
|
+ FIsInheritable: boolean;
|
|
|
+ FName: string;
|
|
|
+ FOwner: TPersistent;
|
|
|
+ function GetActivePackageVariant: TPackageVariant;
|
|
|
+ function GetDefaultPackageVariant: TPackageVariant;
|
|
|
+ procedure SetActivePackageVariantName(AValue: string);
|
|
|
+ procedure SetDefaultPackageVariantName(AValue: string);
|
|
|
+ protected
|
|
|
+ function GetOwner: TPersistent; override;
|
|
|
+ public
|
|
|
+ function Add(AName: String): TPackageVariant; overload; virtual;
|
|
|
+ property Name: string read FName write FName;
|
|
|
+ property DefaultPackageVariant: TPackageVariant read GetDefaultPackageVariant;
|
|
|
+ property ActivePackageVariant: TPackageVariant read GetActivePackageVariant;
|
|
|
+ property DefaultPackageVariantName: string read FDefaultPackageVariantName write SetDefaultPackageVariantName;
|
|
|
+ property ActivePackageVariantName: string read FActivePackageVariantName write SetActivePackageVariantName;
|
|
|
+ property IsInheritable: boolean read FIsInheritable;
|
|
|
+ end;
|
|
|
+
|
|
|
+
|
|
|
TDependencies = Class(TConditionalStrings)
|
|
|
function GetDependency(Index : Integer): TDependency;
|
|
|
procedure SetDependency(Index : Integer; const AValue: TDependency);
|
|
@@ -484,6 +531,7 @@ Type
|
|
|
Public
|
|
|
Constructor Create(ACollection : TCollection); override;
|
|
|
Destructor Destroy; override;
|
|
|
+ procedure AssignTo(Dest: TPersistent); override;
|
|
|
Function GetOutputFileName (AOs : TOS) : String; Virtual;
|
|
|
Function HaveOptions : Boolean;
|
|
|
procedure SetName(const AValue: String);override;
|
|
@@ -654,6 +702,8 @@ Type
|
|
|
FDescriptionFile : String;
|
|
|
FDescription : String;
|
|
|
FInstalledChecksum : Cardinal;
|
|
|
+ FUnitsOutputDir: String;
|
|
|
+ FPackageUnitInstallDir: String;
|
|
|
// Cached directory of installed packages
|
|
|
FUnitDir : String;
|
|
|
// Used by buildunits
|
|
@@ -665,6 +715,7 @@ Type
|
|
|
FDictionary : TDictionary;
|
|
|
// Is set when all sourcefiles are found
|
|
|
FAllFilesResolved: boolean;
|
|
|
+ FPackageVariants: TFPList;
|
|
|
Function GetDescription : string;
|
|
|
function GetDictionary: TDictionary;
|
|
|
Function GetFileName : string;
|
|
@@ -683,6 +734,12 @@ Type
|
|
|
destructor destroy; override;
|
|
|
Function HaveOptions : Boolean;
|
|
|
Function GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
|
|
|
+ Function GetUnitConfigOutputDir(ACPU:TCPU; AOS : TOS):String;
|
|
|
+ Procedure InheritPackageVariantsFromDependency(ADependencyPackage: TPackage);
|
|
|
+ Function GetPackageVariantsByName(AName: string): TPackageVariants;
|
|
|
+ Procedure SetUnitsOutputDir(AValue: string);
|
|
|
+ Function GetPackageUnitInstallDir(ACPU:TCPU; AOS : TOS):String;
|
|
|
+ Procedure SetPackageUnitInstallDir(AValue: string);
|
|
|
Function GetBinOutputDir(ACPU:TCPU; AOS : TOS) : String;
|
|
|
Procedure GetCleanFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
|
|
|
procedure GetInstallFiles(List: TStrings;Types : TTargetTypes;ACPU:TCPU; AOS : TOS); virtual;
|
|
@@ -690,6 +747,9 @@ Type
|
|
|
Procedure GetArchiveFiles(List : TStrings; ACPU:TCPU; AOS : TOS); virtual;
|
|
|
Procedure GetArchiveSourceFiles(List : TStrings); virtual;
|
|
|
Procedure GetManifest(Manifest : TStrings);
|
|
|
+ function AddPackageVariant(AName: string; AIsInheritable: boolean): TPackageVariants;
|
|
|
+ procedure ApplyPackageVariantToCompilerOptions(ACompilerOptions: tstrings);
|
|
|
+ procedure SetDefaultPackageVariant;
|
|
|
Property Version : String Read GetVersion Write SetVersion;
|
|
|
Property FileName : String Read GetFileName Write FFileName;
|
|
|
Property HomepageURL : String Read FHomepageURL Write FHomepageURL;
|
|
@@ -936,7 +996,7 @@ Type
|
|
|
Procedure InstallUnitConfigFile(APAckage : TPackage; Const Dest : String);
|
|
|
Function InstallPackageSourceFiles(APAckage : TPackage; stt : TSourceTypes; ttt : TTargetTypes; Const Dest : String):Boolean;
|
|
|
Function FileNewer(const Src,Dest : String) : Boolean;
|
|
|
- Procedure LogSearchPath(const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
|
|
|
+ Procedure LogSearchPath(APackage: TPackage;const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
|
|
|
Function FindFileInPath(APackage: TPackage; Path:TConditionalStrings; AFileName:String; var FoundPath:String;ACPU:TCPU;AOS:TOS):Boolean;
|
|
|
|
|
|
procedure GetDirectoriesFromFilelist(const AFileList, ADirectoryList: TStringList);
|
|
@@ -1036,6 +1096,7 @@ Type
|
|
|
FListMode : Boolean;
|
|
|
FLogLevels : TVerboseLevels;
|
|
|
FFPMakeOptionsString: string;
|
|
|
+ FPackageVariantSettings: TStrings;
|
|
|
Protected
|
|
|
Procedure Log(Level : TVerboseLevel; Const Msg : String);
|
|
|
Procedure CreatePackages; virtual;
|
|
@@ -1123,6 +1184,7 @@ Type
|
|
|
|
|
|
TInstallerClass = Class of TCustomInstaller;
|
|
|
TDictionaryClass = Class of TDictionary;
|
|
|
+ TPackageDictionaryClass = Class of TPackageDictionary;
|
|
|
|
|
|
Type
|
|
|
TArchiveEvent = Procedure (Const AFileName : String; List : TStrings) of Object;
|
|
@@ -1130,7 +1192,7 @@ Type
|
|
|
|
|
|
Var
|
|
|
DictionaryClass : TDictionaryClass = TDictionary;
|
|
|
- PackageDictionaryClass : TDictionaryClass = TPackageDictionary;
|
|
|
+ PackageDictionaryClass : TPackageDictionaryClass = TPackageDictionary;
|
|
|
OnArchiveFiles : TArchiveEvent = Nil;
|
|
|
ArchiveFilesProc : TArchiveProc = Nil;
|
|
|
|
|
@@ -1220,6 +1282,7 @@ ResourceString
|
|
|
SErrInvalidState = 'Invalid state for target %s';
|
|
|
SErrCouldNotCompile = 'Could not compile target %s from package %s';
|
|
|
SErrUnsupportedBuildmode = 'Package does not support this buildmode';
|
|
|
+ SErrBuildOptNotExist = 'There are no build options with the name "%s"';
|
|
|
|
|
|
SWarnCircularTargetDependency = 'Warning: Circular dependency detected when compiling target %s with target %s';
|
|
|
SWarnCircularPackageDependency = 'Warning: Circular dependency detected when compiling package %s with package %s';
|
|
@@ -1361,6 +1424,7 @@ Const
|
|
|
KeyAddIn = 'FPMakeAddIn';
|
|
|
KeySourcePath = 'SourcePath';
|
|
|
KeyFPMakeOptions = 'FPMakeOptions';
|
|
|
+ KeyPackageVar = 'PackageVariant_';
|
|
|
|
|
|
{****************************************************************************
|
|
|
Helpers
|
|
@@ -1837,15 +1901,16 @@ begin
|
|
|
end;
|
|
|
|
|
|
|
|
|
-function AddConditionalStrings(Dest : TStrings; Src : TConditionalStrings;ACPU:TCPU;AOS:TOS; Const APrefix : String='') : Integer ;
|
|
|
+function AddConditionalStrings(APackage: TPackage; Dest : TStrings; Src : TConditionalStrings;ACPU:TCPU;AOS:TOS; Const APrefix : String='') : Integer ;
|
|
|
Var
|
|
|
I : Integer;
|
|
|
C : TConditionalString;
|
|
|
- D : TDictionary;
|
|
|
+ D : TPackageDictionary;
|
|
|
S : String;
|
|
|
begin
|
|
|
Result:=0;
|
|
|
D := PackageDictionaryClass.Create(nil);
|
|
|
+ D.MasterDictionary := APackage.Dictionary;
|
|
|
try
|
|
|
D.AddVariable('CPU',CPUToString(ACPU));
|
|
|
D.AddVariable('OS',OSToString(AOS));
|
|
@@ -2097,6 +2162,61 @@ begin
|
|
|
Move(Buf,Result[1],Count);
|
|
|
end;
|
|
|
|
|
|
+constructor TPackageVariant.Create(ACollection: TCollection);
|
|
|
+begin
|
|
|
+ inherited Create(ACollection);
|
|
|
+ FTargets := TTargets.Create(TTarget);
|
|
|
+ FOptions := TStringList.Create;
|
|
|
+end;
|
|
|
+
|
|
|
+destructor TPackageVariant.Destroy;
|
|
|
+begin
|
|
|
+ FOptions.Free;
|
|
|
+ FTargets.Free;
|
|
|
+ inherited Destroy;
|
|
|
+end;
|
|
|
+
|
|
|
+{ TPackageVariants }
|
|
|
+
|
|
|
+procedure TPackageVariants.SetDefaultPackageVariantName(AValue: string);
|
|
|
+begin
|
|
|
+ if FDefaultPackageVariantName=AValue then Exit;
|
|
|
+ if not assigned(ItemByName(avalue)) then
|
|
|
+ raise exception.CreateFmt(SErrBuildOptNotExist,[AValue]);
|
|
|
+ FDefaultPackageVariantName:=AValue;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackageVariants.GetOwner: TPersistent;
|
|
|
+begin
|
|
|
+ Result:=FOwner;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackageVariants.GetActivePackageVariant: TPackageVariant;
|
|
|
+begin
|
|
|
+ result := ItemByName(ActivePackageVariantName) as TPackageVariant;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackageVariants.GetDefaultPackageVariant: TPackageVariant;
|
|
|
+begin
|
|
|
+ result := ItemByName(DefaultPackageVariantName) as TPackageVariant;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackageVariants.SetActivePackageVariantName(AValue: string);
|
|
|
+begin
|
|
|
+ if FActivePackageVariantName=AValue then Exit;
|
|
|
+ if not assigned(ItemByName(avalue)) then
|
|
|
+ raise exception.CreateFmt(SErrBuildOptNotExist,[AValue]);
|
|
|
+ FActivePackageVariantName:=AValue;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackageVariants.Add(AName: String): TPackageVariant;
|
|
|
+begin
|
|
|
+ result := self.add as TPackageVariant;
|
|
|
+ result.Name := AName;
|
|
|
+ if FDefaultPackageVariantName='' then
|
|
|
+ FDefaultPackageVariantName:=AName;
|
|
|
+end;
|
|
|
+
|
|
|
{$endif HAS_UNIT_PROCESS}
|
|
|
|
|
|
{ TConditionalDestStrings }
|
|
@@ -2152,7 +2272,10 @@ begin
|
|
|
I:=Flist.IndexOf(AName);
|
|
|
If (I=-1) then
|
|
|
begin
|
|
|
- result := GlobalDictionary.GetValue(AName,Args);
|
|
|
+ if assigned(MasterDictionary) then
|
|
|
+ result := MasterDictionary.GetValue(AName,Args)
|
|
|
+ else
|
|
|
+ result := GlobalDictionary.GetValue(AName,Args);
|
|
|
Exit;
|
|
|
end;
|
|
|
O:=Flist.Objects[I];
|
|
@@ -2240,6 +2363,16 @@ end;
|
|
|
TNamedCollection
|
|
|
****************************************************************************}
|
|
|
|
|
|
+function TNamedCollection.GetItem(Index: Integer): TNamedItem;
|
|
|
+begin
|
|
|
+ result := TNamedItem(inherited getItem(index));
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TNamedCollection.SetItem(Index: Integer; AValue: TNamedItem);
|
|
|
+begin
|
|
|
+ inherited SetItem(Index, AValue);
|
|
|
+end;
|
|
|
+
|
|
|
function TNamedCollection.IndexOfName(const AName: String): Integer;
|
|
|
|
|
|
begin
|
|
@@ -2613,6 +2746,8 @@ begin
|
|
|
FExamplePath:=TConditionalStrings.Create(TConditionalString);
|
|
|
FTestPath:=TConditionalStrings.Create(TConditionalString);
|
|
|
FCommands:=TCommands.Create(TCommand);
|
|
|
+ FUnitsOutputDir:='units'+PathDelim+'$(target)'+PathDelim;
|
|
|
+ FPackageVariants:=TFPList.Create;
|
|
|
FCPUs:=AllCPUs;
|
|
|
FOSes:=AllOSes;
|
|
|
FInstalledChecksum:=$ffffffff;
|
|
@@ -2623,6 +2758,8 @@ end;
|
|
|
|
|
|
|
|
|
destructor TPackage.destroy;
|
|
|
+var
|
|
|
+ i: integer;
|
|
|
begin
|
|
|
FreeAndNil(FDictionary);
|
|
|
FreeAndNil(FDependencies);
|
|
@@ -2638,6 +2775,12 @@ begin
|
|
|
FreeAndNil(FTargets);
|
|
|
FreeAndNil(FVersion);
|
|
|
FreeAndNil(FOptions);
|
|
|
+ for i := 0 to FPackageVariants.Count-1 do
|
|
|
+ begin
|
|
|
+ if TPackageVariants(FPackageVariants.Items[i]).Owner=Self then
|
|
|
+ TPackageVariants(FPackageVariants.Items[i]).Free;
|
|
|
+ end;
|
|
|
+ FreeAndNil(FPackageVariants);
|
|
|
inherited destroy;
|
|
|
end;
|
|
|
|
|
@@ -2658,7 +2801,64 @@ end;
|
|
|
|
|
|
Function TPackage.GetUnitsOutputDir(ACPU:TCPU; AOS : TOS):String;
|
|
|
begin
|
|
|
- Result:='units'+PathDelim+MakeTargetString(ACPU,AOS);
|
|
|
+ result:=FixPath(Dictionary.Substitute(FUnitsOutputDir,['CPU',CPUToString(ACPU),'OS',OSToString(AOS),'target',MakeTargetString(ACPU,AOS)]));
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackage.GetUnitConfigOutputDir(ACPU: TCPU; AOS: TOS): String;
|
|
|
+begin
|
|
|
+ result:=FixPath(Dictionary.Substitute('units'+PathDelim+'$(target)'+PathDelim,['CPU',CPUToString(ACPU),'OS',OSToString(AOS),'target',MakeTargetString(ACPU,AOS)]));
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackage.InheritPackageVariantsFromDependency(ADependencyPackage: TPackage);
|
|
|
+var
|
|
|
+ i: integer;
|
|
|
+ APackageVariants: TPackageVariants;
|
|
|
+begin
|
|
|
+ for i := 0 to ADependencyPackage.FPackageVariants.Count-1 do
|
|
|
+ begin
|
|
|
+ APackageVariants := TPackageVariants(ADependencyPackage.FPackageVariants[i]);
|
|
|
+ if APackageVariants.IsInheritable then
|
|
|
+ begin
|
|
|
+ if not assigned(GetPackageVariantsByName(APackageVariants.Name)) then
|
|
|
+ begin
|
|
|
+ FPackageVariants.Add(APackageVariants);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackage.GetPackageVariantsByName(AName: string): TPackageVariants;
|
|
|
+var
|
|
|
+ i: Integer;
|
|
|
+begin
|
|
|
+ result := nil;
|
|
|
+ for i := 0 to FPackageVariants.Count-1 do
|
|
|
+ if SameText(TPackageVariants(FPackageVariants.Items[i]).Name, AName) then
|
|
|
+ begin
|
|
|
+ result := TPackageVariants(FPackageVariants.Items[i]);
|
|
|
+ break;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackage.SetUnitsOutputDir(AValue: string);
|
|
|
+begin
|
|
|
+ if AValue<>'' then
|
|
|
+ FUnitsOutputDir:=IncludeTrailingPathDelimiter(AValue)
|
|
|
+ else
|
|
|
+ FUnitsOutputDir:='';
|
|
|
+end;
|
|
|
+
|
|
|
+function TPackage.GetPackageUnitInstallDir(ACPU: TCPU; AOS: TOS): String;
|
|
|
+begin
|
|
|
+ result:=FixPath(Dictionary.Substitute(FPackageUnitInstallDir,['CPU',CPUToString(ACPU),'OS',OSToString(AOS),'target',MakeTargetString(ACPU,AOS)]));
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackage.SetPackageUnitInstallDir(AValue: string);
|
|
|
+begin
|
|
|
+ if AValue<>'' then
|
|
|
+ FPackageUnitInstallDir:=IncludeTrailingPathDelimiter(AValue)
|
|
|
+ else
|
|
|
+ FPackageUnitInstallDir:='';
|
|
|
end;
|
|
|
|
|
|
|
|
@@ -2675,7 +2875,7 @@ Var
|
|
|
begin
|
|
|
OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(ACPU,AOS));
|
|
|
OU:=IncludeTrailingPathDelimiter(GetUnitsOutputDir(ACPU,AOS));
|
|
|
- AddConditionalStrings(List,CleanFiles,ACPU,AOS);
|
|
|
+ AddConditionalStrings(Self, List,CleanFiles,ACPU,AOS);
|
|
|
For I:=0 to FTargets.Count-1 do
|
|
|
FTargets.TargetItems[I].GetCleanFiles(List, OU, OB, ACPU, AOS);
|
|
|
end;
|
|
@@ -2688,7 +2888,7 @@ Var
|
|
|
T : TTarget;
|
|
|
begin
|
|
|
if Types=[] then
|
|
|
- AddConditionalStrings(List,InstallFiles,ACPU,AOS)
|
|
|
+ AddConditionalStrings(Self, List,InstallFiles,ACPU,AOS)
|
|
|
else
|
|
|
begin
|
|
|
OB:=IncludeTrailingPathDelimiter(GetBinOutputDir(Defaults.CPU,Defaults.OS));
|
|
@@ -2900,6 +3100,49 @@ begin
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+function TPackage.AddPackageVariant(AName: string; AIsInheritable: boolean): TPackageVariants;
|
|
|
+begin
|
|
|
+ result := TPackageVariants.Create(TPackageVariant);
|
|
|
+ result.Name:=AName;
|
|
|
+ result.FIsInheritable:=AIsInheritable;
|
|
|
+ FPackageVariants.Add(result);
|
|
|
+ result.FOwner := Self;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackage.ApplyPackageVariantToCompilerOptions(ACompilerOptions: tstrings);
|
|
|
+var
|
|
|
+ i: integer;
|
|
|
+ PackageVariants: TPackageVariants;
|
|
|
+begin
|
|
|
+ for i := 0 to FPackageVariants.Count-1 do
|
|
|
+ begin
|
|
|
+ PackageVariants := TPackageVariants(FPackageVariants.Items[i]);
|
|
|
+ ACompilerOptions.AddStrings(PackageVariants.ActivePackageVariant.Options);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TPackage.SetDefaultPackageVariant;
|
|
|
+var
|
|
|
+ i,j: integer;
|
|
|
+ PackageVariants: TPackageVariants;
|
|
|
+begin
|
|
|
+ for i := 0 to FPackageVariants.Count-1 do
|
|
|
+ begin
|
|
|
+ PackageVariants := TPackageVariants(FPackageVariants.Items[i]);
|
|
|
+ if Installer.FPackageVariantSettings.Values[PackageVariants.Name]<>'' then
|
|
|
+ PackageVariants.ActivePackageVariantName:= Installer.FPackageVariantSettings.Values[PackageVariants.Name]
|
|
|
+ else
|
|
|
+ PackageVariants.ActivePackageVariantName:= PackageVariants.DefaultPackageVariantName;
|
|
|
+ Dictionary.AddVariable(PackageVariants.Name,PackageVariants.ActivePackageVariantName);
|
|
|
+ SetUnitsOutputDir(FUnitsOutputDir+'$('+PackageVariants.name+')');
|
|
|
+ SetPackageUnitInstallDir(FPackageUnitInstallDir+'$('+PackageVariants.Name+')');
|
|
|
+ // Do not add targets f the package is inerited
|
|
|
+ if PackageVariants.GetOwner=Self then
|
|
|
+ for j := 0 to PackageVariants.ActivePackageVariant.Targets.count -1 do
|
|
|
+ targets.add.assign(PackageVariants.ActivePackageVariant.Targets.items[j]);
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
|
|
|
procedure TPackage.LoadUnitConfigFromFile(Const AFileName: String);
|
|
|
var
|
|
@@ -2910,6 +3153,10 @@ var
|
|
|
DepChecksum : Cardinal;
|
|
|
DepName : String;
|
|
|
D : TDependency;
|
|
|
+ PackageVariantsStr: string;
|
|
|
+ PackageVarName: string;
|
|
|
+ pv: TPackageVariants;
|
|
|
+ AnIsInheritable: boolean;
|
|
|
begin
|
|
|
L:=TStringList.Create;
|
|
|
Try
|
|
@@ -2941,6 +3188,40 @@ begin
|
|
|
FreeAndNil(L2);
|
|
|
NeedLibC:=Upcase(Values[KeyNeedLibC])='Y';
|
|
|
IsFPMakeAddIn:=Upcase(Values[KeyAddIn])='Y';
|
|
|
+
|
|
|
+ i := 1;
|
|
|
+ repeat
|
|
|
+ PackageVariantsStr:=Values[KeyPackageVar+inttostr(i)];
|
|
|
+ if PackageVariantsStr<>'' then
|
|
|
+ begin
|
|
|
+ k := pos(':',PackageVariantsStr);
|
|
|
+ if k > 0 then
|
|
|
+ begin
|
|
|
+ PackageVarName:=copy(PackageVariantsStr,1,k-1);
|
|
|
+ if PackageVarName[Length(PackageVarName)]='*' then
|
|
|
+ begin
|
|
|
+ SetLength(PackageVarName,Length(PackageVarName)-1);
|
|
|
+ AnIsInheritable:=true;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ AnIsInheritable:=false;
|
|
|
+ PackageVariantsStr:=copy(PackageVariantsStr,k+1,length(PackageVariantsStr)-k);
|
|
|
+ pv := AddPackageVariant(PackageVarName, AnIsInheritable);
|
|
|
+
|
|
|
+ k := pos(',',PackageVariantsStr);
|
|
|
+ while k>0 do
|
|
|
+ begin
|
|
|
+ PackageVarName:=copy(PackageVariantsStr,1,k-1);
|
|
|
+ PackageVariantsStr:=copy(PackageVariantsStr,k+1,length(PackageVariantsStr)-k);
|
|
|
+ pv.Add(PackageVarName);
|
|
|
+ k := pos(',',PackageVariantsStr);
|
|
|
+ end;
|
|
|
+ pv.Add(PackageVariantsStr);
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ inc(i);
|
|
|
+ until PackageVariantsStr='';
|
|
|
+
|
|
|
end;
|
|
|
Finally
|
|
|
L.Free;
|
|
@@ -2950,9 +3231,11 @@ end;
|
|
|
procedure TPackage.SaveUnitConfigToStringList(const AStringList: TStrings; ACPU: TCPU; AOS: TOS);
|
|
|
Var
|
|
|
Deps : String;
|
|
|
- i : integer;
|
|
|
+ i,j : integer;
|
|
|
D : TDependency;
|
|
|
p : TPackage;
|
|
|
+ PackageVariants : TPackageVariants;
|
|
|
+ PackageVariantsStr: string;
|
|
|
begin
|
|
|
with AStringList do
|
|
|
begin
|
|
@@ -2988,6 +3271,18 @@ begin
|
|
|
Values[KeyAddIn]:='Y'
|
|
|
else
|
|
|
Values[KeyAddIn]:='N';
|
|
|
+ for i := 0 to FPackageVariants.Count-1 do
|
|
|
+ begin
|
|
|
+ PackageVariants := TPackageVariants(FPackageVariants.Items[i]);
|
|
|
+ PackageVariantsStr:=PackageVariants.Name;
|
|
|
+ if PackageVariants.IsInheritable then
|
|
|
+ PackageVariantsStr:=PackageVariantsStr+'*';
|
|
|
+ PackageVariantsStr := PackageVariantsStr +':'+PackageVariants.DefaultPackageVariantName;
|
|
|
+ for j := 0 to PackageVariants.Count-1 do
|
|
|
+ if not sametext(PackageVariants.Items[j].Name, PackageVariants.DefaultPackageVariantName) then
|
|
|
+ PackageVariantsStr:=PackageVariantsStr+','+PackageVariants.Items[j].Name;
|
|
|
+ values[KeyPackageVar+inttostr(i+1)] := PackageVariantsStr;
|
|
|
+ end;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
@@ -3522,6 +3817,7 @@ end;
|
|
|
|
|
|
constructor TCustomInstaller.Create(AOwner: TComponent);
|
|
|
begin
|
|
|
+ FPackageVariantSettings := TStringList.Create;
|
|
|
GlobalDictionary:=DictionaryClass.Create(Nil);
|
|
|
AnalyzeOptions;
|
|
|
GlobalDictionary.AddVariable('BaseInstallDir',Defaults.BaseInstallDir);
|
|
@@ -3537,6 +3833,7 @@ begin
|
|
|
FreePackages;
|
|
|
FreeAndNil(Defaults);
|
|
|
FreeAndNil(GlobalDictionary);
|
|
|
+ FreeAndNil(FPackageVariantSettings);
|
|
|
inherited destroy;
|
|
|
end;
|
|
|
|
|
@@ -3605,6 +3902,28 @@ procedure TCustomInstaller.AnalyzeOptions;
|
|
|
if AddToOptionString and Result then FFPMakeOptionsString := FFPMakeOptionsString+' '+O;
|
|
|
end;
|
|
|
|
|
|
+ Function CheckBuildOptionSetValue(Index: Integer): boolean;
|
|
|
+ var
|
|
|
+ O : String;
|
|
|
+ BuildModeName: string;
|
|
|
+ P: integer;
|
|
|
+ begin
|
|
|
+ O:=Paramstr(Index);
|
|
|
+ result := O[1]='+';
|
|
|
+ if result then
|
|
|
+ begin
|
|
|
+ P:=Pos('=',Paramstr(Index));
|
|
|
+ If (P=0) then
|
|
|
+ Error(SErrNeedArgument,[Index,O])
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ BuildModeName:=copy(o,2,P-2);
|
|
|
+ Delete(O,1,P);
|
|
|
+ FPackageVariantSettings.Values[BuildModeName] := O;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
Function CheckCustomOption(Index : Integer; out CustOptName: string): Boolean;
|
|
|
var
|
|
|
O : String;
|
|
@@ -3760,7 +4079,7 @@ begin
|
|
|
CustomFpMakeCommandlineValues := TStringList.Create;
|
|
|
CustomFpMakeCommandlineValues.Values[CustOptName]:=OptionArg(I)
|
|
|
end
|
|
|
- else if not Defaults.IgnoreInvalidOptions then
|
|
|
+ else if (not CheckBuildOptionSetValue(I)) and (not Defaults.IgnoreInvalidOptions) then
|
|
|
begin
|
|
|
Usage(SErrInValidArgument,[I,ParamStr(I)]);
|
|
|
end;
|
|
@@ -4434,7 +4753,7 @@ begin
|
|
|
end;
|
|
|
|
|
|
|
|
|
-Procedure TBuildEngine.LogSearchPath(const ASearchPathName:string;Path:TConditionalStrings; ACPU:TCPU;AOS:TOS);
|
|
|
+procedure TBuildEngine.LogSearchPath(APackage: TPackage; const ASearchPathName: string; Path: TConditionalStrings; ACPU: TCPU; AOS: TOS);
|
|
|
var
|
|
|
S : String;
|
|
|
I : Integer;
|
|
@@ -4448,7 +4767,7 @@ begin
|
|
|
begin
|
|
|
if S<>'' then
|
|
|
S:=S+PathSeparator;
|
|
|
- S:=S+GlobalDictionary.ReplaceStrings(C.Value)
|
|
|
+ S:=S+APackage.Dictionary.ReplaceStrings(C.Value)
|
|
|
end;
|
|
|
end;
|
|
|
if S<>'' then
|
|
@@ -4495,7 +4814,7 @@ Procedure TBuildEngine.ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;D
|
|
|
var
|
|
|
SD,SF : String;
|
|
|
begin
|
|
|
- LogSearchPath('package source',APackage.SourcePath,ACPU,AOS);
|
|
|
+ LogSearchPath(APackage,'package source',APackage.SourcePath,ACPU,AOS);
|
|
|
SD:=APackage.Dictionary.ReplaceStrings(T.Directory);
|
|
|
SF:=APackage.Dictionary.ReplaceStrings(T.SourceFileName);
|
|
|
if SD='' then
|
|
@@ -4520,8 +4839,8 @@ Procedure TBuildEngine.ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;D
|
|
|
D : TDependency;
|
|
|
j : integer;
|
|
|
begin
|
|
|
- LogSearchPath('target include',T.IncludePath,ACPU,AOS);
|
|
|
- LogSearchPath('package include',APackage.IncludePath,ACPU,AOS);
|
|
|
+ LogSearchPath(APackage,'target include',T.IncludePath,ACPU,AOS);
|
|
|
+ LogSearchPath(APackage,'package include',APackage.IncludePath,ACPU,AOS);
|
|
|
for j:=0 to T.Dependencies.Count-1 do
|
|
|
begin
|
|
|
D:=T.Dependencies[j];
|
|
@@ -4565,7 +4884,7 @@ Procedure TBuildEngine.ResolveFileNames(APackage : TPackage; ACPU:TCPU;AOS:TOS;D
|
|
|
var
|
|
|
SD,SF : String;
|
|
|
begin
|
|
|
- LogSearchPath('package example',APackage.ExamplePath,ACPU,AOS);
|
|
|
+ LogSearchPath(APackage,'package example',APackage.ExamplePath,ACPU,AOS);
|
|
|
SD:=APackage.Dictionary.ReplaceStrings(T.Directory);
|
|
|
SF:=APackage.Dictionary.ReplaceStrings(T.SourceFileName);
|
|
|
if SD='' then
|
|
@@ -4655,13 +4974,13 @@ begin
|
|
|
if (APackage.UnitDir='') and
|
|
|
(Defaults.LocalUnitDir<>'') then
|
|
|
begin
|
|
|
- APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.LocalUnitDir)+APackage.Name;
|
|
|
+ APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.LocalUnitDir)+APackage.Name+PathDelim+APackage.GetPackageUnitInstallDir(defaults.CPU, Defaults.OS);
|
|
|
if not SysDirectoryExists(APackage.UnitDir) then
|
|
|
APackage.UnitDir:='';
|
|
|
end;
|
|
|
if APackage.UnitDir='' then
|
|
|
begin
|
|
|
- APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.GlobalUnitDir)+APackage.Name;
|
|
|
+ APackage.UnitDir:=IncludeTrailingPathDelimiter(Defaults.GlobalUnitDir)+APackage.Name+PathDelim+APackage.GetPackageUnitInstallDir(defaults.CPU, Defaults.OS);
|
|
|
if not SysDirectoryExists(APackage.UnitDir) then
|
|
|
APackage.UnitDir:=DirNotFound;
|
|
|
end;
|
|
@@ -4796,8 +5115,8 @@ begin
|
|
|
// Object Path
|
|
|
L:=TUnsortedDuplicatesStringList.Create;
|
|
|
L.Duplicates:=dupIgnore;
|
|
|
- AddConditionalStrings(L,APackage.ObjectPath,Defaults.CPU,Defaults.OS);
|
|
|
- AddConditionalStrings(L,ATarget.ObjectPath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,APackage.ObjectPath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,ATarget.ObjectPath,Defaults.CPU,Defaults.OS);
|
|
|
for i:=0 to L.Count-1 do
|
|
|
Args.Add('-Fo'+AddPathPrefix(APackage,L[i]));
|
|
|
FreeAndNil(L);
|
|
@@ -4806,8 +5125,8 @@ begin
|
|
|
L.Duplicates:=dupIgnore;
|
|
|
AddDependencyUnitPaths(L,APackage);
|
|
|
AddDependencyPaths(L,depUnit,ATarget);
|
|
|
- AddConditionalStrings(L,APackage.UnitPath,Defaults.CPU,Defaults.OS);
|
|
|
- AddConditionalStrings(L,ATarget.UnitPath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,APackage.UnitPath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,ATarget.UnitPath,Defaults.CPU,Defaults.OS);
|
|
|
for i:=0 to L.Count-1 do
|
|
|
Args.Add('-Fu'+AddPathPrefix(APackage,L[i]));
|
|
|
FreeAndNil(L);
|
|
@@ -4815,14 +5134,17 @@ begin
|
|
|
L:=TUnsortedDuplicatesStringList.Create;
|
|
|
L.Duplicates:=dupIgnore;
|
|
|
AddDependencyPaths(L,depInclude,ATarget);
|
|
|
- AddConditionalStrings(L,APackage.IncludePath,Defaults.CPU,Defaults.OS);
|
|
|
- AddConditionalStrings(L,ATarget.IncludePath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,APackage.IncludePath,Defaults.CPU,Defaults.OS);
|
|
|
+ AddConditionalStrings(APackage, L,ATarget.IncludePath,Defaults.CPU,Defaults.OS);
|
|
|
for i:=0 to L.Count-1 do
|
|
|
Args.Add('-Fi'+AddPathPrefix(APackage,L[i]));
|
|
|
FreeAndNil(L);
|
|
|
// Custom Options
|
|
|
If (Defaults.HaveOptions) then
|
|
|
Args.AddStrings(Defaults.Options);
|
|
|
+
|
|
|
+ APackage.ApplyPackageVariantToCompilerOptions(Args);
|
|
|
+
|
|
|
If (APackage.HaveOptions) then
|
|
|
Args.AddStrings(APackage.Options);
|
|
|
If (ATarget.HaveOptions) then
|
|
@@ -4964,8 +5286,12 @@ begin
|
|
|
if ATarget.TargetType in [ttExampleUnit, ttExampleProgram] then
|
|
|
Exit;
|
|
|
|
|
|
+ // Files which should not be compiled on this target can not trigger a compile.
|
|
|
+ if not TargetOK(ATarget) then
|
|
|
+ Exit;
|
|
|
+
|
|
|
// Check output file
|
|
|
- if not result and TargetOK(ATarget) then
|
|
|
+ if not result then
|
|
|
begin
|
|
|
if ATarget.TargetType in ProgramTargets then
|
|
|
OD:=APackage.GetBinOutputDir(Defaults.CPU,Defaults.OS)
|
|
@@ -5044,7 +5370,7 @@ begin
|
|
|
If Assigned(ATarget.BeforeCompile) then
|
|
|
ATarget.BeforeCompile(ATarget);
|
|
|
|
|
|
- if APackage.BuildMode=bmBuildUnit then
|
|
|
+ if (APackage.BuildMode=bmBuildUnit) and not (ATarget.TargetType in [ttProgram,ttExampleProgram]) then
|
|
|
begin
|
|
|
APackage.FBUTarget.Dependencies.AddUnit(ATarget.Name).FTargetFileName:=ATarget.TargetSourceFileName;
|
|
|
end
|
|
@@ -5218,6 +5544,8 @@ begin
|
|
|
begin
|
|
|
Log(vlDebug, Format(SDbgLoading, [F]));
|
|
|
Result.LoadUnitConfigFromFile(F);
|
|
|
+ result.SetDefaultPackageVariant;
|
|
|
+ result.UnitDir:=result.UnitDir+Result.GetPackageUnitInstallDir(Defaults.CPU, Defaults.OS);
|
|
|
end;
|
|
|
// Check recursive implicit dependencies
|
|
|
CompileDependencies(Result);
|
|
@@ -5263,6 +5591,7 @@ begin
|
|
|
(P.InstalledChecksum<>$ffffffff) and
|
|
|
(P.InstalledChecksum<>D.RequireChecksum) then
|
|
|
Log(vlDebug,SDbgPackageChecksumChanged,[P.Name]);
|
|
|
+ APackage.InheritPackageVariantsFromDependency(P);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
@@ -5304,6 +5633,7 @@ begin
|
|
|
(P.InstalledChecksum<>$ffffffff) and
|
|
|
(P.InstalledChecksum<>D.RequireChecksum) then
|
|
|
Log(vlDebug,SDbgPackageChecksumChanged,[P.Name]);
|
|
|
+ APackage.InheritPackageVariantsFromDependency(P);
|
|
|
end;
|
|
|
end;
|
|
|
end;
|
|
@@ -5494,7 +5824,7 @@ begin
|
|
|
|
|
|
if RegenerateUnitconfigFile then
|
|
|
begin
|
|
|
- UC:=IncludeTrailingPathDelimiter(AddPathPrefix(APackage,APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS)))+UnitConfigFile;
|
|
|
+ UC:=IncludeTrailingPathDelimiter(AddPathPrefix(APackage,APackage.GetUnitConfigOutputDir(Defaults.CPU,Defaults.OS)))+UnitConfigFile;
|
|
|
Log(vlInfo, Format(SDbgGenerating, [UC]));
|
|
|
APackage.SaveUnitConfigToFile(UC,Defaults.CPU,Defaults.OS);
|
|
|
end;
|
|
@@ -5573,6 +5903,8 @@ begin
|
|
|
result := False;
|
|
|
Exit;
|
|
|
end;
|
|
|
+ APackage.SetDefaultPackageVariant;
|
|
|
+
|
|
|
ResolveFileNames(APackage,Defaults.CPU,Defaults.OS,True,False);
|
|
|
If NeedsCompile(APackage) then
|
|
|
result := True
|
|
@@ -5609,7 +5941,7 @@ Var
|
|
|
begin
|
|
|
List:=TStringList.Create;
|
|
|
Try
|
|
|
- List.add(IncludeTrailingPathDelimiter(APackage.GetUnitsOutputDir(Defaults.CPU,Defaults.OS))+UnitConfigFile);
|
|
|
+ List.add(IncludeTrailingPathDelimiter(APackage.GetUnitConfigOutputDir(Defaults.CPU,Defaults.OS))+UnitConfigFile);
|
|
|
CmdCopyFiles(List,Dest);
|
|
|
Finally
|
|
|
List.Free;
|
|
@@ -5671,19 +6003,21 @@ begin
|
|
|
B:=false;
|
|
|
GlobalDictionary.AddVariable('PackageName',APackage.Name);
|
|
|
GlobalDictionary.AddVariable('unitinstalldir',Defaults.UnitInstallDir);
|
|
|
+ GlobalDictionary.AddVariable('packageunitinstalldir',APackage.GetPackageUnitInstallDir(Defaults.CPU,Defaults.OS));
|
|
|
|
|
|
D:=IncludeTrailingPathDelimiter(Defaults.BaseInstallDir);
|
|
|
// This is to install the TPackage.Installfiles, which are not related to any
|
|
|
// target
|
|
|
if InstallPackageFiles(APackage,[],D) then
|
|
|
B:=true;
|
|
|
- D:=IncludeTrailingPathDelimiter(Defaults.UnitInstallDir);
|
|
|
+ D:=IncludeTrailingPathDelimiter(Defaults.UnitInstallDir)+APackage.GetPackageUnitInstallDir(Defaults.CPU,Defaults.OS);
|
|
|
if InstallPackageFiles(APackage,[ttUnit, ttImplicitUnit],D) then
|
|
|
B:=true;
|
|
|
// By default do not install the examples. Maybe add an option for this later
|
|
|
//if InstallPackageFiles(APAckage,ttExampleUnit,D) then
|
|
|
// B:=true;
|
|
|
// Unit (dependency) configuration if there were units installed
|
|
|
+ D:=IncludeTrailingPathDelimiter(Defaults.UnitInstallDir);
|
|
|
if B then
|
|
|
InstallUnitConfigFile(APackage,D);
|
|
|
// Programs
|
|
@@ -6268,6 +6602,42 @@ begin
|
|
|
inherited Destroy;
|
|
|
end;
|
|
|
|
|
|
+procedure TTarget.AssignTo(Dest: TPersistent);
|
|
|
+var
|
|
|
+ DestTarget: TTarget;
|
|
|
+begin
|
|
|
+ if Dest is TTarget then
|
|
|
+ begin
|
|
|
+ DestTarget := TTarget(Dest);
|
|
|
+ DestTarget.Dependencies.Assign(Dependencies);
|
|
|
+ DestTarget.Commands.Assign(Commands);
|
|
|
+ DestTarget.FTargetState := FTargetState;
|
|
|
+ DestTarget.TargetType := TargetType;
|
|
|
+ DestTarget.CPUs := CPUs;
|
|
|
+ DestTarget.OSes := OSes;
|
|
|
+ DestTarget.Mode := Mode;
|
|
|
+ DestTarget.Options := Options;
|
|
|
+ DestTarget.Name := Name;
|
|
|
+ DestTarget.Extension:= Extension;
|
|
|
+ DestTarget.FPCTarget := FPCTarget;
|
|
|
+ DestTarget.FileType := FileType;
|
|
|
+ DestTarget.Directory := Directory;
|
|
|
+ DestTarget.ResourceStrings := ResourceStrings;
|
|
|
+ DestTarget.Install := Install;
|
|
|
+ DestTarget.FTargetSourceFileName := fTargetSourceFileName;
|
|
|
+ DestTarget.ObjectPath.Assign(ObjectPath);
|
|
|
+ DestTarget.UnitPath.Assign(UnitPath);
|
|
|
+ DestTarget.IncludePath.Assign(IncludePath);
|
|
|
+ DestTarget.FXML := FXML;
|
|
|
+ DestTarget.AfterCompile := AfterCompile;
|
|
|
+ DestTarget.BeforeCompile := BeforeCompile;
|
|
|
+ DestTarget.BeforeClean := BeforeCompile;
|
|
|
+ DestTarget.AfterClean := AfterClean;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ inherited AssignTo(Dest);
|
|
|
+end;
|
|
|
+
|
|
|
function TTarget.GetOptions: TStrings;
|
|
|
begin
|
|
|
If Foptions=Nil then
|