You've already forked lazarus-ccr
iphonelazext: update in Xcode project generation, using pbx files rather than a text template. Updates project options dialog to compare changes and mark project as modified, if necessary
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4404 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
@ -51,7 +51,6 @@ type
|
|||||||
constructor Create;
|
constructor Create;
|
||||||
procedure UpdateXcode(Sender: TObject);
|
procedure UpdateXcode(Sender: TObject);
|
||||||
procedure SimRun(Sender: TObject);
|
procedure SimRun(Sender: TObject);
|
||||||
//procedure isProjectClicked(Sender: TObject);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -349,6 +348,7 @@ var
|
|||||||
projname : string;
|
projname : string;
|
||||||
|
|
||||||
ext : string;
|
ext : string;
|
||||||
|
exename : string;
|
||||||
tname : string;
|
tname : string;
|
||||||
plistname : string;
|
plistname : string;
|
||||||
|
|
||||||
@ -358,7 +358,6 @@ var
|
|||||||
opt : string;
|
opt : string;
|
||||||
optSim: string;
|
optSim: string;
|
||||||
begin
|
begin
|
||||||
FillBunldeInfo(false, Info);
|
|
||||||
// the create .plist would be used by XCode project
|
// the create .plist would be used by XCode project
|
||||||
// the simulator .plist in created with InstallAppToSim.
|
// the simulator .plist in created with InstallAppToSim.
|
||||||
// they differ with SDKs used
|
// they differ with SDKs used
|
||||||
@ -367,43 +366,32 @@ begin
|
|||||||
|
|
||||||
tname:=ExtractFileName( LazarusIDE.ActiveProject.MainFile.Filename);
|
tname:=ExtractFileName( LazarusIDE.ActiveProject.MainFile.Filename);
|
||||||
tname:=ChangeFileExt(tname, '');
|
tname:=ChangeFileExt(tname, '');
|
||||||
plistname:=tname+'.plist';
|
plistname:='info.plist';
|
||||||
|
|
||||||
build.Add('INFOPLIST_FILE','"'+plistname+'"');
|
build.Add('INFOPLIST_FILE','"'+plistname+'"');
|
||||||
build.Add('PRODUCT_NAME','"'+tname+'"');
|
build.Add('PRODUCT_NAME','"'+tname+'"');
|
||||||
build.Add('SDKROOT',EnvOptions.GetSDKName(ProjOptions.SDK, false));
|
build.Add('SDKROOT',EnvOptions.GetSDKName(ProjOptions.SDK, false));
|
||||||
build.Add('FPC_COMPILER_PATH','"'+EnvOptions.CompilerPath+'"');
|
build.Add('FPC_COMPILER_PATH','"'+EnvOptions.CompilerPath+'"');
|
||||||
build.Add('FPC_MAIN_FILE','"'+LazarusIDE.ActiveProject.MainFile.Filename+'"');
|
build.Add('FPC_MAIN_FILE','"'+LazarusIDE.ActiveProject.MainFile.Filename+'"');
|
||||||
opt :=
|
opt:='';
|
||||||
' -XR'+EnvOptions.GetSDKFullPath(ProjOptions.SDK, false)+' ' +
|
|
||||||
' -FD'+IncludeTrailingPathDelimiter(EnvOptions.PlatformsBaseDir)+'iPhoneOS.platform/Developer/usr/bin ' +
|
|
||||||
EnvOptions.CommonOpt;
|
|
||||||
optSim :=
|
|
||||||
' -XR'+EnvOptions.GetSDKFullPath(ProjOptions.SDK, true)+' ' +
|
|
||||||
' -FD'+IncludeTrailingPathDelimiter(EnvOptions.PlatformsBaseDir)+'iPhoneSimulator.platform/Developer/usr/bin ' +
|
|
||||||
EnvOptions.CommonOpt;
|
|
||||||
|
|
||||||
with LazarusIDE.ActiveProject.LazCompilerOptions do begin
|
with LazarusIDE.ActiveProject.LazCompilerOptions do begin
|
||||||
opt:=opt + ' ' +BreakPathsStringToOption(OtherUnitFiles, '-Fu', '\"');
|
opt:=opt + ' ' +BreakPathsStringToOption(OtherUnitFiles, '-Fu', '\"');
|
||||||
opt:=opt + ' ' +BreakPathsStringToOption(IncludePath, '-Fi', '\"');
|
opt:=opt + ' ' +BreakPathsStringToOption(IncludePath, '-Fi', '\"');
|
||||||
opt:=opt + ' ' +BreakPathsStringToOption(ObjectPath, '-Fo', '\"');
|
opt:=opt + ' ' +BreakPathsStringToOption(ObjectPath, '-Fo', '\"');
|
||||||
opt:=opt + ' ' +BreakPathsStringToOption(Libraries, '-Fl', '\"');
|
opt:=opt + ' ' +BreakPathsStringToOption(Libraries, '-Fl', '\"');
|
||||||
optSim:=optSim + ' ' +BreakPathsStringToOption(OtherUnitFiles, '-Fu', '\"');
|
|
||||||
optSim:=optSim + ' ' +BreakPathsStringToOption(IncludePath, '-Fi', '\"');
|
|
||||||
optSim:=optSim + ' ' +BreakPathsStringToOption(ObjectPath, '-Fo', '\"');
|
|
||||||
optSim:=optSim + ' ' +BreakPathsStringToOption(Libraries, '-Fl', '\"');
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
build.Add('FPC_CUSTOM_OPTIONS','"'+opt+'"');
|
|
||||||
build.Add('"FPC_CUSTOM_OPTIONS[sdk=iphonesimulator*]"','"'+optSim+'"');
|
|
||||||
|
|
||||||
dir:=ResolveProjectPath('xcode');
|
dir:=ResolveProjectPath('xcode');
|
||||||
dir:=dir+'/';
|
dir:=dir+'/';
|
||||||
|
|
||||||
name:=ExtractFileName(GetProjectExeName(LazarusIDE.ActiveProject));
|
// not using executable name. It's driven by product name
|
||||||
|
//exename:=ExtractFileName(GetProjectExeName(LazarusIDE.ActiveProject));
|
||||||
|
//name:=exename;
|
||||||
ForceDirectories(dir);
|
ForceDirectories(dir);
|
||||||
WriteDefInfoList( dir + GetProjectPlistName(LazarusIDE.ActiveProject),
|
|
||||||
name, name, Info);
|
FillBunldeInfo(false, Info);
|
||||||
|
WriteDefInfoList( dir + plistname, tname, tname, Info);
|
||||||
|
|
||||||
|
|
||||||
projname:=ExtractFileName(LazarusIDE.ActiveProject.MainFile.Filename);
|
projname:=ExtractFileName(LazarusIDE.ActiveProject.MainFile.Filename);
|
||||||
@ -417,32 +405,30 @@ begin
|
|||||||
proj:=TStringList.Create;
|
proj:=TStringList.Create;
|
||||||
templates:=nil;
|
templates:=nil;
|
||||||
try
|
try
|
||||||
if not FileExists(projname) then begin
|
templates:=TStringList.Create;
|
||||||
templates:=TStringList.Create;
|
|
||||||
|
|
||||||
if WriteIconTo( IncludeTrailingPathDelimiter(dir)+'Icon.png') then begin
|
if WriteIconTo( IncludeTrailingPathDelimiter(dir)+'Icon.png') then begin
|
||||||
templates.Values['icon']:=XCodeProjectTemplateIcon;
|
templates.Values['icon']:=XCodeProjectTemplateIcon;
|
||||||
templates.Values['iconid']:=XCodeProjectTemplateIconID;
|
templates.Values['iconid']:=XCodeProjectTemplateIconID;
|
||||||
templates.Values['iconfile']:=XCodeIconFile;
|
templates.Values['iconfile']:=XCodeIconFile;
|
||||||
templates.Values['iconfileref']:=XCodeIconFileRef;
|
templates.Values['iconfileref']:=XCodeIconFileRef;
|
||||||
end else begin
|
end else begin
|
||||||
templates.Values['icon']:='';
|
templates.Values['icon']:='';
|
||||||
templates.Values['iconid']:='';
|
templates.Values['iconid']:='';
|
||||||
templates.Values['iconfile']:='';
|
templates.Values['iconfile']:='';
|
||||||
templates.Values['iconfileref']:='';
|
templates.Values['iconfileref']:='';
|
||||||
end;
|
end;
|
||||||
|
|
||||||
//todo:
|
//todo:
|
||||||
templates.Values['bundle']:=tname+'.app';
|
templates.Values['bundle']:=tname+'.app';
|
||||||
templates.Values['plist']:=plistname;
|
templates.Values['plist']:=plistname;
|
||||||
templates.Values['targetname']:=tname;
|
templates.Values['targetname']:=tname; // Target and Product name must match
|
||||||
templates.Values['productname']:=tname;
|
templates.Values['productname']:=tname;
|
||||||
|
templates.Values['mainfile']:=LazarusIDE.ActiveProject.MainFile.Filename;
|
||||||
|
templates.Values['projoptions']:=opt;
|
||||||
|
|
||||||
proj.Text:=XCodeProjectTemplate;
|
// Xcode project updated (/Users/dmitry/FPC_Laz/iphonelazext/tests/xcode/test_xcodetemplate.xcodeproj)
|
||||||
end else
|
PrepareTemplateFile(proj, templates);
|
||||||
proj.LoadFromFile(projname);
|
|
||||||
|
|
||||||
PrepareTemplateFile(proj, templates, build);
|
|
||||||
proj.SaveToFile(projname);
|
proj.SaveToFile(projname);
|
||||||
except
|
except
|
||||||
on e: exception do
|
on e: exception do
|
||||||
@ -453,7 +439,7 @@ begin
|
|||||||
templates.Free;
|
templates.Free;
|
||||||
build.Free;
|
build.Free;
|
||||||
|
|
||||||
IDEMessagesWindow.AddMsg(strXcodeUpdated, '', 0);
|
IDEMessagesWindow.AddMsg(Format(strXcodeUpdated,[projdir]), '', 0);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure SimRunDirect;
|
procedure SimRunDirect;
|
||||||
@ -496,15 +482,6 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{procedure TiPhoneExtension.isProjectClicked(Sender: TObject);
|
|
||||||
begin
|
|
||||||
if not Assigned(Sender) or not Assigned(LazarusIDE.ActiveProject) then Exit;
|
|
||||||
TIDEMenuCommand(Sender).Checked:=not TIDEMenuCommand(Sender).Checked;
|
|
||||||
ProjOptions.isiPhoneApp:=TIDEMenuCommand(Sender).Checked;
|
|
||||||
ProjOptions.Save;
|
|
||||||
end;}
|
|
||||||
|
|
||||||
procedure Register;
|
procedure Register;
|
||||||
begin
|
begin
|
||||||
// IDE integration is done in constructor
|
// IDE integration is done in constructor
|
||||||
|
@ -21,6 +21,7 @@ interface
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, MacroIntf,
|
Classes, SysUtils, IDEOptionsIntf, LazIDEIntf, ProjectIntf, MacroIntf,
|
||||||
|
CompOptsIntf,
|
||||||
iPhoneBundle, XMLConf, XcodeUtils, FileUtil, iphonesimctrl;
|
iPhoneBundle, XMLConf, XcodeUtils, FileUtil, iphonesimctrl;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -40,8 +41,11 @@ type
|
|||||||
fResourceDir : String;
|
fResourceDir : String;
|
||||||
fExcludeMask : String;
|
fExcludeMask : String;
|
||||||
fMainNib : String;
|
fMainNib : String;
|
||||||
|
fResFiles : TStrings;
|
||||||
public
|
public
|
||||||
|
//constructor Create; override;
|
||||||
constructor Create;
|
constructor Create;
|
||||||
|
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: Boolean;
|
||||||
@ -54,6 +58,7 @@ type
|
|||||||
property ResourceDir: String read fResourceDir write fResourceDir;
|
property ResourceDir: String read fResourceDir write fResourceDir;
|
||||||
property ExcludeMask: String read fExcludeMask write fExcludeMask;
|
property ExcludeMask: String read fExcludeMask write fExcludeMask;
|
||||||
property MainNib: String read fMainNib write fMainNib;
|
property MainNib: String read fMainNib write fMainNib;
|
||||||
|
property ResFiles: TStrings read fResFiles;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ TiPhoneEnvironmentOptions }
|
{ TiPhoneEnvironmentOptions }
|
||||||
@ -149,6 +154,7 @@ const
|
|||||||
optResourceDir = 'iPhone/ResourceDir';
|
optResourceDir = 'iPhone/ResourceDir';
|
||||||
optExcludeMask = 'iPhone/ExcludeMask';
|
optExcludeMask = 'iPhone/ExcludeMask';
|
||||||
optMainNib = 'iPhone/MainNib';
|
optMainNib = 'iPhone/MainNib';
|
||||||
|
optResFiles = 'iPhone/ResFiles';
|
||||||
|
|
||||||
function EnvOptions: TiPhoneEnvironmentOptions;
|
function EnvOptions: TiPhoneEnvironmentOptions;
|
||||||
begin
|
begin
|
||||||
@ -403,14 +409,22 @@ begin
|
|||||||
fAppID:='com.mycompany.myapplication';
|
fAppID:='com.mycompany.myapplication';
|
||||||
fSpaceName:='';
|
fSpaceName:='';
|
||||||
DataWritten:=false;
|
DataWritten:=false;
|
||||||
|
fResFiles.Clear;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
constructor TiPhoneProjectOptions.Create;
|
constructor TiPhoneProjectOptions.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
|
fResFiles := TStringList.Create;
|
||||||
Reset;
|
Reset;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TiPhoneProjectOptions.Destroy;
|
||||||
|
begin
|
||||||
|
fResFiles.Free;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TiPhoneProjectOptions.GetGroupCaption: String;
|
class function TiPhoneProjectOptions.GetGroupCaption: String;
|
||||||
begin
|
begin
|
||||||
Result:='iPhone';
|
Result:='iPhone';
|
||||||
@ -435,24 +449,42 @@ 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];
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function TiPhoneProjectOptions.Save: Boolean;
|
function TiPhoneProjectOptions.Save: Boolean;
|
||||||
const
|
const
|
||||||
BoolStr : array[Boolean] of String = ('false', 'true');
|
BoolStr : array[Boolean] of String = ('false', 'true');
|
||||||
|
var
|
||||||
|
modflag: Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=True;
|
Result:=True;
|
||||||
{do not write iPhone related info to non-iPhone projects}
|
{do not write iPhone related info to non-iPhone projects}
|
||||||
if DataWritten or fisiPhone then
|
if DataWritten or fisiPhone then
|
||||||
with LazarusIDE.ActiveProject do begin
|
with LazarusIDE.ActiveProject do begin
|
||||||
CustomData.Values[optisIPhone] := BoolStr[fisiPhone];
|
|
||||||
CustomData.Values[optSDK]:=fSDK;
|
modflag:=false;
|
||||||
CustomData.Values[optAppID]:=fAppID;
|
modflag:=(CustomData.Values[optisIPhone] <> BoolStr[fisiPhone])
|
||||||
CustomData.Values[optSpaceName]:=fSpaceName;
|
or (CustomData.Values[optSDK]<>fSDK)
|
||||||
CustomData.Values[optResourceDir]:=fResourceDir;
|
or (CustomData.Values[optAppID]<>fAppID)
|
||||||
CustomData.Values[optExcludeMask]:=fExcludeMask;
|
or (CustomData.Values[optSpaceName]<>fSpaceName)
|
||||||
CustomData.Values[optMainNib]:=fMainNib;
|
or (CustomData.Values[optResourceDir]<>fResourceDir)
|
||||||
|
or (CustomData.Values[optExcludeMask]<>fExcludeMask)
|
||||||
|
or (CustomData.Values[optMainNib]<>fMainNib)
|
||||||
|
or (CustomData.Values[optResFiles]<>ResFiles.Text);
|
||||||
|
|
||||||
|
if modflag then begin
|
||||||
|
LazarusIDE.ActiveProject.Modified:=true;
|
||||||
|
CustomData.Values[optisIPhone] := BoolStr[fisiPhone];
|
||||||
|
CustomData.Values[optSDK]:=fSDK;
|
||||||
|
CustomData.Values[optAppID]:=fAppID;
|
||||||
|
CustomData.Values[optSpaceName]:=fSpaceName;
|
||||||
|
CustomData.Values[optResourceDir]:=fResourceDir;
|
||||||
|
CustomData.Values[optExcludeMask]:=fExcludeMask;
|
||||||
|
CustomData.Values[optMainNib]:=fMainNib;
|
||||||
|
CustomData.Values[optResFiles]:=ResFiles.Text;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ resourcestring
|
|||||||
strPtrOptAppID = 'Application ID';
|
strPtrOptAppID = 'Application ID';
|
||||||
strPtrOptAppIDHint = 'It''s recommended by Apple to use domain-structured identifier i.e. "com.mycompany.myApplication"';
|
strPtrOptAppIDHint = 'It''s recommended by Apple to use domain-structured identifier i.e. "com.mycompany.myApplication"';
|
||||||
|
|
||||||
strXcodeUpdated = 'Xcode project updated';
|
strXcodeUpdated = 'Xcode project updated (%s)';
|
||||||
|
|
||||||
strWNoSDKSelected = 'Warning: SDK is not selected using %s';
|
strWNoSDKSelected = 'Warning: SDK is not selected using %s';
|
||||||
strWNoSDK = 'Warning: No SDK available. Linking might fail.';
|
strWNoSDK = 'Warning: No SDK available. Linking might fail.';
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?xml version="1.0"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<CONFIG>
|
<CONFIG>
|
||||||
<Package Version="4">
|
<Package Version="4">
|
||||||
<Name Value="iphonelazext"/>
|
<Name Value="iphonelazext"/>
|
||||||
<AddToProjectUsesSection Value="True"/>
|
<Type Value="DesignTime"/>
|
||||||
<Author Value="Dmitry 'skalogryz' Boyarintsev"/>
|
<Author Value="Dmitry 'skalogryz' Boyarintsev"/>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
<Version Value="11"/>
|
<Version Value="11"/>
|
||||||
<SearchPaths>
|
<SearchPaths>
|
||||||
|
<OtherUnitFiles Value="pbx"/>
|
||||||
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
|
||||||
</SearchPaths>
|
</SearchPaths>
|
||||||
<Parsing>
|
<Parsing>
|
||||||
@ -16,15 +17,15 @@
|
|||||||
</Parsing>
|
</Parsing>
|
||||||
<Other>
|
<Other>
|
||||||
<CompilerMessages>
|
<CompilerMessages>
|
||||||
<IgnoredMessages idx4055="True" idx4079="True" idx4080="True" idx4081="True" idx5024="True" idx5057="True" idx5060="True"/>
|
<IgnoredMessages idx5091="True" idx5060="True" idx5057="True" idx5024="True" idx4081="True" idx4080="True" idx4079="True" idx4055="True"/>
|
||||||
</CompilerMessages>
|
</CompilerMessages>
|
||||||
<CompilerPath Value="$(CompPath)"/>
|
<CustomOptions Value="-Sm -dPACKAGE_PATH:='$(PkgDir)'"/>
|
||||||
</Other>
|
</Other>
|
||||||
</CompilerOptions>
|
</CompilerOptions>
|
||||||
<Description Value="iPhone Development Lazarus extension"/>
|
<Description Value="iPhone Development Lazarus extension"/>
|
||||||
<License Value="LGPL"/>
|
<License Value="LGPL"/>
|
||||||
<Version Minor="7"/>
|
<Version Minor="8"/>
|
||||||
<Files Count="14">
|
<Files Count="21">
|
||||||
<Item1>
|
<Item1>
|
||||||
<Filename Value="ideext.pas"/>
|
<Filename Value="ideext.pas"/>
|
||||||
<HasRegisterProc Value="True"/>
|
<HasRegisterProc Value="True"/>
|
||||||
@ -68,22 +69,52 @@
|
|||||||
</Item10>
|
</Item10>
|
||||||
<Item11>
|
<Item11>
|
||||||
<Filename Value="lazfilesutils.pas"/>
|
<Filename Value="lazfilesutils.pas"/>
|
||||||
<UnitName Value="lazfilesutils"/>
|
<UnitName Value="LazFilesUtils"/>
|
||||||
</Item11>
|
</Item11>
|
||||||
<Item12>
|
<Item12>
|
||||||
<Filename Value="xcodeutils.pas"/>
|
<Filename Value="xcodeutils.pas"/>
|
||||||
<UnitName Value="xcodeutils"/>
|
<UnitName Value="XcodeUtils"/>
|
||||||
</Item12>
|
</Item12>
|
||||||
<Item13>
|
<Item13>
|
||||||
<Filename Value="newxibdialog.pas"/>
|
<Filename Value="newxibdialog.pas"/>
|
||||||
<UnitName Value="newxibdialog"/>
|
<UnitName Value="newXibDialog"/>
|
||||||
</Item13>
|
</Item13>
|
||||||
<Item14>
|
<Item14>
|
||||||
<Filename Value="xibfile.pas"/>
|
<Filename Value="xibfile.pas"/>
|
||||||
<UnitName Value="xibfile"/>
|
<UnitName Value="xibfile"/>
|
||||||
</Item14>
|
</Item14>
|
||||||
|
<Item15>
|
||||||
|
<Filename Value="pbx/pbxcontainer.pas"/>
|
||||||
|
<AddToUsesPkgSection Value="False"/>
|
||||||
|
<UnitName Value="pbxcontainer"/>
|
||||||
|
</Item15>
|
||||||
|
<Item16>
|
||||||
|
<Filename Value="pbx/pbxfile.pas"/>
|
||||||
|
<AddToUsesPkgSection Value="False"/>
|
||||||
|
<UnitName Value="pbxfile"/>
|
||||||
|
</Item16>
|
||||||
|
<Item17>
|
||||||
|
<Filename Value="pbx/xcodeproj.pas"/>
|
||||||
|
<AddToUsesPkgSection Value="False"/>
|
||||||
|
<UnitName Value="xcodeproj"/>
|
||||||
|
</Item17>
|
||||||
|
<Item18>
|
||||||
|
<Filename Value="plistfile.pas"/>
|
||||||
|
<UnitName Value="PlistFile"/>
|
||||||
|
</Item18>
|
||||||
|
<Item19>
|
||||||
|
<Filename Value="pbx/xcodeprojutils.pas"/>
|
||||||
|
<UnitName Value="xcodeprojutils"/>
|
||||||
|
</Item19>
|
||||||
|
<Item20>
|
||||||
|
<Filename Value="iphonesimctrl.pas"/>
|
||||||
|
<UnitName Value="iphonesimctrl"/>
|
||||||
|
</Item20>
|
||||||
|
<Item21>
|
||||||
|
<Filename Value="res/buildscript.sh"/>
|
||||||
|
<Type Value="Text"/>
|
||||||
|
</Item21>
|
||||||
</Files>
|
</Files>
|
||||||
<Type Value="DesignTime"/>
|
|
||||||
<RequiredPkgs Count="3">
|
<RequiredPkgs Count="3">
|
||||||
<Item1>
|
<Item1>
|
||||||
<PackageName Value="LCL"/>
|
<PackageName Value="LCL"/>
|
||||||
|
@ -10,7 +10,7 @@ uses
|
|||||||
ideext, iPhoneExtStr, iPhoneBundle, XCodeProject,
|
ideext, iPhoneExtStr, iPhoneBundle, XCodeProject,
|
||||||
environment_iphone_options, project_iphone_options, iPhoneExtOptions,
|
environment_iphone_options, project_iphone_options, iPhoneExtOptions,
|
||||||
xcodetemplate, LazFilesUtils, XcodeUtils, newXibDialog, xibfile, PlistFile,
|
xcodetemplate, LazFilesUtils, XcodeUtils, newXibDialog, xibfile, PlistFile,
|
||||||
LazarusPackageIntf;
|
xcodeprojutils, iphonesimctrl, LazarusPackageIntf;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -25,7 +25,8 @@ uses
|
|||||||
|
|
||||||
function ResolveProjectPath(const path: string; project: TLazProject = nil): string;
|
function ResolveProjectPath(const path: string; project: TLazProject = nil): string;
|
||||||
|
|
||||||
function BreakPathsStringToOption(const Paths, Switch: String; const Quotes: string = '"'; project: TLazProject = nil): String;
|
function BreakPathsStringToOption(const Paths, Switch: String;
|
||||||
|
const Quotes: string = '"'; project: TLazProject = nil; AResolvePath: Boolean = false): String;
|
||||||
|
|
||||||
function RelativeToFullPath(const BasePath, Relative: string): String;
|
function RelativeToFullPath(const BasePath, Relative: string): String;
|
||||||
function NeedQuotes(const path: string): Boolean;
|
function NeedQuotes(const path: string): Boolean;
|
||||||
@ -152,7 +153,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function BreakPathsStringToOption(const Paths, Switch, Quotes: String; project: TLazProject): String;
|
function BreakPathsStringToOption(const Paths, Switch, Quotes: String; project: TLazProject; AResolvePath: Boolean): String;
|
||||||
var
|
var
|
||||||
i, j : Integer;
|
i, j : Integer;
|
||||||
fixed : String;
|
fixed : String;
|
||||||
@ -168,7 +169,7 @@ begin
|
|||||||
if Paths[i]=';' then begin
|
if Paths[i]=';' then begin
|
||||||
fixed:=Trim(Copy(paths,j, i-j) );
|
fixed:=Trim(Copy(paths,j, i-j) );
|
||||||
if fixed<>'' then begin
|
if fixed<>'' then begin
|
||||||
fixed:=ResolveProjectPath(fixed, project);
|
if AResolvePath then fixed:=ResolveProjectPath(fixed, project);
|
||||||
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
||||||
end;
|
end;
|
||||||
j:=i+1;
|
j:=i+1;
|
||||||
@ -176,7 +177,7 @@ begin
|
|||||||
|
|
||||||
fixed:=Trim(Copy(paths,j, length(paths)-j+1) );
|
fixed:=Trim(Copy(paths,j, length(paths)-j+1) );
|
||||||
if fixed<>'' then begin
|
if fixed<>'' then begin
|
||||||
fixed:=ResolveProjectPath(fixed, project);
|
if AResolvePath then fixed:=ResolveProjectPath(fixed, project);
|
||||||
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
Result:=Result+' ' + Switch + QuoteStrIfNeeded(fixed, quotes);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -85,10 +85,14 @@ type
|
|||||||
TPBXKeyValue = class(TFPHashObjectList)
|
TPBXKeyValue = class(TFPHashObjectList)
|
||||||
protected
|
protected
|
||||||
function AddVal(const name: string; atype: TPBXValueType): TPBXValue;
|
function AddVal(const name: string; atype: TPBXValueType): TPBXValue;
|
||||||
|
function GetValStr(const name: string): string;
|
||||||
|
procedure AddValStr(const name, avalue: string);
|
||||||
public
|
public
|
||||||
function AddStr(const name: string; const avalue: string = ''): TPBXValue;
|
function AddStr(const name: string; const avalue: string = ''): TPBXValue;
|
||||||
function AddStrArray(const name: string): TPBXValue;
|
function AddStrArray(const name: string): TPBXValue;
|
||||||
function AddKeyVal(const name: string): TPBXValue;
|
function AddKeyVal(const name: string): TPBXValue;
|
||||||
|
// it must be "public, not published"
|
||||||
|
property Str[const name: string]: string read GetValStr write AddValStr;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
TPBXFileInfo = record
|
TPBXFileInfo = record
|
||||||
@ -135,10 +139,16 @@ procedure PBXWriteStrArray( w: TPBXWriter; list: TPBXStringArray );
|
|||||||
procedure PBXWriteKeyValue( w: TPBXWriter; kv: TPBXKeyValue );
|
procedure PBXWriteKeyValue( w: TPBXWriter; kv: TPBXKeyValue );
|
||||||
procedure PBXWriteObj(pbx: PBXObject; w: TPBXWriter; WriteEmpty: TStrings);
|
procedure PBXWriteObj(pbx: PBXObject; w: TPBXWriter; WriteEmpty: TStrings);
|
||||||
|
|
||||||
|
{ assigns reference IDs to each object in the list. "ID" is 24 charactewr long hex-string }
|
||||||
procedure PBXAssignRef(list: TList);
|
procedure PBXAssignRef(list: TList);
|
||||||
|
|
||||||
|
{ Returns the list of objects that should populate the "objects" section of pbx file }
|
||||||
procedure PBXGatherObjects(obj: TObject; srz: TList);
|
procedure PBXGatherObjects(obj: TObject; srz: TList);
|
||||||
|
|
||||||
|
procedure PBXKeyValsCopy(src, dst: TPBXKeyValue);
|
||||||
|
procedure PBXValueCopy(src, dst: TPBXValue);
|
||||||
|
procedure PBXStringArrayCopy(src, dst: TPBXStringArray);
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
var
|
var
|
||||||
@ -170,6 +180,48 @@ begin
|
|||||||
Result:=True;
|
Result:=True;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure PBXStringArrayCopy(src, dst: TPBXStringArray);
|
||||||
|
begin
|
||||||
|
if not Assigned(src) or not Assigned(dst) then Exit;
|
||||||
|
src.Assign(dst);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PBXValueCopy(src, dst: TPBXValue);
|
||||||
|
var
|
||||||
|
dv : TPBXValue;
|
||||||
|
begin
|
||||||
|
if not Assigned(src) or not Assigned(dst) then Exit;
|
||||||
|
dst.valType:=src.valType;
|
||||||
|
case dst.valType of
|
||||||
|
vtString: dst.str:=src.str;
|
||||||
|
vtArrayOfStr: begin
|
||||||
|
if not Assigned(dst.arr) then dst.arr:=TPBXStringArray.Create;
|
||||||
|
PBXStringArrayCopy(src.arr, dst.arr);
|
||||||
|
end;
|
||||||
|
vtKeyVal: begin
|
||||||
|
if not Assigned(dst.keyval) then dst.keyval:=TPBXKeyValue.Create(true);
|
||||||
|
PBXKeyValsCopy(src.keyval, dst.keyval);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PBXKeyValsCopy(src, dst: TPBXKeyValue);
|
||||||
|
var
|
||||||
|
svl : TPBXValue;
|
||||||
|
nm : string;
|
||||||
|
i : Integer;
|
||||||
|
dvl : TPBXValue;
|
||||||
|
begin
|
||||||
|
if not Assigned(src) or not Assigned(dst) then Exit;
|
||||||
|
for i:=0 to src.Count-1 do begin
|
||||||
|
nm:=src.NameOfIndex(i);
|
||||||
|
svl:=TPBXValue(src.Items[i]);
|
||||||
|
dvl:=dst.AddVal(nm, svl.valType);
|
||||||
|
PBXValueCopy(svl, dvl);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure TestContainer(const buf: string);
|
procedure TestContainer(const buf: string);
|
||||||
var
|
var
|
||||||
c : TPBXContainer;
|
c : TPBXContainer;
|
||||||
@ -215,6 +267,11 @@ end;
|
|||||||
|
|
||||||
{ TPBXKeyValue }
|
{ TPBXKeyValue }
|
||||||
|
|
||||||
|
procedure TPBXKeyValue.AddValStr(const name, AValue: string);
|
||||||
|
begin
|
||||||
|
AddStr(name, Avalue);
|
||||||
|
end;
|
||||||
|
|
||||||
function TPBXKeyValue.AddVal(const name: string; atype: TPBXValueType): TPBXValue;
|
function TPBXKeyValue.AddVal(const name: string; atype: TPBXValueType): TPBXValue;
|
||||||
begin
|
begin
|
||||||
Result:=TPBXValue.Create;
|
Result:=TPBXValue.Create;
|
||||||
@ -226,6 +283,16 @@ begin
|
|||||||
Add(name, Result);
|
Add(name, Result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPBXKeyValue.GetValStr(const name: string): string;
|
||||||
|
var
|
||||||
|
vl : TPBXValue;
|
||||||
|
begin
|
||||||
|
vl:=TPBXValue(Self.Find(name));
|
||||||
|
if not Assigned(vl)
|
||||||
|
then Result:=''
|
||||||
|
else Result:=vl.str;
|
||||||
|
end;
|
||||||
|
|
||||||
function TPBXKeyValue.AddStr(const name: string; const avalue: string): TPBXValue;
|
function TPBXKeyValue.AddStr(const name: string; const avalue: string): TPBXValue;
|
||||||
begin
|
begin
|
||||||
Result:=AddVal(name, vtString);
|
Result:=AddVal(name, vtString);
|
||||||
@ -242,6 +309,7 @@ begin
|
|||||||
Result:=AddVal(name, vtKeyVal);
|
Result:=AddVal(name, vtKeyVal);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ TPBXReref }
|
{ TPBXReref }
|
||||||
|
|
||||||
constructor TPBXReref.Create(ainstance: TObject; const apropname, aref: string);
|
constructor TPBXReref.Create(ainstance: TObject; const apropname, aref: string);
|
||||||
@ -666,8 +734,8 @@ begin
|
|||||||
vl:=IntToStr(GetInt64Prop(pbx, p^[i]));
|
vl:=IntToStr(GetInt64Prop(pbx, p^[i]));
|
||||||
isstr:=(vl<>'') or (WriteEmpty.indexOf(nm)>=0);
|
isstr:=(vl<>'') or (WriteEmpty.indexOf(nm)>=0);
|
||||||
end else if p^[i].PropType.Kind = tkBool then begin
|
end else if p^[i].PropType.Kind = tkBool then begin
|
||||||
vl:=IntToStr(GetOrdProp(pbx, p^[i]));
|
isstr:=PtrUInt(p^[i].Default)<>PtrUInt(p^[i].GetProc);
|
||||||
isstr:=true;
|
if isstr then vl:=IntToStr(GetOrdProp(pbx, p^[i]));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if isstr then begin
|
if isstr then begin
|
||||||
|
@ -17,7 +17,8 @@ interface
|
|||||||
* {} - is an object (just like json) *
|
* {} - is an object (just like json) *
|
||||||
* escaping characters with C-style escaping: *
|
* escaping characters with C-style escaping: *
|
||||||
* * quotes (") *
|
* * quotes (") *
|
||||||
* * line breaks (note OSX is typically using \n, unline Unix \r) *
|
* * line breaks (note OSX is typically using \n, unlike Unix \r) *
|
||||||
|
* *
|
||||||
* *
|
* *
|
||||||
* PBXScanner - scans through the file *
|
* PBXScanner - scans through the file *
|
||||||
* PBXParser - parses the file, returning a higher level entities of the file: *
|
* PBXParser - parses the file, returning a higher level entities of the file: *
|
||||||
@ -177,6 +178,7 @@ var
|
|||||||
i : Integer;
|
i : Integer;
|
||||||
k : Integer;
|
k : Integer;
|
||||||
begin
|
begin
|
||||||
|
Result:='';
|
||||||
k:=0;
|
k:=0;
|
||||||
for i:=1 to length(v) do begin
|
for i:=1 to length(v) do begin
|
||||||
if not (v[i] in IdentName) then begin
|
if not (v[i] in IdentName) then begin
|
||||||
@ -435,6 +437,7 @@ begin
|
|||||||
LastComment:='';
|
LastComment:='';
|
||||||
Name:='';
|
Name:='';
|
||||||
Value:='';
|
Value:='';
|
||||||
|
Result:=etError;
|
||||||
case fState of
|
case fState of
|
||||||
stInit :
|
stInit :
|
||||||
case scanner.FetchToken of
|
case scanner.FetchToken of
|
||||||
@ -700,6 +703,7 @@ var
|
|||||||
lvl : Integer;
|
lvl : Integer;
|
||||||
tk : TPBXEntity;
|
tk : TPBXEntity;
|
||||||
begin
|
begin
|
||||||
|
Result:=false;
|
||||||
if not Assigned(p) then Exit;
|
if not Assigned(p) then Exit;
|
||||||
lvl:=p.Level;
|
lvl:=p.Level;
|
||||||
while (p.Level>=lvl) do begin
|
while (p.Level>=lvl) do begin
|
||||||
|
@ -17,10 +17,15 @@ unit xcodeproj;
|
|||||||
* * any objects within key-value tables are freed *
|
* * any objects within key-value tables are freed *
|
||||||
* Alternative solution - implement ref counting! *
|
* Alternative solution - implement ref counting! *
|
||||||
* *
|
* *
|
||||||
|
* PBXShellScriptBuildPhase - the give script must be using MacOS line breaks *
|
||||||
|
* which are \n (#13). Using unix line breaks \r (#10) will cause issues *
|
||||||
|
* in Xcode. *
|
||||||
--------------------------------------------------------------------------------}
|
--------------------------------------------------------------------------------}
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
|
{$ifdef fpc}{$mode delphi}{$endif}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils,
|
Classes, SysUtils,
|
||||||
typinfo, pbxcontainer;
|
typinfo, pbxcontainer;
|
||||||
@ -49,10 +54,16 @@ type
|
|||||||
fdefaultConfigurationIsVisible: string;
|
fdefaultConfigurationIsVisible: string;
|
||||||
fdefaultConfigurationName: string;
|
fdefaultConfigurationName: string;
|
||||||
fbuildConfigurations: TPBXObjectsList;
|
fbuildConfigurations: TPBXObjectsList;
|
||||||
|
|
||||||
|
function GetConfigItem(i: integer): XCBuildConfiguration;
|
||||||
|
function GetCount: integer;
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
function addConfig(const aname: string): XCBuildConfiguration;
|
function addConfig(const aname: string): XCBuildConfiguration;
|
||||||
|
// Count and Items are just for convenience. MUST NOT BE in "published" section
|
||||||
|
property Count: integer read GetCount;
|
||||||
|
property Items[i: integer]: XCBuildConfiguration read GetConfigItem; default;
|
||||||
published
|
published
|
||||||
property buildConfigurations: TPBXObjectsList read fbuildConfigurations;
|
property buildConfigurations: TPBXObjectsList read fbuildConfigurations;
|
||||||
property defaultConfigurationIsVisible: string read fdefaultConfigurationIsVisible write fdefaultConfigurationIsVisible;
|
property defaultConfigurationIsVisible: string read fdefaultConfigurationIsVisible write fdefaultConfigurationIsVisible;
|
||||||
@ -76,17 +87,19 @@ type
|
|||||||
|
|
||||||
{ PBXFileReference }
|
{ PBXFileReference }
|
||||||
|
|
||||||
|
// these files might not be physically present in for the project.
|
||||||
|
// i.e. a bundle .app file doesn't physically exists until it's actual "built" by the xcode
|
||||||
PBXFileReference = class(PBXObject)
|
PBXFileReference = class(PBXObject)
|
||||||
private
|
private
|
||||||
FexplicitFileType: string;
|
FexplicitFileType: string;
|
||||||
FincludeInIndex: string;
|
FincludeInIndex: Boolean;
|
||||||
FlastKnownFileType: string;
|
FlastKnownFileType: string;
|
||||||
Fname: string;
|
Fname: string;
|
||||||
Fpath: string;
|
Fpath: string;
|
||||||
FsourceTree: string;
|
FsourceTree: string;
|
||||||
published
|
published
|
||||||
property explicitFileType: string read FexplicitFileType write FexplicitFileType;
|
property explicitFileType: string read FexplicitFileType write FexplicitFileType;
|
||||||
property includeInIndex: string read FincludeInIndex write FincludeInIndex;
|
property includeInIndex: Boolean read FincludeInIndex write FincludeInIndex;
|
||||||
property lastKnownFileType: string read flastKnownFileType write flastKnownFileType;
|
property lastKnownFileType: string read flastKnownFileType write flastKnownFileType;
|
||||||
property name: string read Fname write Fname;
|
property name: string read Fname write Fname;
|
||||||
property path: string read Fpath write Fpath;
|
property path: string read Fpath write Fpath;
|
||||||
@ -135,6 +148,7 @@ type
|
|||||||
foutputPaths: TPBXStringArray;
|
foutputPaths: TPBXStringArray;
|
||||||
fshellpath: string;
|
fshellpath: string;
|
||||||
fshellScript: string;
|
fshellScript: string;
|
||||||
|
fshowEnvVarsInLog: Boolean;
|
||||||
public
|
public
|
||||||
constructor Create; override;
|
constructor Create; override;
|
||||||
destructor Destroy; override;
|
destructor Destroy; override;
|
||||||
@ -143,6 +157,7 @@ type
|
|||||||
property outputPaths: TPBXStringArray read foutputPaths;
|
property outputPaths: TPBXStringArray read foutputPaths;
|
||||||
property shellPath: string read fshellpath write fshellPath;
|
property shellPath: string read fshellpath write fshellPath;
|
||||||
property shellScript: string read fshellScript write fshellScript;
|
property shellScript: string read fshellScript write fshellScript;
|
||||||
|
property showEnvVarsInLog: Boolean read fshowEnvVarsInLog write fshowEnvVarsInLog default true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ PBXGroup }
|
{ PBXGroup }
|
||||||
@ -197,10 +212,27 @@ type
|
|||||||
property dependencies: TPBXObjectsList read fdependencies;
|
property dependencies: TPBXObjectsList read fdependencies;
|
||||||
property name: string read fname write fname;
|
property name: string read fname write fname;
|
||||||
property productName: string read fproductName write fproductName; // = ttestGame;
|
property productName: string read fproductName write fproductName; // = ttestGame;
|
||||||
property productReference: PBXObject read fproductReference write fproductReference; // = 0AFA6EAD19F60EFE004C8FD9 /* ttestGame.app */;
|
property productReference: PBXObject read fproductReference write fproductReference; // producut resulting file
|
||||||
property productType: string read fproductType write fproductType; // = "com.apple.product-type.application";
|
property productType: string read fproductType write fproductType; // = "com.apple.product-type.application";
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{ PBXLegacyTarget }
|
||||||
|
|
||||||
|
PBXLegacyTarget = class(PBXObject)
|
||||||
|
private
|
||||||
|
fpassBuildSettingsInEnvironment : Boolean;
|
||||||
|
fbuildArgumentsString : string;
|
||||||
|
fbuildToolPath : string;
|
||||||
|
fbuildWorkingDirectory : string;
|
||||||
|
public
|
||||||
|
constructor Create; override;
|
||||||
|
published
|
||||||
|
property buildArgumentsString: string read fbuildArgumentsString write fbuildArgumentsString;
|
||||||
|
property buildToolPath: string read fbuildToolPath write fbuildToolPath;
|
||||||
|
property buildWorkingDirectory: string read fbuildWorkingDirectory write fbuildWorkingDirectory;
|
||||||
|
property passBuildSettingsInEnvironment: Boolean read fpassBuildSettingsInEnvironment write fpassBuildSettingsInEnvironment;
|
||||||
|
end;
|
||||||
|
|
||||||
{ PBXTargetDependency }
|
{ PBXTargetDependency }
|
||||||
|
|
||||||
// mmgt:
|
// mmgt:
|
||||||
@ -285,19 +317,28 @@ const
|
|||||||
//FILETYPE_SCRIPT = 'text.script.sh';
|
//FILETYPE_SCRIPT = 'text.script.sh';
|
||||||
FILETYPE_EXEC = 'compiled.mach-o.executable';
|
FILETYPE_EXEC = 'compiled.mach-o.executable';
|
||||||
FILETYPE_MACHO = FILETYPE_EXEC;
|
FILETYPE_MACHO = FILETYPE_EXEC;
|
||||||
|
FILETYPE_BUNDLE = 'wrapper.application';
|
||||||
|
FILETYPE_PLIST = 'text.plist.xml';
|
||||||
|
FILETYPE_OBJC = 'sourcecode.c.objc';
|
||||||
|
|
||||||
function FileRefCreate(const afilename: string; const filetype: string = ''): PBXFileReference;
|
function FileRefCreate(const afilename: string; const filetype: string = ''): PBXFileReference;
|
||||||
|
|
||||||
const
|
const
|
||||||
GROUPSRC_ABSOLUTE = '<absolute>';
|
SRCTREE_ABSOLUTE = '<absolute>'; // path is absolute path
|
||||||
GROUPSRC_GROUP = '<group>';
|
SRCTREE_GROUP = '<group>'; // path is relative to the parent group
|
||||||
|
SRCTREE_PRODUCT = 'BUILT_PRODUCTS_DIR'; // path is relative to the product build directory
|
||||||
|
SRCTREE_PROJECT = 'SOURCE_ROOT'; // path is relative for .xcodeproj directory location
|
||||||
|
SRCTREE_DEV = 'DEVELOPER_DIR'; // path is relative to developer dir
|
||||||
|
SRCTREE_SDK = 'SDKROOT'; // path is relative to selected SDK dir
|
||||||
|
|
||||||
function GroupCreate(const aname: string; const srcTree: string = GROUPSRC_GROUP): PBXGroup;
|
function GroupCreate(const aname: string; const srcTree: string = SRCTREE_GROUP): PBXGroup;
|
||||||
//todo: need a rountine to update the path whenever the project is saved
|
//todo: need a rountine to update the path whenever the project is saved
|
||||||
function GroupCreateRoot(const projectfolder: string = ''): PBXGroup;
|
function GroupCreateRoot(const projectfolder: string = ''): PBXGroup;
|
||||||
|
|
||||||
const
|
const
|
||||||
PRODTYPE_TOOL = 'com.apple.product-type.tool';
|
PRODTYPE_TOOL = 'com.apple.product-type.tool';
|
||||||
|
PRODTYPE_APP = 'com.apple.product-type.application'; // use it for OSX / iOS app targets
|
||||||
|
// prodtype of app type should have productReference to the result bundle! (.app) file
|
||||||
|
|
||||||
//
|
//
|
||||||
// PBXSourcesBuildPhase (sources) - is part of a PBXNativeTarget
|
// PBXSourcesBuildPhase (sources) - is part of a PBXNativeTarget
|
||||||
@ -309,9 +350,38 @@ const
|
|||||||
//0AA67B671A04929900CF0DD7 /* CopyFiles */,
|
//0AA67B671A04929900CF0DD7 /* CopyFiles */,
|
||||||
//);
|
//);
|
||||||
|
|
||||||
|
const
|
||||||
|
TARGET_IOS_8_0 = '8.0';
|
||||||
|
TARGET_IOS_8_1 = '8.1';
|
||||||
|
|
||||||
|
procedure ConfigIOS(cfg: XCBuildConfiguration; const targetiOS: string);
|
||||||
|
|
||||||
|
const
|
||||||
|
CFG_SDKROOT = 'SDKROOT';
|
||||||
|
CFG_IOSTRG = 'IPHONEOS_DEPLOYMENT_TARGET';
|
||||||
|
CFG_DEVICE = 'TARGET_DEVICE_FAMILY';
|
||||||
|
CFG_DEVICE_ALL = '1,2';
|
||||||
|
CFG_DEVICE_IPHONE = '1';
|
||||||
|
CFG_DEVICE_IPAD = '2';
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
procedure ConfigIOS(cfg: XCBuildConfiguration; const targetiOS: string);
|
||||||
|
begin
|
||||||
|
if not Assigned(cfg) then Exit;
|
||||||
|
cfg.buildSettings.AddStr(CFG_IOSTRG, targetiOS);
|
||||||
|
cfg.buildSettings.AddStr(CFG_SDKROOT, 'iphoneos');
|
||||||
|
cfg.buildSettings.AddStr(CFG_DEVICE, CFG_DEVICE_ALL);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ PBXLegacyTarget }
|
||||||
|
|
||||||
|
constructor PBXLegacyTarget.Create;
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
fpassBuildSettingsInEnvironment:=true;
|
||||||
|
end;
|
||||||
|
|
||||||
{ PBXTargetDependency }
|
{ PBXTargetDependency }
|
||||||
|
|
||||||
destructor PBXTargetDependency.Destroy;
|
destructor PBXTargetDependency.Destroy;
|
||||||
@ -388,12 +458,22 @@ begin
|
|||||||
targets.Add(Result);
|
targets.Add(Result);
|
||||||
Result._headerComment:=aname;
|
Result._headerComment:=aname;
|
||||||
Result.name:=aname;
|
Result.name:=aname;
|
||||||
// productName?
|
Result.productName:=aname;
|
||||||
// productReference - is a resulting file
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{ XCConfigurationList }
|
{ XCConfigurationList }
|
||||||
|
|
||||||
|
function XCConfigurationList.GetConfigItem(i: integer): XCBuildConfiguration;
|
||||||
|
begin
|
||||||
|
if (i<0) or (i>=fbuildConfigurations.Count) then Result:=nil
|
||||||
|
else Result:=XCBuildConfiguration(fbuildConfigurations[i]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function XCConfigurationList.GetCount: integer;
|
||||||
|
begin
|
||||||
|
Result:=fbuildConfigurations.Count;
|
||||||
|
end;
|
||||||
|
|
||||||
constructor XCConfigurationList.Create;
|
constructor XCConfigurationList.Create;
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
@ -406,7 +486,8 @@ begin
|
|||||||
inherited Destroy;
|
inherited Destroy;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function XCConfigurationList.AddConfig(const aname: string): XCBuildConfiguration;
|
function XCConfigurationList.addConfig(const aname: string
|
||||||
|
): XCBuildConfiguration;
|
||||||
begin
|
begin
|
||||||
Result:=XCBuildConfiguration.Create;
|
Result:=XCBuildConfiguration.Create;
|
||||||
Result.name:=aname;
|
Result.name:=aname;
|
||||||
@ -448,7 +529,7 @@ begin
|
|||||||
fchildren.Add(Result);
|
fchildren.Add(Result);
|
||||||
Result.name:=aname;
|
Result.name:=aname;
|
||||||
Result._headerComment:=aname;
|
Result._headerComment:=aname;
|
||||||
Result.sourceTree:=GROUPSRC_GROUP;
|
Result.sourceTree:=SRCTREE_GROUP;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function PBXGroup.findGroup(const aname: string): PBXGroup;
|
function PBXGroup.findGroup(const aname: string): PBXGroup;
|
||||||
@ -536,7 +617,7 @@ begin
|
|||||||
p.buildConfigurationList._headerComment:='Build configuration list for PBXProject';
|
p.buildConfigurationList._headerComment:='Build configuration list for PBXProject';
|
||||||
p.buildConfigurationList.defaultConfigurationIsVisible:='0';
|
p.buildConfigurationList.defaultConfigurationIsVisible:='0';
|
||||||
|
|
||||||
cfg:=p.buildConfigurationList.addConfig('Default');
|
cfg:=p.buildConfigurationList.addConfig('Debug');
|
||||||
cfg:=p.buildConfigurationList.addConfig('Release');
|
cfg:=p.buildConfigurationList.addConfig('Release');
|
||||||
// default name must be present
|
// default name must be present
|
||||||
p.buildConfigurationList.defaultConfigurationName:='Release';
|
p.buildConfigurationList.defaultConfigurationName:='Release';
|
||||||
@ -609,7 +690,7 @@ end;
|
|||||||
|
|
||||||
function GroupCreateRoot(const projectfolder: string): PBXGroup;
|
function GroupCreateRoot(const projectfolder: string): PBXGroup;
|
||||||
begin
|
begin
|
||||||
Result:=GroupCreate('', GROUPSRC_ABSOLUTE);
|
Result:=GroupCreate('', SRCTREE_GROUP);
|
||||||
Result.path:=projectfolder;
|
Result.path:=projectfolder;
|
||||||
Result._headerComment:=projectfolder;
|
Result._headerComment:=projectfolder;
|
||||||
end;
|
end;
|
||||||
|
55
components/iphonelazext/pbx/xcodeprojutils.pas
Normal file
55
components/iphonelazext/pbx/xcodeprojutils.pas
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
unit xcodeprojutils;
|
||||||
|
|
||||||
|
{$mode delphi}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Classes, SysUtils, xcodeproj;
|
||||||
|
|
||||||
|
// proj name is used for ".xcodeprj" bundle-directory
|
||||||
|
// hostdir is the hosting directory for the project
|
||||||
|
// prj - the content of the project
|
||||||
|
function ProjectWriteStruct(prj: PBXProject; const projName: string; const HostDir: string): Boolean;
|
||||||
|
|
||||||
|
const
|
||||||
|
ProjExt = '.xcodeproj';
|
||||||
|
ProjFileName = 'project.pbxproj';
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function ProjectWriteStruct(prj: PBXProject; const projName: string; const HostDir: string): Boolean;
|
||||||
|
var
|
||||||
|
prjdir : string;
|
||||||
|
s : string;
|
||||||
|
fs : TFileStream;
|
||||||
|
fn : string;
|
||||||
|
begin
|
||||||
|
if HostDir = ''
|
||||||
|
then prjdir:=IncludeTrailingPathDelimiter(GetCurrentDir)+projName+ProjExt
|
||||||
|
else prjdir:=IncludeTrailingPathDelimiter(HostDir)+projName+ProjExt;
|
||||||
|
|
||||||
|
Result:=ForceDirectories(prjdir);
|
||||||
|
if not Result then Exit;
|
||||||
|
fn:=IncludeTrailingPathDelimiter(prjdir)+ProjFileName;
|
||||||
|
|
||||||
|
s:=ProjectWrite(prj);
|
||||||
|
|
||||||
|
try
|
||||||
|
fs:=TFileStream.Create(fn, fmCreate);
|
||||||
|
try
|
||||||
|
if length(s)>0 then begin
|
||||||
|
fs.Write(s[1], length(s));
|
||||||
|
fs.Size:=length(s);
|
||||||
|
end;
|
||||||
|
Result:=true;
|
||||||
|
finally
|
||||||
|
fs.Free;
|
||||||
|
end;
|
||||||
|
except
|
||||||
|
Result:=false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -1,57 +1,59 @@
|
|||||||
inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
object iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
||||||
Height = 474
|
Left = 0
|
||||||
Width = 620
|
Height = 466
|
||||||
ClientHeight = 474
|
Top = 0
|
||||||
ClientWidth = 620
|
Width = 598
|
||||||
|
ClientHeight = 466
|
||||||
|
ClientWidth = 598
|
||||||
OnClick = FrameClick
|
OnClick = FrameClick
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
DesignLeft = 513
|
DesignLeft = 408
|
||||||
DesignTop = 97
|
DesignTop = 201
|
||||||
object chkisPhone: TCheckBox[0]
|
object chkisPhone: TCheckBox
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 18
|
||||||
Top = 16
|
Top = 16
|
||||||
Width = 199
|
Width = 191
|
||||||
Caption = 'is iPhone application project'
|
Caption = 'is iPhone application project'
|
||||||
OnChange = chkisPhoneChange
|
OnChange = chkisPhoneChange
|
||||||
TabOrder = 0
|
TabOrder = 0
|
||||||
end
|
end
|
||||||
object lblAppID: TLabel[1]
|
object lblAppID: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 16
|
||||||
Top = 88
|
Top = 88
|
||||||
Width = 87
|
Width = 89
|
||||||
Caption = 'Application ID'
|
Caption = 'Application ID'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object edtAppID: TEdit[2]
|
object edtAppID: TEdit
|
||||||
Left = 112
|
Left = 112
|
||||||
Height = 22
|
Height = 22
|
||||||
Top = 85
|
Top = 85
|
||||||
Width = 490
|
Width = 468
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
TabOrder = 1
|
TabOrder = 1
|
||||||
Text = 'com.mycompany.myapp'
|
Text = 'com.mycompany.myapp'
|
||||||
end
|
end
|
||||||
object lblAppIDHint: TLabel[3]
|
object lblAppIDHint: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 14
|
Height = 12
|
||||||
Top = 117
|
Top = 117
|
||||||
Width = 493
|
Width = 497
|
||||||
Caption = 'It''s recommended by Apple to use domain-structured name, i.e. com.mycompany.myApplication as ID'
|
Caption = 'It''s recommended by Apple to use domain-structured name, i.e. com.mycompany.myApplication as ID'
|
||||||
Font.Height = -10
|
Font.Height = -10
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
ParentFont = False
|
ParentFont = False
|
||||||
end
|
end
|
||||||
object lblSDKVer: TLabel[4]
|
object lblSDKVer: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 16
|
||||||
Top = 51
|
Top = 51
|
||||||
Width = 80
|
Width = 79
|
||||||
Caption = 'SDK version:'
|
Caption = 'SDK version:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object cmbSDKs: TComboBox[5]
|
object cmbSDKs: TComboBox
|
||||||
Left = 112
|
Left = 112
|
||||||
Height = 20
|
Height = 20
|
||||||
Top = 48
|
Top = 48
|
||||||
@ -61,12 +63,12 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
|||||||
Style = csDropDownList
|
Style = csDropDownList
|
||||||
TabOrder = 2
|
TabOrder = 2
|
||||||
end
|
end
|
||||||
object edtResDir: TEdit[6]
|
object edtResDir: TEdit
|
||||||
AnchorSideRight.Control = btnShowInFinder
|
AnchorSideRight.Control = btnShowInFinder
|
||||||
Left = 120
|
Left = 120
|
||||||
Height = 22
|
Height = 22
|
||||||
Top = 174
|
Top = 174
|
||||||
Width = 355
|
Width = 332
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
BorderSpacing.Right = 10
|
BorderSpacing.Right = 10
|
||||||
OnChange = edtResDirChange
|
OnChange = edtResDirChange
|
||||||
@ -74,56 +76,56 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
|||||||
TabOrder = 3
|
TabOrder = 3
|
||||||
Text = 'Resources'
|
Text = 'Resources'
|
||||||
end
|
end
|
||||||
object Label1: TLabel[7]
|
object Label1: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 16
|
||||||
Top = 176
|
Top = 176
|
||||||
Width = 89
|
Width = 89
|
||||||
Caption = 'Resources dir:'
|
Caption = 'Resources dir:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object edtExclude: TEdit[8]
|
object edtExclude: TEdit
|
||||||
Left = 120
|
Left = 120
|
||||||
Height = 22
|
Height = 22
|
||||||
Top = 224
|
Top = 224
|
||||||
Width = 482
|
Width = 460
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
OnChange = edtExcludeChange
|
OnChange = edtExcludeChange
|
||||||
TabOrder = 4
|
TabOrder = 4
|
||||||
Text = '.svn'
|
Text = '.svn'
|
||||||
end
|
end
|
||||||
object Label2: TLabel[9]
|
object Label2: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 16
|
||||||
Top = 224
|
Top = 224
|
||||||
Width = 81
|
Width = 82
|
||||||
Caption = 'Ignore mask:'
|
Caption = 'Ignore mask:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object Label3: TLabel[10]
|
object Label3: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 14
|
Height = 12
|
||||||
Top = 200
|
Top = 200
|
||||||
Width = 364
|
Width = 359
|
||||||
Caption = 'It''s recommended to set resource dir as a relative (to project .lpr file) path'
|
Caption = 'It''s recommended to set resource dir as a relative (to project .lpr file) path'
|
||||||
Font.Height = -10
|
Font.Height = -10
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
ParentFont = False
|
ParentFont = False
|
||||||
end
|
end
|
||||||
object Label4: TLabel[11]
|
object Label4: TLabel
|
||||||
Left = 16
|
Left = 16
|
||||||
Height = 18
|
Height = 16
|
||||||
Top = 256
|
Top = 256
|
||||||
Width = 54
|
Width = 56
|
||||||
Caption = 'Nib files:'
|
Caption = 'Nib files:'
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
end
|
end
|
||||||
object nibFilesBox: TCheckListBox[12]
|
object nibFilesBox: TCheckListBox
|
||||||
Left = 120
|
Left = 120
|
||||||
Height = 180
|
Height = 76
|
||||||
Top = 256
|
Top = 256
|
||||||
Width = 482
|
Width = 460
|
||||||
Anchors = [akTop, akLeft, akRight, akBottom]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
ItemHeight = 0
|
ItemHeight = 0
|
||||||
OnClickCheck = nibFilesBoxClickCheck
|
OnClickCheck = nibFilesBoxClickCheck
|
||||||
OnItemClick = nibFilesBoxItemClick
|
OnItemClick = nibFilesBoxItemClick
|
||||||
@ -132,54 +134,71 @@ inherited iPhoneProjectOptionsEditor: TiPhoneProjectOptionsEditor
|
|||||||
PopupMenu = nibsPopup
|
PopupMenu = nibsPopup
|
||||||
TabOrder = 5
|
TabOrder = 5
|
||||||
end
|
end
|
||||||
object Label5: TLabel[13]
|
object Label5: TLabel
|
||||||
AnchorSideTop.Control = nibFilesBox
|
AnchorSideTop.Control = nibFilesBox
|
||||||
AnchorSideTop.Side = asrBottom
|
AnchorSideTop.Side = asrBottom
|
||||||
Left = 120
|
Left = 120
|
||||||
Height = 14
|
Height = 12
|
||||||
Top = 436
|
Top = 332
|
||||||
Width = 246
|
Width = 247
|
||||||
Caption = 'The checked one is the main Nib of the application'
|
Caption = 'The checked one is the main Nib of the application'
|
||||||
Font.Height = -10
|
Font.Height = -10
|
||||||
ParentColor = False
|
ParentColor = False
|
||||||
ParentFont = False
|
ParentFont = False
|
||||||
end
|
end
|
||||||
object btnShowInFinder: TButton[14]
|
object btnShowInFinder: TButton
|
||||||
Left = 485
|
Left = 462
|
||||||
Height = 20
|
Height = 20
|
||||||
Top = 176
|
Top = 176
|
||||||
Width = 117
|
Width = 118
|
||||||
Anchors = [akTop, akRight]
|
Anchors = [akTop, akRight]
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
Caption = 'Show in Finder'
|
Caption = 'Show in Finder'
|
||||||
OnClick = btnShowInFinderClick
|
OnClick = btnShowInFinderClick
|
||||||
TabOrder = 6
|
TabOrder = 6
|
||||||
end
|
end
|
||||||
object btnAddXib: TButton[15]
|
object btnAddXib: TButton
|
||||||
AnchorSideLeft.Control = btnRemoveXib
|
AnchorSideLeft.Control = btnRemoveXib
|
||||||
AnchorSideRight.Control = btnRemoveXib
|
AnchorSideRight.Control = btnRemoveXib
|
||||||
AnchorSideRight.Side = asrBottom
|
AnchorSideRight.Side = asrBottom
|
||||||
Left = 40
|
Left = 40
|
||||||
Height = 20
|
Height = 20
|
||||||
Top = 283
|
Top = 283
|
||||||
Width = 74
|
Width = 77
|
||||||
Anchors = [akTop, akLeft, akRight]
|
Anchors = [akTop, akLeft, akRight]
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
Caption = 'Add'
|
Caption = 'Add'
|
||||||
OnClick = btnAddXibClick
|
OnClick = btnAddXibClick
|
||||||
TabOrder = 7
|
TabOrder = 7
|
||||||
end
|
end
|
||||||
object btnRemoveXib: TButton[16]
|
object btnRemoveXib: TButton
|
||||||
Left = 40
|
Left = 40
|
||||||
Height = 20
|
Height = 20
|
||||||
Top = 312
|
Top = 312
|
||||||
Width = 74
|
Width = 77
|
||||||
AutoSize = True
|
AutoSize = True
|
||||||
Caption = 'Remove'
|
Caption = 'Remove'
|
||||||
OnClick = btnRemoveXibClick
|
OnClick = btnRemoveXibClick
|
||||||
TabOrder = 8
|
TabOrder = 8
|
||||||
end
|
end
|
||||||
object nibsPopup: TPopupMenu[17]
|
object memResFiles: TMemo
|
||||||
|
Left = 120
|
||||||
|
Height = 106
|
||||||
|
Top = 352
|
||||||
|
Width = 458
|
||||||
|
Anchors = [akTop, akLeft, akRight, akBottom]
|
||||||
|
ScrollBars = ssVertical
|
||||||
|
TabOrder = 9
|
||||||
|
end
|
||||||
|
object Label6: TLabel
|
||||||
|
Left = 16
|
||||||
|
Height = 16
|
||||||
|
Top = 352
|
||||||
|
Width = 90
|
||||||
|
Caption = 'Included Files:'
|
||||||
|
ParentColor = False
|
||||||
|
end
|
||||||
|
object nibsPopup: TPopupMenu
|
||||||
OnPopup = nibsPopupPopup
|
OnPopup = nibsPopupPopup
|
||||||
left = 160
|
left = 160
|
||||||
top = 272
|
top = 272
|
||||||
|
@ -21,7 +21,8 @@ interface
|
|||||||
uses
|
uses
|
||||||
Classes,SysUtils,FileUtil,LResources,Forms,StdCtrls,CheckLst,Buttons, Dialogs,
|
Classes,SysUtils,FileUtil,LResources,Forms,StdCtrls,CheckLst,Buttons, Dialogs,
|
||||||
Menus,IDEOptionsIntf,ProjectIntf,LazIDEIntf,iPhoneExtStr,
|
Menus,IDEOptionsIntf,ProjectIntf,LazIDEIntf,iPhoneExtStr,
|
||||||
iPhoneExtOptions, Controls, LazFilesUtils, XcodeUtils, newXibDialog, xibfile;
|
iPhoneExtOptions, Controls, LazFilesUtils, XcodeUtils, newXibDialog, xibfile
|
||||||
|
,CompOptsIntf;
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
||||||
@ -32,6 +33,8 @@ type
|
|||||||
btnAddXib:TButton;
|
btnAddXib:TButton;
|
||||||
btnRemoveXib:TButton;
|
btnRemoveXib:TButton;
|
||||||
Label5:TLabel;
|
Label5:TLabel;
|
||||||
|
Label6: TLabel;
|
||||||
|
memResFiles: TMemo;
|
||||||
mnuDump:TMenuItem;
|
mnuDump:TMenuItem;
|
||||||
mnuOpenIB:TMenuItem;
|
mnuOpenIB:TMenuItem;
|
||||||
nibFilesBox:TCheckListBox;
|
nibFilesBox:TCheckListBox;
|
||||||
@ -72,8 +75,8 @@ type
|
|||||||
SelXibFile : String;
|
SelXibFile : String;
|
||||||
ResDirChanged : Boolean;
|
ResDirChanged : Boolean;
|
||||||
|
|
||||||
fOnChanged : TNotifyEvent;
|
//fOnChanged : TNotifyEvent;
|
||||||
procedure DoChanged;
|
//procedure DoChanged;
|
||||||
|
|
||||||
procedure RefreshXIBList;
|
procedure RefreshXIBList;
|
||||||
|
|
||||||
@ -86,7 +89,7 @@ type
|
|||||||
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
|
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
|
||||||
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
|
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
|
||||||
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
|
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
|
||||||
property OnChanged: TNotifyEvent read fOnChanged write fOnChanged;
|
//property OnChanged: TNotifyEvent read fOnChanged write fOnChanged;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -281,10 +284,10 @@ begin
|
|||||||
mnuDump.Enabled:=SelXibFile<>''
|
mnuDump.Enabled:=SelXibFile<>''
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TiPhoneProjectOptionsEditor.DoChanged;
|
//procedure TiPhoneProjectOptionsEditor.DoChanged;
|
||||||
begin
|
//begin
|
||||||
if Assigned(fOnChanged) then fOnChanged(Self);
|
//if Assigned(fOnChanged) then fOnChanged(Self);
|
||||||
end;
|
//end;
|
||||||
|
|
||||||
procedure TiPhoneProjectOptionsEditor.RefreshXIBList;
|
procedure TiPhoneProjectOptionsEditor.RefreshXIBList;
|
||||||
var
|
var
|
||||||
@ -513,7 +516,7 @@ procedure TiPhoneProjectOptionsEditor.ReadSettings(AOptions: TAbstractIDEOptions
|
|||||||
var
|
var
|
||||||
i : Integer;
|
i : Integer;
|
||||||
begin
|
begin
|
||||||
with TiPhoneProjectOptions(AOptions) do
|
with ProjOptions do
|
||||||
begin
|
begin
|
||||||
Load;
|
Load;
|
||||||
chkisPhone.Checked:=isIPhoneApp;
|
chkisPhone.Checked:=isIPhoneApp;
|
||||||
@ -526,14 +529,16 @@ begin
|
|||||||
edtAppID.Text:=AppID;
|
edtAppID.Text:=AppID;
|
||||||
edtResDir.Text:=ResourceDir;
|
edtResDir.Text:=ResourceDir;
|
||||||
edtExclude.Text:=ExcludeMask;
|
edtExclude.Text:=ExcludeMask;
|
||||||
|
memResFiles.Text:=ResFiles.Text;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
RefreshXIBList;
|
RefreshXIBList;
|
||||||
if TiPhoneProjectOptions(AOptions).MainNib<>'' then begin
|
if ProjOptions.MainNib<>'' then begin
|
||||||
i:=nibFilesBox.Items.IndexOf(TiPhoneProjectOptions(AOptions).MainNib);
|
i:=nibFilesBox.Items.IndexOf(ProjOptions.MainNib);
|
||||||
if i>=0 then nibFilesBox.Checked[i]:=True;
|
if i>=0 then nibFilesBox.Checked[i]:=True;
|
||||||
end;
|
end;
|
||||||
SetControlsEnabled(chkisPhone.Checked); // is iPhone project
|
SetControlsEnabled(chkisPhone.Checked); // is iPhone project
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TiPhoneProjectOptionsEditor.WriteSettings(AOptions: TAbstractIDEOptions);
|
procedure TiPhoneProjectOptionsEditor.WriteSettings(AOptions: TAbstractIDEOptions);
|
||||||
@ -548,7 +553,7 @@ begin
|
|||||||
Break;
|
Break;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
with TiPhoneProjectOptions(AOptions) do
|
with ProjOptions do
|
||||||
begin
|
begin
|
||||||
isIPhoneApp:=chkisPhone.Checked;
|
isIPhoneApp:=chkisPhone.Checked;
|
||||||
SDK:=cmbSDKs.Caption;
|
SDK:=cmbSDKs.Caption;
|
||||||
@ -556,14 +561,16 @@ begin
|
|||||||
ResourceDir:=edtResDir.Text;
|
ResourceDir:=edtResDir.Text;
|
||||||
ExcludeMask:=edtExclude.Text;
|
ExcludeMask:=edtExclude.Text;
|
||||||
MainNib:=amainnib;
|
MainNib:=amainnib;
|
||||||
|
ResFiles.Text:=memResFiles.Text;
|
||||||
Save;
|
Save;
|
||||||
DoChanged;
|
|
||||||
end;
|
end;
|
||||||
|
DoOnChange;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
class function TiPhoneProjectOptionsEditor.SupportedOptionsClass: TAbstractIDEOptionsClass;
|
class function TiPhoneProjectOptionsEditor.SupportedOptionsClass: TAbstractIDEOptionsClass;
|
||||||
begin
|
begin
|
||||||
Result:=TiPhoneProjectOptions;
|
//Result:=TiPhoneProjectOptions;
|
||||||
|
Result:=TLazCompilerOptions;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
@ -19,9 +19,13 @@ unit xcodetemplate;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
Classes, SysUtils, contnrs;
|
Classes, SysUtils, contnrs, xcodeproj;
|
||||||
|
|
||||||
procedure PrepareTemplateFile(Src, TemplateValues: TStrings; BuildSettings: TFPStringHashTable);
|
procedure PrepareTemplateFile_(Src, TemplateValues: TStrings; BuildSettings: TFPStringHashTable);
|
||||||
|
procedure PrepareTemplateFile(Src, TemplateValues: TStrings);
|
||||||
|
procedure UpdateBldConfig(const proj: PBXProject; optName, optVal: string);
|
||||||
|
procedure UpdateMainFile(const proj: PBXProject; mainfile: string);
|
||||||
|
procedure UpdateCompileOpts(const proj: PBXProject; options: string);
|
||||||
|
|
||||||
const
|
const
|
||||||
XCodeProjectTemplateIconID : AnsiString ='0AE3FFA610F3C9AF00A9B007,';
|
XCodeProjectTemplateIconID : AnsiString ='0AE3FFA610F3C9AF00A9B007,';
|
||||||
@ -141,10 +145,10 @@ const
|
|||||||
' COPY_PHASE_STRIP = YES;'#10+
|
' COPY_PHASE_STRIP = YES;'#10+
|
||||||
' FPC_OUTPUT_FILE = $BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH;'#10+
|
' FPC_OUTPUT_FILE = $BUILT_PRODUCTS_DIR/$EXECUTABLE_PATH;'#10+
|
||||||
' FPC_COMPILER_OPTIONS = "-Parm -o$FPC_OUTPUT_FILE $FPC_CUSTOM_OPTIONS";'#10+
|
' FPC_COMPILER_OPTIONS = "-Parm -o$FPC_OUTPUT_FILE $FPC_CUSTOM_OPTIONS";'#10+
|
||||||
' "FPC_COMPILER_OPTIONS[sdk=iphonesimulator*]" = "-Tiphonesim -Pi386 -o$FPC_OUTPUT_FILE $FPC_CUSTOM_OPTIONS";'#10+
|
' "FPC_COMPILER_OPTIONS[sdk=iphonesimulator*]" = "-Tiphonesim -Pi386 -o$FPC_OUTPUT_FILE $FPC_CUSTOM_OPTIONS";'#10+
|
||||||
' FPC_COMPILER_PATH = ;'#10+
|
' FPC_COMPILER_PATH = ;'#10+
|
||||||
' FPC_CUSTOM_OPTIONS = ;'#10+
|
' FPC_CUSTOM_OPTIONS = ;'#10+
|
||||||
' "FPC_CUSTOM_OPTIONS[sdk=iphonesimulator*]" = ;'#10+
|
' "FPC_CUSTOM_OPTIONS[sdk=iphonesimulator*]" = ;'#10+
|
||||||
' FPC_MAIN_FILE = ;'#10+
|
' FPC_MAIN_FILE = ;'#10+
|
||||||
' SDKROOT = iphoneos2.0;'#10+
|
' SDKROOT = iphoneos2.0;'#10+
|
||||||
' VALID_ARCHS = "armv6 armv7";'#10+
|
' VALID_ARCHS = "armv6 armv7";'#10+
|
||||||
@ -199,6 +203,41 @@ const
|
|||||||
' rootObject = 0A52AE8310F0D05300478C4F /* Project object */;'#10+
|
' rootObject = 0A52AE8310F0D05300478C4F /* Project object */;'#10+
|
||||||
'}'#10;
|
'}'#10;
|
||||||
|
|
||||||
|
BuildScript =
|
||||||
|
'## start'#13
|
||||||
|
+'echo "compiling FPC project"'#13
|
||||||
|
+''#13
|
||||||
|
+'export RESULT_EXE=${BUILT_PRODUCTS_DIR}/${EXECUTABLE_PATH}'#13
|
||||||
|
+'export IOSHEADERS='#13
|
||||||
|
+'cd $FPC_MAIN_DIR'#13
|
||||||
|
+'#rm $RESULT_EXE'#13
|
||||||
|
+'export TargetCPU=${PLATFORM_PREFERRED_ARCH}'#13
|
||||||
|
+''#13
|
||||||
|
+'if [ "${PLATFORM_NAME}" == "iphonesimulator" ]; then'#13
|
||||||
|
+' export TargetOS="iphonesim"'#13
|
||||||
|
+'fi'#13
|
||||||
|
+'export Target=${TargetCPU}-${TargetOS}'#13
|
||||||
|
+''#13
|
||||||
|
+'pwd'#13
|
||||||
|
+'echo ${RESULT_EXE}'#13
|
||||||
|
+''#13
|
||||||
|
+'${FPC_DIR}fpc -T${TargetOS} -P${TargetCPU} -MDelphi -Scghi -O1 -l -dIPHONEALL \'#13
|
||||||
|
+' ${FPC_CUSTOM_OPTIONS} \'#13
|
||||||
|
//-Fu~/iOS_6_0 -Fu.
|
||||||
|
+'-Filib/${Target} -FUlib/${Target} \'#13
|
||||||
|
+'-XR${SDKROOT} -FD${PLATFORM_DEVELOPER_BIN_DIR} $FPC_MAIN_FILE \'#13
|
||||||
|
+' -o${RESULT_EXE}'#13
|
||||||
|
+'export RES=$?'#13
|
||||||
|
+''#13
|
||||||
|
+'if [ $RES != 0 ]; then'#13
|
||||||
|
+' exit $RES'#13
|
||||||
|
+'fi'#13
|
||||||
|
+''#13
|
||||||
|
+'echo ${RESULT_EXE}'#13
|
||||||
|
+''#13
|
||||||
|
+'exit $FPCRES'#13;
|
||||||
|
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function GetValueName(const Source: String; idx: Integer): String;
|
function GetValueName(const Source: String; idx: Integer): String;
|
||||||
@ -244,7 +283,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure PrepareTemplateFile(Src, TemplateValues: TStrings; BuildSettings: TFPStringHashTable);
|
procedure PrepareTemplateFile_(Src, TemplateValues: TStrings; BuildSettings: TFPStringHashTable);
|
||||||
//todo: Better code to update XCode project file!
|
//todo: Better code to update XCode project file!
|
||||||
var
|
var
|
||||||
i, j : Integer;
|
i, j : Integer;
|
||||||
@ -286,6 +325,119 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure UpdateBldConfig(const proj: PBXProject; optName, optVal: string);
|
||||||
|
var
|
||||||
|
trg : PBXNativeTarget;
|
||||||
|
cfg : XCBuildConfiguration;
|
||||||
|
i : integer;
|
||||||
|
j : integer;
|
||||||
|
begin
|
||||||
|
for i:=0 to proj.targets.Count-1 do begin
|
||||||
|
trg := PBXNativeTarget(proj.targets[i]);
|
||||||
|
for j:=0 to trg.buildConfigurationList.Count-1 do begin
|
||||||
|
cfg:=XCBuildConfiguration(trg.buildConfigurationList.buildConfigurations[j]);
|
||||||
|
cfg.buildSettings.str[optName]:=optVal;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UpdateCompileOpts(const proj: PBXProject; options: string);
|
||||||
|
var
|
||||||
|
opt : string;
|
||||||
|
begin
|
||||||
|
//UpdateBldConfig(proj, 'FPC_CUSTOM_OPTIONS', options);
|
||||||
|
UpdateBldConfig(proj, 'FPC_CUSTOM_OPTIONS', '');
|
||||||
|
|
||||||
|
opt:=options;
|
||||||
|
opt:=StringReplace(opt,'$(TargetCPU)','$arch',[rfReplaceAll, rfIgnoreCase]);
|
||||||
|
opt:=StringReplace(opt,'$(TargetOS)','iphone',[rfReplaceAll, rfIgnoreCase]);
|
||||||
|
UpdateBldConfig(proj, 'FPC_CUSTOM_OPTIONS[sdk=iphoneos*]', opt);
|
||||||
|
|
||||||
|
opt:=options;
|
||||||
|
opt:=StringReplace(opt,'$(TargetCPU)','$arch',[rfReplaceAll, rfIgnoreCase]);
|
||||||
|
opt:=StringReplace(opt,'$(TargetOS)','iphonesim',[rfReplaceAll, rfIgnoreCase]);
|
||||||
|
UpdateBldConfig(proj, 'FPC_CUSTOM_OPTIONS[sdk=iphonesimulator*]', opt);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure UpdateMainFile(const proj: PBXProject; mainfile: string);
|
||||||
|
begin
|
||||||
|
UpdateBldConfig(proj, 'FPC_MAIN_FILE', mainfile);
|
||||||
|
UpdateBldConfig(proj, 'FPC_MAIN_DIR', ExtractFileDir(mainfile));
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure PrepareTemplateFile(Src, TemplateValues: TStrings);
|
||||||
|
var
|
||||||
|
prj : PBXProject;
|
||||||
|
trg : PBXNativeTarget;
|
||||||
|
cfg : XCBuildConfiguration;
|
||||||
|
fr : PBXFileReference;
|
||||||
|
grp : PBXGroup;
|
||||||
|
scr : PBXShellScriptBuildPhase;
|
||||||
|
i : integer;
|
||||||
|
plist : string;
|
||||||
|
targetName : string;
|
||||||
|
bundle : string;
|
||||||
|
main : string;
|
||||||
|
begin
|
||||||
|
prj:=ProjectCreate3_2;
|
||||||
|
|
||||||
|
targetName:=TemplateValues.Values['targetname'];
|
||||||
|
bundle:=TemplateValues.Values['bundle'];
|
||||||
|
plist:=TemplateValues.Values['plist'];
|
||||||
|
if plist='' then plist:='info.plist';
|
||||||
|
main:=TemplateValues.Values['mainfile'];
|
||||||
|
|
||||||
|
trg:=ProjectAddTarget(prj, targetName);
|
||||||
|
for i:=0 to prj.buildConfigurationList.Count-1 do begin
|
||||||
|
cfg:=prj.buildConfigurationList[i];
|
||||||
|
ConfigIOS(cfg, TARGET_IOS_8_1);
|
||||||
|
// Enable Build Active Architecture Only When Debugging
|
||||||
|
if cfg.name='Debug' then cfg.buildSettings.AddStr('ONLY_ACTIVE_ARCH','YES');
|
||||||
|
end;
|
||||||
|
|
||||||
|
// adding application type
|
||||||
|
trg.productName:=TemplateValues.Values['productname'];
|
||||||
|
trg.productType:=PRODTYPE_APP;
|
||||||
|
|
||||||
|
// target configuration
|
||||||
|
trg.buildConfigurationList:=XCConfigurationList.Create;
|
||||||
|
// Debug
|
||||||
|
cfg:=trg.buildConfigurationList.addConfig('Debug');
|
||||||
|
cfg.buildSettings.AddStr('INFOPLIST_FILE', '$(SRCROOT)/'+plist);
|
||||||
|
cfg.buildSettings.AddStr('PRODUCT_NAME', trg.productName);
|
||||||
|
// Build
|
||||||
|
cfg:=trg.buildConfigurationList.addConfig('Release');
|
||||||
|
cfg.buildSettings.AddStr('INFOPLIST_FILE', '$(SRCROOT)/'+plist);
|
||||||
|
cfg.buildSettings.AddStr('PRODUCT_NAME', trg.productName);
|
||||||
|
|
||||||
|
trg.buildConfigurationList.defaultConfigurationName:='Debug';
|
||||||
|
|
||||||
|
// Adding the ".app" directory for the bundle and bind it to the target
|
||||||
|
fr:=FileRefCreate(bundle, FILETYPE_MACHO);
|
||||||
|
fr.sourceTree:= SRCTREE_PRODUCT;
|
||||||
|
trg.productReference:=fr;
|
||||||
|
|
||||||
|
// Creating "content" for the directory. It should also contain .plist
|
||||||
|
grp:=prj.mainGroup.addSubGroup(targetName); // name must match to the target name!
|
||||||
|
grp:=grp.addSubGroup('Supporting Files'); // name must match!
|
||||||
|
|
||||||
|
// creating a reference to info.plist. It's located at "xcode" folder.
|
||||||
|
// Thus at the same directar as .xcodeproj dir
|
||||||
|
fr:=FileRefCreate(plist, FILETYPE_PLIST );
|
||||||
|
fr.sourceTree:=SRCTREE_PROJECT;
|
||||||
|
|
||||||
|
fr.path:=plist;
|
||||||
|
grp.children.Add( fr );
|
||||||
|
|
||||||
|
scr:=TargetAddRunScript(trg);
|
||||||
|
scr.shellScript:=BuildScript;
|
||||||
|
scr.showEnvVarsInLog:=true;
|
||||||
|
|
||||||
|
UpdateMainFile(prj, main);
|
||||||
|
UpdateCompileOpts(prj, TemplateValues.Values['projoptions']);
|
||||||
|
|
||||||
|
src.Text:=ProjectWrite(prj);
|
||||||
|
end;
|
||||||
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user