diff --git a/components/iphonelazext/pbx/xcodeproj.pas b/components/iphonelazext/pbx/xcodeproj.pas index 02a063d6b..742ca7fae 100644 --- a/components/iphonelazext/pbx/xcodeproj.pas +++ b/components/iphonelazext/pbx/xcodeproj.pas @@ -129,6 +129,7 @@ type public constructor Create; override; destructor Destroy; override; + function AddFile(ref: PBXFileReference): PBXBuildFile; published property buildActionMask: Integer read fbuildActionMask write fbuildActionMask; property files: TPBXObjectsList read ffiles; @@ -141,6 +142,8 @@ type PBXResourcesBuildPhase = class(PBXBuildPhase); PBXSourcesBuildPhase = class(PBXBuildPhase); + PBXBuildPhaseClass = class of PBXBuildPhase; + { PBXShellScriptBuildPhase } PBXShellScriptBuildPhase = class(PBXBuildPhase) @@ -316,6 +319,9 @@ const SCRIPT_DEFNAME = 'Run Script'; function TargetAddRunScript(atarget: PBXNativeTarget): PBXShellScriptBuildPhase; +function TargetFindBuildPhase(atarget: PBXNativeTarget; aclass: PBXBuildPhaseClass; aforce: Boolean = false): PBXBuildPhase; +function TargetFindRunScript(atarget: PBXNativeTarget; aforce: Boolean = false): PBXShellScriptBuildPhase; +function TargetFindResources(atarget: PBXNativeTarget; aforce: Boolean = false): PBXResourcesBuildPhase; const //FILETYPE_SCRIPT = 'text.script.sh'; @@ -325,7 +331,9 @@ const FILETYPE_PLIST = 'text.plist.xml'; FILETYPE_OBJC = 'sourcecode.c.objc'; -function FileRefCreate(const afilename: string; const filetype: string = ''): PBXFileReference; +// defaults to SRCTREE_GROUP for source related +function FileRefCreate(const afilename: string; const filetype: string = ''): PBXFileReference; overload; +function FileRefCreate(const afilename: string; const filetype, ASrcTreeRel: string): PBXFileReference; overload; const SRCTREE_ABSOLUTE = ''; // path is absolute path @@ -597,6 +605,17 @@ begin ffiles.Free; end; +function PBXBuildPhase.AddFile(ref: PBXFileReference): PBXBuildFile; +begin + if not Assigned(ref) then begin + Result:=nil; + Exit; + end; + Result := PBXBuildFile.Create; + Result.fileRef:=ref; + ffiles.Add(Result); +end; + function ProjectLoadFromStream(st: TStream; var prj: PBXProject): Boolean; var c : TPBXContainer; @@ -711,8 +730,41 @@ begin Result:=ProjectAddTarget(prj, ATargetName); end; +function TargetFindBuildPhase(atarget: PBXNativeTarget; aclass: PBXBuildPhaseClass; aforce: Boolean = false): PBXBuildPhase; +var + i : integer; +begin + Result:=nil; + if not Assigned(atarget) then Exit; + for i:=0 to atarget.buildPhases.Count-1 do + if atarget.buildPhases[i] is aclass then begin + Result:=PBXBuildPhase(atarget.buildPhases[i]); + Break; + end; + if not Assigned(Result) and aforce then begin + Result:=aclass.Create; + atarget.buildPhases.Add(Result); + end; +end; + +function TargetFindResources(atarget: PBXNativeTarget; aforce: Boolean = false): PBXResourcesBuildPhase; +begin + Result:=PBXResourcesBuildPhase(TargetFindBuildPhase(atarget, PBXResourcesBuildPhase, aforce)); +end; + +function TargetFindRunScript(atarget: PBXNativeTarget; aforce: Boolean = false): PBXShellScriptBuildPhase; +begin + Result:=PBXShellScriptBuildPhase(TargetFindBuildPhase(atarget, PBXShellScriptBuildPhase, false)); + if not Assigned(Result) and aforce then + Result:=TargetAddRunScript(atarget); +end; + function TargetAddRunScript(atarget: PBXNativeTarget): PBXShellScriptBuildPhase; begin + if not Assigned(atarget) then begin + Result:=nil; + Exit; + end; Result:=PBXShellScriptBuildPhase.Create; Result.name:=SCRIPT_DEFNAME; Result._headerComment:=SCRIPT_DEFNAME; @@ -722,11 +774,17 @@ begin end; function FileRefCreate(const afilename: string; const filetype: string ): PBXFileReference; +begin + Result:=FileRefCreate(afilename, filetype, SRCTREE_GROUP); +end; + +function FileRefCreate(const afilename: string; const filetype, ASrcTreeRel: string): PBXFileReference; begin Result:=PBXFileReference.Create; Result.path:=afilename; Result._headerComment:=afilename; Result.explicitFileType:=FILETYPE_EXEC; + Result.sourceTree:=ASrcTreeRel; end; function GroupCreate(const aname, srcTree: string): PBXGroup; diff --git a/components/iphonelazext/xcodetemplate.pas b/components/iphonelazext/xcodetemplate.pas index 735664514..12d30e570 100644 --- a/components/iphonelazext/xcodetemplate.pas +++ b/components/iphonelazext/xcodetemplate.pas @@ -372,14 +372,37 @@ var begin prj:=ProjectCreate3_2; PrepareTemplateFile(prj, TemplateValues, ResFiles); + src.Text:=ProjectWrite(prj); end; +function ReadBuildScriptFile(const fn: string): string; +var + fs : TFileStream; +begin + fs:=TFileStream.Create(fn, fmOpenRead or fmShareDenyNone); + try + if fs.Size=0 then begin + Result:=''; + Exit; + end; + SetLength(Result, fs.Size); + fs.Read(Result[1], fs.Size); + + // replacing line breaks with #13 for Xcode + Result:=StringReplace(Result, #13#10, #13, [rfReplaceAll]); + Result:=StringReplace(Result, #10#13, #13, [rfReplaceAll]); + Result:=StringReplace(Result, #10, #13, [rfReplaceAll]); + finally + fs.Free; + end; +end; + + procedure PrepareTemplateFile(prj: PBXProject; TemplateValues, ResFiles: TStrings); var trg : PBXNativeTarget; cfg : XCBuildConfiguration; fr : PBXFileReference; - fbld : PBXBuildFile; grp : PBXGroup; pgrp : PBXGroup; scr : PBXShellScriptBuildPhase; @@ -390,6 +413,8 @@ var bundle : string; main : string; fnm : string; +const + FILE_COPY_MASK = 2147483647; begin targetName:=TemplateValues.Values['targetname']; bundle:=TemplateValues.Values['bundle']; @@ -425,16 +450,15 @@ begin cfg.buildSettings.AddStr('INFOPLIST_FILE', '$(SRCROOT)/'+plist); cfg.buildSettings.AddStr('PRODUCT_NAME', trg.productName); - if trg.buildConfigurationList = '' then + if trg.buildConfigurationList.defaultConfigurationName = '' then trg.buildConfigurationList.defaultConfigurationName:='Debug'; // Adding the ".app" directory for the bundle and bind it to the target if not Assigned(trg.productReference) then begin - fr:=FileRefCreate(bundle, FILETYPE_MACHO); - fr.sourceTree:= SRCTREE_PRODUCT; + fr:=FileRefCreate(bundle, FILETYPE_MACHO, SRCTREE_PRODUCT); trg.productReference:=fr; - end else - fr:=trg.productReference; + end; (* else + fr:=trg.productReference;*) // Creating "content" for the directory. It should also contain .plist pgrp:=prj.mainGroup.findGroup(targetName, true); // name must match to the target name! @@ -444,41 +468,41 @@ begin // Thus at the same directar as .xcodeproj dir if not Assigned(grp.findFileRefByPathName(plist)) then begin - fr:=FileRefCreate(plist, FILETYPE_PLIST ); - fr.sourceTree:=SRCTREE_PROJECT; - - fr.path:=plist; + fr:=FileRefCreate(plist, FILETYPE_PLIST, SRCTREE_PROJECT ); grp.children.Add( fr ); end; - scr:=TargetAddRunScript(trg); - scr.shellScript:=BuildScript; - scr.showEnvVarsInLog:=true; + if not Assigned(TargetFindRunScript(trg)) then begin + scr:=TargetAddRunScript(trg); + scr.shellScript:=BuildScript; + scr.showEnvVarsInLog:=true; + end; + // todo: removal of files! if Assigned(ResFiles) and (ResFiles.Count>0) then begin - grp:=prj.mainGroup.addSubGroup('Resources'); // name must match to the target name! + grp:=prj.mainGroup.findGroup('Resources', true); // name must match to the target name! //grp:=pgrp.addSubGroup('Supporting Files'); // name must match! - res := PBXResourcesBuildPhase.Create; - res.buildActionMask:=2147483647; - //res.name:='Resources'; - trg.buildPhases.Add(res); + res := PBXResourcesBuildPhase(TargetFindBuildPhase(trg, PBXResourcesBuildPhase)); + if not Assigned(res) then begin + res := PBXResourcesBuildPhase.Create; + //res.name:='Resources'; + res.buildActionMask:=FILE_COPY_MASK; + trg.buildPhases.Add(res); + end; + for i:=0 to ResFiles.Count-1 do begin fnm:='../'+ResFiles[i]; - fr:=FileRefCreate(fnm, FILETYPE_MACHO); - fr.sourceTree:=SRCTREE_PROJECT; - grp.children.add(fr); - - fbld := PBXBuildFile.Create; - fbld.fileRef:=fr; - res.files.Add(fbld); + if not Assigned(grp.findFileRefByPathName(fnm)) then begin + fr:=FileRefCreate(fnm, FILETYPE_MACHO, SRCTREE_PROJECT); + grp.children.add( fr ); + res.AddFile(fr); + end; end; end; UpdateMainFile(prj, main); UpdateCompileOpts(prj, TemplateValues.Values['projoptions']); - - src.Text:=ProjectWrite(prj); end; end.