You've already forked lazarus-ccr
reading files based of the Xcode project
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4622 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -21,7 +21,9 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, MacroIntf,
|
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, MacroIntf,
|
||||||
iPhoneBundle, XMLConf, XcodeUtils, LazFileUtils, iphonesimctrl;
|
iPhoneBundle, XMLConf, XcodeUtils, PlistFile
|
||||||
|
, LazFileUtils, LazFilesUtils
|
||||||
|
, iphonesimctrl, xcodeproj;
|
||||||
|
|
||||||
const
|
const
|
||||||
DefaultResourceDir = 'Resources';
|
DefaultResourceDir = 'Resources';
|
||||||
@ -47,8 +49,8 @@ type
|
|||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
class function GetGroupCaption: String; override;
|
class function GetGroupCaption: String; override;
|
||||||
class function GetInstance: TAbstractIDEOptions; override;
|
class function GetInstance: TAbstractIDEOptions; override;
|
||||||
function Load: Boolean;
|
function Load(AProject: TLazProject = nil): Boolean;
|
||||||
function Save: Boolean;
|
function Save(AProject: TLazProject = nil): Boolean;
|
||||||
procedure Reset;
|
procedure Reset;
|
||||||
property isIPhoneApp: Boolean read fisIPhone write fisIPhone;
|
property isIPhoneApp: Boolean read fisIPhone write fisIPhone;
|
||||||
property SDK: String read fSDK write fSDK;
|
property SDK: String read fSDK write fSDK;
|
||||||
@ -137,6 +139,10 @@ var
|
|||||||
iPhoneEnvGroup : Integer;
|
iPhoneEnvGroup : Integer;
|
||||||
iPhonePrjGroup : Integer;
|
iPhonePrjGroup : Integer;
|
||||||
|
|
||||||
|
function LazToXcodeProjFile(AProject: TLazProject): string;
|
||||||
|
function LazToXcodePlistFile(AProject: TLazProject): string;
|
||||||
|
procedure ReadUploadFilesList(pbx: PBXProject; lst: TStrings);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -434,12 +440,66 @@ begin
|
|||||||
Result:=ProjOptions;
|
Result:=ProjOptions;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TiPhoneProjectOptions.Load: Boolean;
|
procedure ReadUploadFilesList(pbx: PBXProject; lst: TStrings);
|
||||||
|
var
|
||||||
|
trg : PBXNativeTarget;
|
||||||
|
i : Integer;
|
||||||
|
res : PBXResourcesBuildPhase;
|
||||||
|
bf : PBXBuildFile;
|
||||||
|
grp : PBXGroup;
|
||||||
|
p : string;
|
||||||
|
begin
|
||||||
|
if not Assigned(pbx) or not Assigned(lst) or not Assigned(pbx.targets)
|
||||||
|
or (pbx.targets.Count=0) then Exit;
|
||||||
|
trg:=PBXNativeTarget(pbx.targets.Items[0]);
|
||||||
|
|
||||||
|
res := PBXResourcesBuildPhase(TargetFindBuildPhase(trg, PBXResourcesBuildPhase));
|
||||||
|
if not Assigned(res) then begin
|
||||||
|
writeln('failed');
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
grp:=pbx.mainGroup.findGroup('Resources', true); // name must match to the target name!
|
||||||
|
|
||||||
|
for i:=0 to res.files.Count-1 do begin
|
||||||
|
bf:=PBXBuildFile(res.files[i]);
|
||||||
|
// making sure that the file is one of "Resources" files
|
||||||
|
p:=bf.fileRef.path;
|
||||||
|
if Assigned(grp.findFileRefByPathName(p)) then
|
||||||
|
lst.Add(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure FileNamesRelateiveToProject(st: TStrings);
|
||||||
|
var
|
||||||
|
i : integer;
|
||||||
|
s : string;
|
||||||
|
begin
|
||||||
|
//todo: it shouldn't really be hardcoded
|
||||||
|
if not Assigned(st) then Exit;
|
||||||
|
|
||||||
|
for i:=0 to st.Count-1 do begin
|
||||||
|
s:=st[i];
|
||||||
|
if s='' then Continue;
|
||||||
|
if Pos('../',s)=1 then
|
||||||
|
s:=Copy(s, 4, length(s));
|
||||||
|
st[i]:=s;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TiPhoneProjectOptions.Load(AProject: TLazProject): Boolean;
|
||||||
|
var
|
||||||
|
projname : string;
|
||||||
|
pbx : PBXProject;
|
||||||
|
st : TStringList;
|
||||||
begin
|
begin
|
||||||
Result:=True;
|
Result:=True;
|
||||||
with LazarusIDE.ActiveProject do begin
|
if not Assigned(AProject) then
|
||||||
|
AProject:=LazarusIDE.ActiveProject;
|
||||||
|
|
||||||
|
with AProject do begin
|
||||||
DataWritten:=CustomData.Contains(optisIphone);
|
DataWritten:=CustomData.Contains(optisIphone);
|
||||||
fisiPhone:=(DataWritten) and (CustomData.Values[optisIphone] = 'true');
|
fisiPhone:=(DataWritten) and (CustomData.Values[optisIphone] = 'true');
|
||||||
|
|
||||||
if CustomData.Contains(optSDK) then fSDK:=CustomData.Values[optSDK];
|
if CustomData.Contains(optSDK) then fSDK:=CustomData.Values[optSDK];
|
||||||
if CustomData.Contains(optAppID) then fAppID:=CustomData.Values[optAppID];
|
if CustomData.Contains(optAppID) then fAppID:=CustomData.Values[optAppID];
|
||||||
fSpaceName:=CustomData.Values[optSpaceName];
|
fSpaceName:=CustomData.Values[optSpaceName];
|
||||||
@ -448,11 +508,31 @@ begin
|
|||||||
else fResourceDir:=DefaultResourceDir;
|
else fResourceDir:=DefaultResourceDir;
|
||||||
if CustomData.Contains(optExcludeMask) then fExcludeMask:=CustomData.Values[optExcludeMask];
|
if CustomData.Contains(optExcludeMask) then fExcludeMask:=CustomData.Values[optExcludeMask];
|
||||||
if CustomData.Contains(optMainNib) then fMainNib:=CustomData.Values[optMainNib];
|
if CustomData.Contains(optMainNib) then fMainNib:=CustomData.Values[optMainNib];
|
||||||
if CustomData.Contains(optResFiles) then ResFiles.Text:=CustomData.Values[optResFiles];
|
|
||||||
|
projname:=LazToXcodeProjFile(AProject);
|
||||||
|
if FileExists(projname) then begin
|
||||||
|
ProjectLoadFromFile(projname, pbx);
|
||||||
|
if Assigned(pbx) then begin
|
||||||
|
st:=TStringList.Create;
|
||||||
|
try
|
||||||
|
ReadUploadFilesList(pbx, st);
|
||||||
|
FileNamesRelateiveToProject(st);
|
||||||
|
ResFiles.Assign(st);
|
||||||
|
finally
|
||||||
|
st.Free;
|
||||||
|
pbx.Free;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
//todo: this must go away. the only intention is to cleanup the old code
|
||||||
|
if CustomData.Contains(optResFiles) then begin
|
||||||
|
CustomData.Remove(optResFiles);
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TiPhoneProjectOptions.Save: Boolean;
|
function TiPhoneProjectOptions.Save(AProject: TLazProject): Boolean;
|
||||||
const
|
const
|
||||||
BoolStr : array[Boolean] of String = ('false', 'true');
|
BoolStr : array[Boolean] of String = ('false', 'true');
|
||||||
var
|
var
|
||||||
@ -487,6 +567,27 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function LazToXcodeProjFile(AProject: TLazProject): string;
|
||||||
|
begin
|
||||||
|
if not Assigned(AProject) then
|
||||||
|
AProject:=LazarusIDE.ActiveProject;
|
||||||
|
|
||||||
|
Result:=
|
||||||
|
IncludeTrailingPathDelimiter( ResolveProjectPath('xcode', AProject) )
|
||||||
|
+ ChangeFileExt( ExtractFileName(LazarusIDE.ActiveProject.MainFile.Filename),'.xcodeproj')
|
||||||
|
+ PathDelim
|
||||||
|
+'project.pbxproj';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function LazToXcodePlistFile(AProject: TLazProject): string;
|
||||||
|
begin
|
||||||
|
if not Assigned(AProject) then
|
||||||
|
AProject:=LazarusIDE.ActiveProject;
|
||||||
|
Result:=
|
||||||
|
IncludeTrailingPathDelimiter( ResolveProjectPath('xcode', AProject) )
|
||||||
|
+'info.plist';
|
||||||
|
end;
|
||||||
|
|
||||||
initialization
|
initialization
|
||||||
InitOptions;
|
InitOptions;
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
<Description Value="iPhone Development Lazarus extension"/>
|
<Description Value="iPhone Development Lazarus extension"/>
|
||||||
<License Value="LGPL"/>
|
<License Value="LGPL"/>
|
||||||
<Version Minor="8"/>
|
<Version Minor="8"/>
|
||||||
<Files Count="22">
|
<Files Count="20">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="ideext.pas"/>
|
<Filename Value="ideext.pas"/>
|
||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
@ -46,84 +46,76 @@
|
|||||||
<UnitName Value="iPhoneBundle"/>
|
<UnitName Value="iPhoneBundle"/>
|
||||||
</Item3>
|
</Item3>
|
||||||
<Item4>
|
<Item4>
|
||||||
<Filename Value="xcodeproject.pas"/>
|
|
||||||
<UnitName Value="XCodeProject"/>
|
|
||||||
</Item4>
|
|
||||||
<Item5>
|
|
||||||
<Filename Value="environment_iphone_options.pas"/>
|
<Filename Value="environment_iphone_options.pas"/>
|
||||||
<UnitName Value="environment_iphone_options"/>
|
<UnitName Value="environment_iphone_options"/>
|
||||||
</Item5>
|
</Item4>
|
||||||
<Item6>
|
<Item5>
|
||||||
<Filename Value="project_iphone_options.pas"/>
|
<Filename Value="project_iphone_options.pas"/>
|
||||||
<UnitName Value="project_iphone_options"/>
|
<UnitName Value="project_iphone_options"/>
|
||||||
</Item6>
|
</Item5>
|
||||||
<Item7>
|
<Item6>
|
||||||
<Filename Value="iphoneextoptions.pas"/>
|
<Filename Value="iphoneextoptions.pas"/>
|
||||||
<UnitName Value="iPhoneExtOptions"/>
|
<UnitName Value="iPhoneExtOptions"/>
|
||||||
</Item7>
|
</Item6>
|
||||||
<Item8>
|
<Item7>
|
||||||
<Filename Value="xcodetemplate.pas"/>
|
<Filename Value="xcodetemplate.pas"/>
|
||||||
<UnitName Value="xcodetemplate"/>
|
<UnitName Value="xcodetemplate"/>
|
||||||
|
</Item7>
|
||||||
|
<Item8>
|
||||||
|
<Filename Value="environment_iphone_options.lfm"/>
|
||||||
|
<Type Value="LFM"/>
|
||||||
</Item8>
|
</Item8>
|
||||||
<Item9>
|
<Item9>
|
||||||
<Filename Value="environment_iphone_options.lfm"/>
|
<Filename Value="project_iphone_options.lfm"/>
|
||||||
<Type Value="LFM"/>
|
<Type Value="LFM"/>
|
||||||
</Item9>
|
</Item9>
|
||||||
<Item10>
|
<Item10>
|
||||||
<Filename Value="project_iphone_options.lfm"/>
|
|
||||||
<Type Value="LFM"/>
|
|
||||||
</Item10>
|
|
||||||
<Item11>
|
|
||||||
<Filename Value="lazfilesutils.pas"/>
|
<Filename Value="lazfilesutils.pas"/>
|
||||||
<UnitName Value="LazFilesUtils"/>
|
<UnitName Value="LazFilesUtils"/>
|
||||||
</Item11>
|
</Item10>
|
||||||
<Item12>
|
<Item11>
|
||||||
<Filename Value="xcodeutils.pas"/>
|
<Filename Value="xcodeutils.pas"/>
|
||||||
<UnitName Value="XcodeUtils"/>
|
<UnitName Value="XcodeUtils"/>
|
||||||
</Item12>
|
</Item11>
|
||||||
<Item13>
|
<Item12>
|
||||||
<Filename Value="newxibdialog.pas"/>
|
<Filename Value="newxibdialog.pas"/>
|
||||||
<UnitName Value="newXibDialog"/>
|
<UnitName Value="newXibDialog"/>
|
||||||
</Item13>
|
</Item12>
|
||||||
<Item14>
|
<Item13>
|
||||||
<Filename Value="xibfile.pas"/>
|
<Filename Value="xibfile.pas"/>
|
||||||
<UnitName Value="xibfile"/>
|
<UnitName Value="xibfile"/>
|
||||||
</Item14>
|
</Item13>
|
||||||
<Item15>
|
<Item14>
|
||||||
<Filename Value="pbx/pbxcontainer.pas"/>
|
<Filename Value="pbx/pbxcontainer.pas"/>
|
||||||
<AddToUsesPkgSection Value="False"/>
|
<AddToUsesPkgSection Value="False"/>
|
||||||
<UnitName Value="pbxcontainer"/>
|
<UnitName Value="pbxcontainer"/>
|
||||||
</Item15>
|
</Item14>
|
||||||
<Item16>
|
<Item15>
|
||||||
<Filename Value="pbx/pbxfile.pas"/>
|
<Filename Value="pbx/pbxfile.pas"/>
|
||||||
<AddToUsesPkgSection Value="False"/>
|
<AddToUsesPkgSection Value="False"/>
|
||||||
<UnitName Value="pbxfile"/>
|
<UnitName Value="pbxfile"/>
|
||||||
</Item16>
|
</Item15>
|
||||||
<Item17>
|
<Item16>
|
||||||
<Filename Value="pbx/xcodeproj.pas"/>
|
<Filename Value="pbx/xcodeproj.pas"/>
|
||||||
<AddToUsesPkgSection Value="False"/>
|
<AddToUsesPkgSection Value="False"/>
|
||||||
<UnitName Value="xcodeproj"/>
|
<UnitName Value="xcodeproj"/>
|
||||||
</Item17>
|
</Item16>
|
||||||
<Item18>
|
<Item17>
|
||||||
<Filename Value="plistfile.pas"/>
|
<Filename Value="plistfile.pas"/>
|
||||||
<UnitName Value="PlistFile"/>
|
<UnitName Value="PlistFile"/>
|
||||||
</Item18>
|
</Item17>
|
||||||
<Item19>
|
<Item18>
|
||||||
<Filename Value="pbx/xcodeprojutils.pas"/>
|
<Filename Value="pbx/xcodeprojutils.pas"/>
|
||||||
<UnitName Value="xcodeprojutils"/>
|
<UnitName Value="xcodeprojutils"/>
|
||||||
</Item19>
|
</Item18>
|
||||||
<Item20>
|
<Item19>
|
||||||
<Filename Value="iphonesimctrl.pas"/>
|
<Filename Value="iphonesimctrl.pas"/>
|
||||||
<UnitName Value="iphonesimctrl"/>
|
<UnitName Value="iphonesimctrl"/>
|
||||||
</Item20>
|
</Item19>
|
||||||
<Item21>
|
<Item20>
|
||||||
<Filename Value="res/buildscript.sh"/>
|
|
||||||
<Type Value="Text"/>
|
|
||||||
</Item21>
|
|
||||||
<Item22>
|
|
||||||
<Filename Value="iphonelog_form.pas"/>
|
<Filename Value="iphonelog_form.pas"/>
|
||||||
<UnitName Value="iphonelog_form"/>
|
<UnitName Value="iphonelog_form"/>
|
||||||
</Item22>
|
</Item20>
|
||||||
</Files>
|
</Files>
|
||||||
<RequiredPkgs Count="3">
|
<RequiredPkgs Count="3">
|
||||||
<Item1>
|
<Item1>
|
||||||
|
@ -7,10 +7,10 @@ unit iphonelazext;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
ideext, iPhoneExtStr, iPhoneBundle, XCodeProject,
|
ideext, iPhoneExtStr, iPhoneBundle, environment_iphone_options,
|
||||||
environment_iphone_options, project_iphone_options, iPhoneExtOptions,
|
project_iphone_options, iPhoneExtOptions, xcodetemplate, LazFilesUtils,
|
||||||
xcodetemplate, LazFilesUtils, XcodeUtils, newXibDialog, xibfile, PlistFile,
|
XcodeUtils, newXibDialog, xibfile, PlistFile, xcodeprojutils, iphonesimctrl,
|
||||||
xcodeprojutils, iphonesimctrl, iphonelog_form, LazarusPackageIntf;
|
iphonelog_form, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -653,11 +653,16 @@ function ProjectLoadFromFile(const fn: string; var prj: PBXProject): Boolean;
|
|||||||
var
|
var
|
||||||
fs :TFileStream;
|
fs :TFileStream;
|
||||||
begin
|
begin
|
||||||
fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
|
|
||||||
try
|
try
|
||||||
Result:=ProjectLoadFromStream(fs, prj);
|
prj:=nil;
|
||||||
finally
|
fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone);
|
||||||
fs.Free;
|
try
|
||||||
|
Result:=ProjectLoadFromStream(fs, prj);
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
Result:=false;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1,949 +0,0 @@
|
|||||||
{
|
|
||||||
*****************************************************************************
|
|
||||||
* *
|
|
||||||
* This file is part of the iPhone Laz Extension *
|
|
||||||
* *
|
|
||||||
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
||||||
* for details about the copyright. *
|
|
||||||
* *
|
|
||||||
* This program is distributed in the hope that it will be useful, *
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
||||||
* *
|
|
||||||
*****************************************************************************
|
|
||||||
}
|
|
||||||
unit XCodeProject;
|
|
||||||
|
|
||||||
{$mode objfpc}{$H+}
|
|
||||||
// todo: re-write, using RTTI
|
|
||||||
{$TYPEINFO ON}
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
uses
|
|
||||||
contnrs, Classes, SysUtils, TypInfo;
|
|
||||||
|
|
||||||
const
|
|
||||||
UTF8Mark = '// !$*UTF8*$!';
|
|
||||||
|
|
||||||
FileType_AppWrapper = 'wrapper.application';
|
|
||||||
FileType_Bundle = FileType_AppWrapper;
|
|
||||||
FileType_PList = 'text.plist.xml';
|
|
||||||
// sourceTree = BUILT_PRODUCTS_DIR
|
|
||||||
|
|
||||||
type
|
|
||||||
TXCodeObjectID = string[24];
|
|
||||||
|
|
||||||
TStringValues = class(TStringList);
|
|
||||||
|
|
||||||
{ TXCodeObject }
|
|
||||||
TXCodeObject = class(TObject)
|
|
||||||
private
|
|
||||||
fOwner : TXCodeObject;
|
|
||||||
fChild : TFPList;
|
|
||||||
fValues : TStringList;
|
|
||||||
fID : TXCodeObjectID;
|
|
||||||
protected
|
|
||||||
procedure AddObject(const AName: String; AObject: TXCodeObject);
|
|
||||||
function GetChild(i: Integer): TXCodeObject;
|
|
||||||
function GetCount: Integer;
|
|
||||||
procedure Clear;
|
|
||||||
function GetValue(const AName: String): String;
|
|
||||||
procedure SetValue(const AName: String; const AValue: String);
|
|
||||||
public
|
|
||||||
class function isa: ShortString; virtual; abstract;
|
|
||||||
constructor Create;
|
|
||||||
destructor Destroy; override;
|
|
||||||
|
|
||||||
property Child[i: integer]: TXCodeObject read GetChild;
|
|
||||||
property ChildCount: Integer read GetCount;
|
|
||||||
property Owner: TXCodeObject read fOwner;
|
|
||||||
property ID: TXCodeObjectID read fID;
|
|
||||||
|
|
||||||
property StrValue[const AName: String]: String read GetValue write SetValue;
|
|
||||||
function GetChildObject(const AName: String): TXCodeObject;
|
|
||||||
function GetObjectArray(const AName: String): TFPObjectList;
|
|
||||||
function GetStringArray(const AName: String): TStringList;
|
|
||||||
function GetStringValues(const AName: String): TStringValues;
|
|
||||||
end;
|
|
||||||
TXCodeObjectClass = class of TXCodeObject;
|
|
||||||
|
|
||||||
{ TPBXFileReference }
|
|
||||||
|
|
||||||
TPBXFileReference = class(TXCodeObject)
|
|
||||||
private
|
|
||||||
function GetExplicitFileType: string;
|
|
||||||
function GetPath: String;
|
|
||||||
function GetSourceTree: String;
|
|
||||||
procedure SetExplicitFileType(const AValue: string);
|
|
||||||
procedure SetPath(const AValue: String);
|
|
||||||
procedure SetSourceTree(const AValue: String);
|
|
||||||
public
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
property explicitFileType: string read GetExplicitFileType write SetExplicitFileType;
|
|
||||||
property path : String read GetPath write SetPath;
|
|
||||||
property sourceTree: String read GetSourceTree write SetSourceTree;
|
|
||||||
end;
|
|
||||||
// 0A7E1DA610EAD478000D7855 /* iPhoneApp.app */ =
|
|
||||||
|
|
||||||
{isa = PBXFileReference;
|
|
||||||
explicitFileType = wrapper.application;
|
|
||||||
includeInIndex = 0;
|
|
||||||
path = iPhoneApp.app;
|
|
||||||
sourceTree = BUILT_PRODUCTS_DIR; }
|
|
||||||
|
|
||||||
{isa = PBXFileReference;
|
|
||||||
lastKnownFileType = text.plist.xml;
|
|
||||||
path = "iPhoneApp-Info.plist"; sourceTree = "<group>"; }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
TXCodeBuildPhase = class(TXCodeObject);
|
|
||||||
|
|
||||||
{ TPBXShellScriptBuildPhase }
|
|
||||||
|
|
||||||
TPBXShellScriptBuildPhase = class(TXCodeBuildPhase)
|
|
||||||
private
|
|
||||||
function GetBuildMask: Integer;
|
|
||||||
function GetShellPath: string;
|
|
||||||
function GetShellScript: String;
|
|
||||||
procedure SetBuildMask(const AValue: Integer);
|
|
||||||
procedure SetShellPath(const AValue: string);
|
|
||||||
procedure SetShellScript(const AValue: String);
|
|
||||||
public
|
|
||||||
constructor Create;
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
property BuildActionMask : Integer read GetBuildMask write SetBuildMask;
|
|
||||||
property ShellPath : string read GetShellPath write SetShellPath;
|
|
||||||
property ShellScript : String read GetShellScript write SetShellScript;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXBuildFile }
|
|
||||||
|
|
||||||
TPBXBuildFile = class(TXCodeObject)
|
|
||||||
public
|
|
||||||
fileRef : TPBXFileReference;
|
|
||||||
constructor Create;
|
|
||||||
destructor Destroy; override;
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCBuildConfiguration }
|
|
||||||
|
|
||||||
TXCBuildConfiguration = class(TXCodeObject)
|
|
||||||
private
|
|
||||||
function GetName: String;
|
|
||||||
procedure SetName(const AValue: String);
|
|
||||||
function GetBuildSettings: TStringValues;
|
|
||||||
public
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
constructor Create;
|
|
||||||
destructor Destroy; override;
|
|
||||||
property name: String read GetName write SetName;
|
|
||||||
property Settings: TStringValues read GetBuildSettings;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCConfigurationList }
|
|
||||||
|
|
||||||
TXCConfigurationList = class(TXCodeObject)
|
|
||||||
private
|
|
||||||
fConfigs : TFPObjectList;
|
|
||||||
protected
|
|
||||||
function GetConfig(i: integer): TXCBuildConfiguration;
|
|
||||||
function GetCount: Integer;
|
|
||||||
|
|
||||||
function GetName: string;
|
|
||||||
procedure SetName(const AValue: string);
|
|
||||||
function GetVisible: Boolean;
|
|
||||||
procedure SetVisible(AVisible: Boolean);
|
|
||||||
public
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
constructor Create;
|
|
||||||
destructor Destroy; override;
|
|
||||||
function AddList: TXCBuildConfiguration;
|
|
||||||
property Config[i: Integer] : TXCBuildConfiguration read GetConfig;
|
|
||||||
property ConfigCount: Integer read GetCount;
|
|
||||||
property defaultVisible: Boolean read GetVisible write SetVisible;
|
|
||||||
property defaulConfigName: string read GetName write SetName;
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ TPBXNativeTarget }
|
|
||||||
|
|
||||||
TPBXNativeTarget = class(TXCodeObject)
|
|
||||||
private
|
|
||||||
fConfigList : TXCConfigurationList;
|
|
||||||
fRef : TPBXFileReference;
|
|
||||||
function GetName: String;
|
|
||||||
function GetProductFile: TPBXFileReference;
|
|
||||||
function GetProductName: String;
|
|
||||||
function GetProductType: String;
|
|
||||||
procedure SetName(const AValue: String);
|
|
||||||
procedure SetProductName(const AValue: String);
|
|
||||||
procedure SetProductType(const AValue: String);
|
|
||||||
|
|
||||||
function GetConfigList: TXCConfigurationList;
|
|
||||||
public
|
|
||||||
constructor Create;
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
function AddBuildConfig: TXCBuildConfiguration;
|
|
||||||
function AddScriptPhase: TPBXShellScriptBuildPhase;
|
|
||||||
property name: String read GetName write SetName;
|
|
||||||
property productName: String read GetProductName write SetProductName;
|
|
||||||
property productType: String read GetProductType write SetProductType;
|
|
||||||
property productFile: TPBXFileReference read GetProductFile;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXProject }
|
|
||||||
|
|
||||||
TPBXProject = class(TXCodeObject)
|
|
||||||
private
|
|
||||||
fConfigList : TXCConfigurationList;
|
|
||||||
function GetDirPath: string;
|
|
||||||
function GetRoot: String;
|
|
||||||
procedure SetDirPath(const AValue: string);
|
|
||||||
procedure SetRoot(const AValue: String);
|
|
||||||
protected
|
|
||||||
function GetConfigList: TXCConfigurationList;
|
|
||||||
function GetTargets: TFPObjectList;
|
|
||||||
|
|
||||||
function GetVersion: String;
|
|
||||||
procedure SetVersion(const AVersion: string);
|
|
||||||
public
|
|
||||||
constructor Create;
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
function AddTarget: TPBXNativeTarget;
|
|
||||||
function AddBuildConfig: TXCBuildConfiguration;
|
|
||||||
property DirPath: string read GetDirPath write SetDirPath;
|
|
||||||
property Root: String read GetRoot write SetRoot;
|
|
||||||
property compatibilityVersion: String read GetVersion write SetVersion;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXGroup }
|
|
||||||
|
|
||||||
TPBXGroup = class(TXCodeObject)
|
|
||||||
protected
|
|
||||||
function GetPath: String;
|
|
||||||
procedure SetPath(const APath: String);
|
|
||||||
function GetSourceTree: String;
|
|
||||||
procedure SetSourceTree(const ATree: String);
|
|
||||||
public
|
|
||||||
class function isa: ShortString; override;
|
|
||||||
property Path: String read GetPath write SetPath;
|
|
||||||
property sourceTree: String read GetSourceTree write SetSourceTree;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure WritePBXProjFile(RootObject: TXCodeObject; Dst: TStream);
|
|
||||||
procedure WritePBXProjFile(RootObject: TXCodeObject; const FileName: String);
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
const
|
|
||||||
BoolVal : array[Boolean] of String = ('false', 'true');
|
|
||||||
|
|
||||||
function isQuotedStr(const s: string): Boolean;
|
|
||||||
begin
|
|
||||||
Result:=(length(s)>=2) and (s[1] = '"') and (s[length(s)]='"');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function QuotedStr(const s: string): String;
|
|
||||||
begin
|
|
||||||
if isQuotedStr(s) then Result:=s
|
|
||||||
else Result:='"'+s+'"';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function UnquoteStr(const s: string): String;
|
|
||||||
begin
|
|
||||||
if not isQuotedStr(s) then Result:=s
|
|
||||||
else Result:=Copy(s, 2, length(s)-2);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function GetBoolValue(xobj: TXCodeObject; const AName: String): boolean;
|
|
||||||
begin
|
|
||||||
Result:=xobj.StrValue[AName]=BoolVal[True];
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure SetBoolValue(xobj: TXCodeObject; const AName: String; AValue: Boolean);
|
|
||||||
begin
|
|
||||||
xobj.StrValue[AName]:=BoolVal[AValue];
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCConfigurationList }
|
|
||||||
|
|
||||||
function TXCConfigurationList.GetName: string;
|
|
||||||
begin
|
|
||||||
Result:=StrValue['defaultConfigurationName'];
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TXCConfigurationList.SetName(const AValue: string);
|
|
||||||
begin
|
|
||||||
StrValue['defaultConfigurationName']:=AValue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCConfigurationList.GetVisible: Boolean;
|
|
||||||
begin
|
|
||||||
Result:=GetBoolValue(Self, 'defaultConfigurationIsVisible');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TXCConfigurationList.SetVisible(AVisible: Boolean);
|
|
||||||
begin
|
|
||||||
SetBoolValue(Self, 'defaultConfigurationIsVisible', AVisible);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCConfigurationList.GetConfig(i: integer): TXCBuildConfiguration;
|
|
||||||
begin
|
|
||||||
Result:=TXCBuildConfiguration(fConfigs[i]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCConfigurationList.GetCount: Integer;
|
|
||||||
begin
|
|
||||||
Result:=fConfigs.Count;
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TXCConfigurationList.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='XCConfigurationList';
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TXCConfigurationList.Create;
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
fConfigs:=GetObjectArray('buildConfigurations');
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TXCConfigurationList.Destroy;
|
|
||||||
begin
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCConfigurationList.AddList: TXCBuildConfiguration;
|
|
||||||
begin
|
|
||||||
Result:=TXCBuildConfiguration.Create;
|
|
||||||
AddObject('', Result);
|
|
||||||
fConfigs.Add(Result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCBuildConfiguration }
|
|
||||||
|
|
||||||
constructor TXCBuildConfiguration.Create;
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
GetStringValues('buildSettings');
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TXCBuildConfiguration.Destroy;
|
|
||||||
begin
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCBuildConfiguration.GetName: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('name');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TXCBuildConfiguration.SetName(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('name', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCBuildConfiguration.getBuildSettings: TStringValues;
|
|
||||||
begin
|
|
||||||
Result:=GetStringValues('buildSettings');
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TXCBuildConfiguration.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='XCBuildConfiguration';
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXGroup }
|
|
||||||
|
|
||||||
function TPBXGroup.GetPath: String;
|
|
||||||
begin
|
|
||||||
Result:=StrValue['Path'];
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXGroup.SetPath(const APath: String);
|
|
||||||
begin
|
|
||||||
StrValue['Path']:=APath;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXGroup.GetSourceTree: String;
|
|
||||||
begin
|
|
||||||
Result:=StrValue['sourceTree'];
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXGroup.SetSourceTree(const ATree: String);
|
|
||||||
begin
|
|
||||||
StrValue['sourceTree']:=ATree;
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TPBXGroup.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXGroup';
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXFileReference }
|
|
||||||
|
|
||||||
class function TPBXFileReference.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXFileReference';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXFileReference.GetExplicitFileType: string;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('explicitFileType');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXFileReference.GetPath: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('path');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXFileReference.GetSourceTree: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('sourceTree');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXFileReference.SetExplicitFileType(const AValue: string);
|
|
||||||
begin
|
|
||||||
SetValue('explicitFileType', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXFileReference.SetPath(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('path', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXFileReference.SetSourceTree(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('sourceTree', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXBuildFile }
|
|
||||||
|
|
||||||
constructor TPBXBuildFile.Create;
|
|
||||||
begin
|
|
||||||
fileRef:=TPBXFileReference.Create;
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TPBXBuildFile.Destroy;
|
|
||||||
begin
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TPBXBuildFile.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXBuildFile';
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCodeObject }
|
|
||||||
|
|
||||||
procedure TXCodeObject.AddObject(const AName: String; AObject: TXCodeObject);
|
|
||||||
begin
|
|
||||||
AObject.fOwner:=Self;
|
|
||||||
fChild.Add(AObject);
|
|
||||||
if AName<>'' then
|
|
||||||
fValues.AddObject(AName, AObject);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetChild(i: Integer): TXCodeObject;
|
|
||||||
begin
|
|
||||||
Result:=TXCodeObject(fChild[i]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetCount: Integer;
|
|
||||||
begin
|
|
||||||
Result:=fChild.Count;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TXCodeObject.Clear;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
begin
|
|
||||||
for i:=0 to fValues.Count-1 do begin
|
|
||||||
if Assigned(fValues.Objects[i]) and not (fValues.Objects[i] is TXCodeObject) then
|
|
||||||
fValues.Objects[i].Free;
|
|
||||||
end;
|
|
||||||
fValues.Clear;
|
|
||||||
|
|
||||||
for i:=0 to fChild.Count-1 do
|
|
||||||
TObject(fChild[i]).Free;
|
|
||||||
fChild.Clear;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetValue(const AName: String): String;
|
|
||||||
begin
|
|
||||||
Result:=fValues.Values[AName];
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TXCodeObject.SetValue(const AName, AValue: String);
|
|
||||||
begin
|
|
||||||
fValues.Values[AName]:=Avalue;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TXCodeObject.Create;
|
|
||||||
var
|
|
||||||
q : Qword;
|
|
||||||
begin
|
|
||||||
inherited;
|
|
||||||
fChild:=TFPList.Create;
|
|
||||||
fValues:=TStringList.Create;
|
|
||||||
Q:=PtrUInt(Self);
|
|
||||||
fID:=hexStr(q, 24);
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TXCodeObject.Destroy;
|
|
||||||
begin
|
|
||||||
Clear;
|
|
||||||
fChild.Free;
|
|
||||||
fValues.Free;
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetChildObject(const AName: String): TXCodeObject;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
begin
|
|
||||||
Result:=nil;
|
|
||||||
i:=fValues.IndexOfName(AName);
|
|
||||||
if i>=0 then
|
|
||||||
if fValues.Objects[i] is TXCodeObject then
|
|
||||||
Result:=TXCodeObject(fValues.Objects[i]);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetObjectArray(const AName: String): TFPObjectList;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
begin
|
|
||||||
i:=fValues.IndexOfName(AName);
|
|
||||||
if i<0 then begin
|
|
||||||
Result:=TFPObjectList.Create(false);
|
|
||||||
fValues.AddObject(AName, Result);
|
|
||||||
end else begin
|
|
||||||
if not (fValues.Objects[i] is TFPObjectList) then
|
|
||||||
Result:=nil
|
|
||||||
else
|
|
||||||
Result:= TFPObjectList(fValues.Objects[i]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetStringArray(const AName: String): TStringList;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
begin
|
|
||||||
i:=fValues.IndexOfName(AName);
|
|
||||||
if i<0 then begin
|
|
||||||
Result:=TStringList.Create;
|
|
||||||
fValues.AddObject(AName, Result);
|
|
||||||
end else begin
|
|
||||||
if not (fValues.Objects[i] is TStringList) then
|
|
||||||
Result:=nil
|
|
||||||
else
|
|
||||||
Result:= TStringList(fValues.Objects[i]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TXCodeObject.GetStringValues(const AName: String): TStringValues;
|
|
||||||
var
|
|
||||||
i : integer;
|
|
||||||
begin
|
|
||||||
i:=fValues.IndexOfName(AName);
|
|
||||||
if i<0 then begin
|
|
||||||
Result:=TStringValues.Create;
|
|
||||||
fValues.Values[AName]:='?';
|
|
||||||
i:=fValues.IndexOfName(AName);
|
|
||||||
fValues.Objects[i]:=Result;
|
|
||||||
//i:=fValues.AddObject(AName + ' = ', Result);
|
|
||||||
end else begin
|
|
||||||
if not (fValues.Objects[i] is TStringValues) then
|
|
||||||
Result:=nil
|
|
||||||
else
|
|
||||||
Result:= TStringValues(fValues.Objects[i]);
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
type
|
|
||||||
|
|
||||||
{ TPBXWriter }
|
|
||||||
|
|
||||||
TPBXWriter = class(TObject)
|
|
||||||
private
|
|
||||||
fDst : TStream;
|
|
||||||
fPrefix : String;
|
|
||||||
fIndent : String;
|
|
||||||
protected
|
|
||||||
procedure WriteItems(data:TObject;arg:pointer);
|
|
||||||
public
|
|
||||||
constructor Create(Dst: TStream);
|
|
||||||
destructor Destroy; override;
|
|
||||||
procedure Indent;
|
|
||||||
procedure Unindent;
|
|
||||||
procedure WriteLn(const utf8: AnsiString);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXWriter }
|
|
||||||
|
|
||||||
procedure TPBXWriter.WriteItems(data: TObject; arg: pointer);
|
|
||||||
var
|
|
||||||
list : TFPList;
|
|
||||||
i : Integer;
|
|
||||||
j : Integer;
|
|
||||||
k : Integer;
|
|
||||||
xobj : TXCodeObject;
|
|
||||||
vobj : TObject;
|
|
||||||
sublist : TFPObjectList;
|
|
||||||
st : TStringList;
|
|
||||||
prefix : String;
|
|
||||||
begin
|
|
||||||
list:=TFPList(data);
|
|
||||||
if not Assigned(list) or (list.Count=0) then Exit;
|
|
||||||
|
|
||||||
for i:=0 to list.Count-1 do begin
|
|
||||||
xobj:=TXCodeObject(list[i]);
|
|
||||||
|
|
||||||
Self.WriteLn( xobj.ID + ' = {');
|
|
||||||
Self.Indent;
|
|
||||||
|
|
||||||
Self.Writeln('isa = ' + xobj.isa+';');
|
|
||||||
|
|
||||||
for j:=0 to xobj.fValues.Count - 1 do begin
|
|
||||||
vobj:=xobj.fValues.Objects[j];
|
|
||||||
if not Assigned(vobj) then begin
|
|
||||||
prefix:=xobj.fValues.Names[j] + ' = ';
|
|
||||||
Writeln(prefix + xobj.fValues.ValueFromIndex[j]+';')
|
|
||||||
end else begin
|
|
||||||
if vobj is TXCodeObject then begin
|
|
||||||
prefix:=xobj.fValues[j] + ' = ';
|
|
||||||
Writeln(prefix + TXCodeObject(vobj).ID+';')
|
|
||||||
end else if vobj is TStringValues then begin
|
|
||||||
st:=TStringValues(vobj);
|
|
||||||
prefix:=xobj.fValues.Names[j]+' = ';
|
|
||||||
Self.Writeln(prefix + ' {');
|
|
||||||
Self.Indent;
|
|
||||||
for k:=0 to st.Count-1 do
|
|
||||||
Self.WritelN(st.Names[k] + ' = ' + st.ValueFromIndex[k] + ';' );
|
|
||||||
Self.Unindent;
|
|
||||||
Self.Writeln('};')
|
|
||||||
end else if vobj is TStringList then begin
|
|
||||||
prefix:=xobj.fValues[j] + ' = ';
|
|
||||||
st:=TStringValues(vobj);
|
|
||||||
Self.Writeln(prefix + ' (');
|
|
||||||
Self.Indent;
|
|
||||||
for k:=0 to st.Count-1 do
|
|
||||||
Self.WritelN(' ' + st[k] + ',' );
|
|
||||||
Self.Unindent;
|
|
||||||
Self.Writeln(');')
|
|
||||||
end else if vobj is TFPObjectList then begin
|
|
||||||
prefix:=xobj.fValues[j] + ' = ';
|
|
||||||
sublist:=TFPObjectList(vobj);
|
|
||||||
Self.Writeln(prefix + '(');
|
|
||||||
Self.Indent;
|
|
||||||
for k:=0 to sublist.Count-1 do
|
|
||||||
Self.WritelN(TXCodeObject(sublist[k]).ID+',');
|
|
||||||
Self.Unindent;
|
|
||||||
Self.Writeln(');')
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
Self.Unindent;
|
|
||||||
Self.WritelN('};');
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TPBXWriter.Create(Dst: TStream);
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
fDst:=Dst;
|
|
||||||
fIndent:=#9;
|
|
||||||
end;
|
|
||||||
|
|
||||||
destructor TPBXWriter.Destroy;
|
|
||||||
begin
|
|
||||||
inherited Destroy;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXWriter.Indent;
|
|
||||||
begin
|
|
||||||
fPrefix:=fPrefix+fIndent;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXWriter.Unindent;
|
|
||||||
begin
|
|
||||||
fPrefix:=Copy(fPrefix,1, length(fPrefix)-length(fIndent));
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXWriter.WriteLn(const utf8: AnsiString);
|
|
||||||
const
|
|
||||||
LF : string = #10;
|
|
||||||
begin
|
|
||||||
if utf8='' then Exit;
|
|
||||||
if fPrefix<>'' then fDst.Write(fPrefix[1], length(fPrefix));
|
|
||||||
fDst.Write(utf8[1], length(utf8));
|
|
||||||
fDst.Write(LF[1], length(LF));
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure WritePBXProjFile(RootObject: TXCodeObject; Dst: TStream);
|
|
||||||
var
|
|
||||||
lists : TFPHashObjectList; // list of TFPList
|
|
||||||
items : TFPList;
|
|
||||||
p : TXCodeObject;
|
|
||||||
stack : TFPList;
|
|
||||||
i : Integer;
|
|
||||||
xobjcount : Integer;
|
|
||||||
wr : TPBXWriter;
|
|
||||||
begin
|
|
||||||
if RootObject=nil then Exit;
|
|
||||||
|
|
||||||
lists:=TFPHashObjectList.Create(True);
|
|
||||||
|
|
||||||
stack:=TFPList.Create;
|
|
||||||
xobjcount:=1;
|
|
||||||
stack.Add(RootObject);
|
|
||||||
while stack.Count > 0 do begin
|
|
||||||
p:= TXCodeObject(stack[0]);
|
|
||||||
items:=TFPList(lists.Find(p.isa));
|
|
||||||
if not Assigned(items) then begin
|
|
||||||
items:=TFPList.Create;
|
|
||||||
lists.Add(p.isa, items);
|
|
||||||
end;
|
|
||||||
items.Add(p);
|
|
||||||
inc(xobjcount, p.ChildCount);
|
|
||||||
for i:=0 to p.ChildCount-1 do stack.Add(p.Child[i]);
|
|
||||||
stack.Delete(0);
|
|
||||||
end;
|
|
||||||
stack.Free;
|
|
||||||
|
|
||||||
wr:=TPBXWriter.Create(Dst);
|
|
||||||
wr.WriteLn(UTF8Mark);
|
|
||||||
wr.WriteLn('{');
|
|
||||||
wr.Indent;
|
|
||||||
wr.WriteLn('archiveVersion = 1;');
|
|
||||||
wr.WriteLn('classes = {};');
|
|
||||||
wr.WriteLn('objectVersion = 45;');
|
|
||||||
wr.WriteLn('objects = { ');
|
|
||||||
wr.Indent;
|
|
||||||
lists.ForEachCall(@wr.WriteItems, nil);
|
|
||||||
wr.Unindent;
|
|
||||||
wr.WriteLn('};');
|
|
||||||
wr.WriteLn('rootObject = '+RootObject.ID+';');
|
|
||||||
wr.Unindent;
|
|
||||||
wr.WriteLn('}');
|
|
||||||
wr.Free;
|
|
||||||
|
|
||||||
lists.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure WritePBXProjFile(RootObject: TXCodeObject; const FileName: String);
|
|
||||||
var
|
|
||||||
fs : TFileStream;
|
|
||||||
begin
|
|
||||||
fs:=TFileStream.Create(FileName, fmCreate);
|
|
||||||
WritePBXProjFile(RootOBject, fs);
|
|
||||||
fs.Free;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TXCProject }
|
|
||||||
|
|
||||||
function TPBXProject.GetDirPath: string;
|
|
||||||
begin
|
|
||||||
Result:=UnquoteStr(StrValue['projectDirPath']);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.GetRoot: String;
|
|
||||||
begin
|
|
||||||
Result:=UnquoteStr(StrValue['projectRoot']);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXProject.SetDirPath(const AValue: string);
|
|
||||||
begin
|
|
||||||
StrValue['projectDirPath']:=QuotedStr(AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXProject.SetRoot(const AValue: String);
|
|
||||||
begin
|
|
||||||
StrValue['projectRoot']:=QuotedStr(AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.GetConfigList: TXCConfigurationList;
|
|
||||||
begin
|
|
||||||
if not Assigned(fConfigList) then begin
|
|
||||||
fConfigList:=TXCConfigurationList.Create;
|
|
||||||
AddObject('buildConfigurationList', fConfigList);
|
|
||||||
end;
|
|
||||||
Result:=fConfigList;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.GetTargets: TFPObjectList;
|
|
||||||
begin
|
|
||||||
Result:=GetObjectArray('targets');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.GetVersion: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('compatibilityVersion');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXProject.SetVersion(const AVersion: string);
|
|
||||||
begin
|
|
||||||
SetValue('compatibilityVersion', AVersion);
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TPBXProject.Create;
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
Root:='';
|
|
||||||
DirPath:='';
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TPBXProject.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXProject';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.AddTarget: TPBXNativeTarget;
|
|
||||||
var
|
|
||||||
list : TFPObjectList;
|
|
||||||
begin
|
|
||||||
// adding a target forces configuration list
|
|
||||||
//if fConfigList=nil then GetConfigList;
|
|
||||||
|
|
||||||
list:=GetObjectArray('targets');
|
|
||||||
Result:=TPBXNativeTarget.Create;
|
|
||||||
AddObject('', Result);
|
|
||||||
list.Add(Result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXProject.AddBuildConfig: TXCBuildConfiguration;
|
|
||||||
begin
|
|
||||||
Result:=GetConfigList.AddList;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXNativeTarget }
|
|
||||||
|
|
||||||
function TPBXNativeTarget.GetName: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('name');
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.GetProductFile: TPBXFileReference;
|
|
||||||
begin
|
|
||||||
if not Assigned(fRef) then begin
|
|
||||||
fRef:=TPBXFileReference.Create;
|
|
||||||
AddObject('productReference', fRef);
|
|
||||||
end;
|
|
||||||
Result:=fRef;
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXNativeTarget.SetName(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('name', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.GetProductName: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('productName');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXNativeTarget.SetProductName(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('productName', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.GetProductType: String;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('productType');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXNativeTarget.SetProductType(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('productType', AValue)
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.GetConfigList: TXCConfigurationList;
|
|
||||||
begin
|
|
||||||
if not Assigned(fConfigList) then begin
|
|
||||||
fConfigList:=TXCConfigurationList.Create;
|
|
||||||
AddObject('buildConfigurationList', fConfigList);
|
|
||||||
end;
|
|
||||||
Result:=fConfigList;
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TPBXNativeTarget.Create;
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
productType := '"com.apple.product-type.application"';
|
|
||||||
GetObjectArray('buildPhases');
|
|
||||||
GetObjectArray('buildRules');
|
|
||||||
GetObjectArray('dependencies');
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TPBXNativeTarget.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXNativeTarget';
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.AddBuildConfig: TXCBuildConfiguration;
|
|
||||||
begin
|
|
||||||
Result:=GetConfigList.AddList;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXNativeTarget.AddScriptPhase: TPBXShellScriptBuildPhase;
|
|
||||||
begin
|
|
||||||
Result:=TPBXShellScriptBuildPhase.Create;
|
|
||||||
AddObject('', Result);
|
|
||||||
GetObjectArray('buildPhases').Add(Result);
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ TPBXShellScriptBuildPhase }
|
|
||||||
|
|
||||||
function TPBXShellScriptBuildPhase.GetBuildMask: Integer;
|
|
||||||
begin
|
|
||||||
Result:=StrToIntDef( GetValue('buildActionMask'), 0);
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXShellScriptBuildPhase.SetBuildMask(const AValue: Integer);
|
|
||||||
begin
|
|
||||||
SetValue('buildActionMask', IntToStr(AValue));
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXShellScriptBuildPhase.GetShellPath: string;
|
|
||||||
begin
|
|
||||||
Result:=GetValue('shellPath');
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXShellScriptBuildPhase.SetShellPath(const AValue: string);
|
|
||||||
begin
|
|
||||||
SetValue('shellPath', AValue);
|
|
||||||
end;
|
|
||||||
|
|
||||||
function TPBXShellScriptBuildPhase.GetShellScript: String;
|
|
||||||
begin
|
|
||||||
Result:=UnquoteStr(GetValue('shellScript'));
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure TPBXShellScriptBuildPhase.SetShellScript(const AValue: String);
|
|
||||||
begin
|
|
||||||
SetValue('shellScript', QuotedStr(AValue));
|
|
||||||
end;
|
|
||||||
|
|
||||||
constructor TPBXShellScriptBuildPhase.Create;
|
|
||||||
begin
|
|
||||||
inherited Create;
|
|
||||||
ShellPath:='/bin/sh';
|
|
||||||
GetObjectArray('files');
|
|
||||||
GetObjectArray('inputPaths');
|
|
||||||
GetObjectArray('outputPaths');
|
|
||||||
end;
|
|
||||||
|
|
||||||
class function TPBXShellScriptBuildPhase.isa: ShortString;
|
|
||||||
begin
|
|
||||||
Result:='PBXShellScriptBuildPhase';
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
Reference in New Issue
Block a user