iphonelazext: updating existing xcode project, instead of recreating it from scratch

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@4582 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
skalogryz 2016-03-22 14:54:36 +00:00
parent 279a8cf1e7
commit 12c2780d5c
4 changed files with 78 additions and 17 deletions

View File

@ -383,7 +383,7 @@ var
build : TFPStringHashTable;
dir : string;
projdir : string;
proj : TStringList;
//proj : TStringList;
projname : string;
ext : string;
@ -442,7 +442,7 @@ begin
ForceDirectories(projdir);
projname:=IncludeTrailingPathDelimiter(projdir)+'project.pbxproj';
proj:=TStringList.Create;
//proj:=TStringList.Create;
templates:=nil;
try
templates:=TStringList.Create;
@ -467,18 +467,21 @@ begin
templates.Values['mainfile']:=LazarusIDE.ActiveProject.MainFile.Filename;
templates.Values['projoptions']:=opt;
PrepareTemplateFile(proj, templates, ProjOptions.ResFiles);
proj.SaveToFile(projname);
if not UpdateProject(projName, templates, ProjOptions.ResFiles) then
IDEMsg(Format(strXcodeUpdFailed,[projdir]))
else
IDEMsg(Format(strXcodeUpdated,[projdir]));
//PrepareTemplateFile(proj, templates, ProjOptions.ResFiles);
//proj.SaveToFile(projname);
except
on e: exception do
ShowMessage(e.Message);
end;
proj.Free;
//proj.Free;
templates.Free;
build.Free;
IDEMsg(Format(strXcodeUpdated,[projdir]));
end;
procedure SimRunDirect;

View File

@ -32,6 +32,7 @@ resourcestring
strPtrOptAppIDHint = 'It''s recommended by Apple to use domain-structured identifier i.e. "com.mycompany.myApplication"';
strXcodeUpdated = 'Xcode project updated (%s)';
strXcodeUpdFailed = 'Failed to update Xcode project (%s)';
strWNoSDKSelected = 'Warning: SDK is not selected using %s';
strWNoSDK = 'Warning: No SDK available. Linking might fail.';

View File

@ -294,6 +294,7 @@ type
function ProjectLoadFromStream(st: TStream; var prj: PBXProject): Boolean;
function ProjectLoadFromFile(const fn: string; var prj: PBXProject): Boolean;
function ProjectSaveToFile(prj: PBXProject; const fn: string): Boolean;
// serializes a PBX project to the string, using PBXContainer structure
function ProjectWrite(prj: PBXProject): string;
@ -376,14 +377,25 @@ const
CFG_DEVICE_IPHONE = '1';
CFG_DEVICE_IPAD = '2';
procedure SetNewStr(kv: TPBXKeyValue; const aname, avalue: string);
implementation
procedure SetNewStr(kv: TPBXKeyValue; const aname, avalue: string);
begin
if Assigned(kv) then begin
if kv.FindIndexOf(aname)<0 then
kv.AddStr(aname, avalue);
end;
end;
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);
SetNewStr(cfg.buildSettings, CFG_IOSTRG, targetiOS);
SetNewStr(cfg.buildSettings, CFG_SDKROOT, 'iphoneos');
SetNewStr(cfg.buildSettings, CFG_DEVICE, CFG_DEVICE_ALL);
end;
{ PBXLegacyTarget }
@ -649,6 +661,25 @@ begin
end;
end;
function ProjectSaveToFile(prj: PBXProject; const fn: string): Boolean;
var
fs : TFileStream;
s : string;
begin
s:=ProjectWrite(prj);
try
fs:=TFileStream.Create(fn, fmCreate);
try
if length(s)>0 then fs.Write(s[1], length(s));
finally
fs.Free;
end;
except
Result:=false;
end;
end;
function ProjectWrite(prj: PBXProject): string;
var
info : TPBXFileInfo;

View File

@ -24,6 +24,8 @@ uses
procedure PrepareTemplateFile_(Src, TemplateValues: TStrings; BuildSettings: TFPStringHashTable);
procedure PrepareTemplateFile(Src, TemplateValues, ResFiles: TStrings);
procedure PrepareTemplateFile(prj: PBXProject; TemplateValues, ResFiles: TStrings);
function UpdateProject(const ProjFileName: string; TemplateValues, ResFiles: TStrings): Boolean;
procedure UpdateBldConfig(const proj: PBXProject; optName, optVal: string);
procedure UpdateMainFile(const proj: PBXProject; mainfile: string);
procedure UpdateCompileOpts(const proj: PBXProject; options: string);
@ -430,7 +432,9 @@ begin
// it would be amd-32 for iPhone5 (and earlier)
// and amd-64 for iPhone6 (and later)
// Release requires to have a fat binary 32+64 amd, if target is less than iphone6
if cfg.name='Debug' then cfg.buildSettings.AddStr('ONLY_ACTIVE_ARCH','YES');
if (cfg.name='Debug') then begin
SetNewStr(cfg.buildSettings, 'ONLY_ACTIVE_ARCH', 'YES');
end;
end;
// adding application type
@ -443,12 +447,13 @@ begin
// Debug
cfg:=trg.buildConfigurationList.findConfig('Debug', true);
cfg.buildSettings.AddStr('INFOPLIST_FILE', '$(SRCROOT)/'+plist);
cfg.buildSettings.AddStr('PRODUCT_NAME', trg.productName);
// Build
SetNewStr(cfg.buildSettings, 'INFOPLIST_FILE', '$(SRCROOT)/'+plist);
SetNewStr(cfg.buildSettings, 'PRODUCT_NAME', trg.productName);
// Release
cfg:=trg.buildConfigurationList.findConfig('Release', true);
cfg.buildSettings.AddStr('INFOPLIST_FILE', '$(SRCROOT)/'+plist);
cfg.buildSettings.AddStr('PRODUCT_NAME', trg.productName);
SetNewStr(cfg.buildSettings, 'INFOPLIST_FILE', '$(SRCROOT)/'+plist);
SetNewStr(cfg.buildSettings, 'PRODUCT_NAME', trg.productName);
if trg.buildConfigurationList.defaultConfigurationName = '' then
trg.buildConfigurationList.defaultConfigurationName:='Debug';
@ -457,8 +462,7 @@ begin
if not Assigned(trg.productReference) then begin
fr:=FileRefCreate(bundle, FILETYPE_MACHO, SRCTREE_PRODUCT);
trg.productReference:=fr;
end; (* else
fr:=trg.productReference;*)
end;
// Creating "content" for the directory. It should also contain .plist
pgrp:=prj.mainGroup.findGroup(targetName, true); // name must match to the target name!
@ -505,5 +509,27 @@ begin
UpdateCompileOpts(prj, TemplateValues.Values['projoptions']);
end;
function UpdateProject(const ProjFileName: string; TemplateValues, ResFiles: TStrings): Boolean;
var
prj : PBXProject;
begin
if FileExists(ProjFileName) then begin
prj:=nil;
Result:=ProjectLoadFromFile(ProjFileName, prj);
if not Result then begin
prj.Free;
Exit;
end;
end else
prj:=ProjectCreate3_2;
try
PrepareTemplateFile(prj, TemplateValues, Resfiles);
Result:=ProjectSaveToFile(prj, ProjFileName);
finally
prj.Free;
end;
end;
end.