/** * Generates bodies of all sections that contain a list of source files plus a dictionary of project navigator groups. */ public void GenerateSectionsContents(ref string PBXBuildFileSection, ref string PBXFileReferenceSection, ref string PBXSourcesBuildPhaseSection, ref Dictionary <string, XcodeFileGroup> Groups) { StringBuilder FileSection = new StringBuilder(); StringBuilder ReferenceSection = new StringBuilder(); StringBuilder BuildPhaseSection = new StringBuilder(); foreach (var CurSourceFile in SourceFiles) { XcodeSourceFile SourceFile = CurSourceFile as XcodeSourceFile; string FileName = Path.GetFileName(SourceFile.FilePath); string FileExtension = Path.GetExtension(FileName); string FilePath = Utils.MakePathRelativeTo(SourceFile.FilePath, XcodeProjectFileGenerator.MasterProjectRelativePath); string FilePathMac = Utils.CleanDirectorySeparators(FilePath, '/'); // Xcode doesn't parse the project file correctly if the build files don't use the same file reference ID, // so you can't just manually add an entry for UE4CmdLineRun.m, because the ID will conflict with the // ID that gets generated above implicitly by "XcodeSourceFile SourceFile = CurSourceFile as XcodeSourceFile;" // At the same time, it is necessary to manually add an entry for it, because we're compiling the unit test with // exactly one source file. // This is ugly, but the project file generator wasn't designed to handle special cases like this, // so we're left with little choice. if (FileName == "UE4CmdLineRun.m") { SourceFile.ReplaceGUIDS(UE4CmdLineRunFileGuid, UE4CmdLineRunFileRefGuid); } if (IsGeneratedProject) { FileSection.Append(string.Format("\t\t{0} /* {1} in {2} */ = {{isa = PBXBuildFile; fileRef = {3} /* {1} */; }};" + ProjectFileGenerator.NewLine, SourceFile.FileGUID, FileName, GetFileCategory(FileExtension), SourceFile.FileRefGUID)); } ReferenceSection.Append(string.Format("\t\t{0} /* {1} */ = {{isa = PBXFileReference; lastKnownFileType = {2}; name = \"{1}\"; path = \"{3}\"; sourceTree = SOURCE_ROOT; }};" + ProjectFileGenerator.NewLine, SourceFile.FileRefGUID, FileName, GetFileType(FileExtension), FilePathMac)); if (IsPartOfUE4XcodeHelperTarget(SourceFile)) { BuildPhaseSection.Append("\t\t\t\t" + SourceFile.FileGUID + " /* " + FileName + " in Sources */," + ProjectFileGenerator.NewLine); } string GroupPath = Path.GetFullPath(Path.GetDirectoryName(SourceFile.FilePath)); XcodeFileGroup Group = FindGroupByFullPath(ref Groups, GroupPath); if (Group != null) { Group.Files.Add(SourceFile); } } PBXBuildFileSection += FileSection.ToString(); PBXFileReferenceSection += ReferenceSection.ToString(); PBXSourcesBuildPhaseSection += BuildPhaseSection.ToString(); }
/** * Returns a project navigator group to which the file should belong based on its path. * Creates a group tree if it doesn't exist yet. */ public XcodeFileGroup FindGroupByFullPath(ref Dictionary <string, XcodeFileGroup> Groups, string FullPath) { string RelativePath = (FullPath == XcodeProjectFileGenerator.MasterProjectRelativePath) ? "" : Utils.MakePathRelativeTo(FullPath, XcodeProjectFileGenerator.MasterProjectRelativePath); if (RelativePath.StartsWith("..")) { string UE4Dir = Path.GetFullPath(Directory.GetCurrentDirectory() + "../../.."); RelativePath = Utils.MakePathRelativeTo(FullPath, UE4Dir); } string[] Parts = RelativePath.Split(Path.DirectorySeparatorChar); string CurrentPath = ""; Dictionary <string, XcodeFileGroup> CurrentParent = Groups; foreach (string Part in Parts) { XcodeFileGroup CurrentGroup; if (CurrentPath != "") { CurrentPath += Path.DirectorySeparatorChar; } CurrentPath += Part; if (!CurrentParent.ContainsKey(CurrentPath)) { CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath); CurrentParent.Add(CurrentPath, CurrentGroup); } else { CurrentGroup = CurrentParent[CurrentPath]; } if (CurrentPath == RelativePath) { return(CurrentGroup); } CurrentParent = CurrentGroup.Children; } return(null); }
/** * Returns a project navigator group to which the file should belong based on its path. * Creates a group tree if it doesn't exist yet. */ public XcodeFileGroup FindGroupByFullPath(ref Dictionary<string, XcodeFileGroup> Groups, string FullPath) { string RelativePath = (FullPath == XcodeProjectFileGenerator.MasterProjectRelativePath) ? "" : Utils.MakePathRelativeTo(FullPath, XcodeProjectFileGenerator.MasterProjectRelativePath); if (RelativePath.StartsWith("..")) { string UE4Dir = Path.GetFullPath(Directory.GetCurrentDirectory() + "../../.."); RelativePath = Utils.MakePathRelativeTo(FullPath, UE4Dir); } string[] Parts = RelativePath.Split(Path.DirectorySeparatorChar); string CurrentPath = ""; Dictionary<string, XcodeFileGroup> CurrentParent = Groups; foreach (string Part in Parts) { XcodeFileGroup CurrentGroup; if (CurrentPath != "") { CurrentPath += Path.DirectorySeparatorChar; } CurrentPath += Part; if (!CurrentParent.ContainsKey(CurrentPath)) { CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath); CurrentParent.Add(CurrentPath, CurrentGroup); } else { CurrentGroup = CurrentParent[CurrentPath]; } if (CurrentPath == RelativePath) { return CurrentGroup; } CurrentParent = CurrentGroup.Children; } return null; }
private void AppendGroup(XcodeFileGroup Group, StringBuilder Content, bool bFilesOnly) { if (!Group.bIsReference) { if (!bFilesOnly) { Content.Append(string.Format("\t\t{0} = {{{1}", Group.GroupGuid, ProjectFileGenerator.NewLine)); Content.Append("\t\t\tisa = PBXGroup;" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tchildren = (" + ProjectFileGenerator.NewLine); foreach (XcodeFileGroup ChildGroup in Group.Children.Values) { Content.Append(string.Format("\t\t\t\t{0} /* {1} */,{2}", ChildGroup.GroupGuid, ChildGroup.GroupName, ProjectFileGenerator.NewLine)); } } foreach (XcodeSourceFile File in Group.Files) { Content.Append(string.Format("\t\t\t\t{0} /* {1} */,{2}", File.FileRefGuid, File.Reference.GetFileName(), ProjectFileGenerator.NewLine)); } if (!bFilesOnly) { Content.Append("\t\t\t);" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tname = \"" + Group.GroupName + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tpath = \"" + Group.GroupPath + "\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t\tsourceTree = \"<group>\";" + ProjectFileGenerator.NewLine); Content.Append("\t\t};" + ProjectFileGenerator.NewLine); foreach (XcodeFileGroup ChildGroup in Group.Children.Values) { AppendGroup(ChildGroup, Content, bFilesOnly: false); } } } }
/// <summary> /// Returns a project navigator group to which the file should belong based on its path. /// Creates a group tree if it doesn't exist yet. /// </summary> public XcodeFileGroup FindGroupByRelativePath(ref Dictionary<string, XcodeFileGroup> Groups, string RelativePath) { string[] Parts = RelativePath.Split(Path.DirectorySeparatorChar); string CurrentPath = ""; Dictionary<string, XcodeFileGroup> CurrentParent = Groups; foreach (string Part in Parts) { XcodeFileGroup CurrentGroup; if (CurrentPath != "") { CurrentPath += Path.DirectorySeparatorChar; } CurrentPath += Part; if (!CurrentParent.ContainsKey(CurrentPath)) { CurrentGroup = new XcodeFileGroup(Path.GetFileName(CurrentPath), CurrentPath); CurrentParent.Add(CurrentPath, CurrentGroup); } else { CurrentGroup = CurrentParent[CurrentPath]; } if (CurrentPath == RelativePath) { return CurrentGroup; } CurrentParent = CurrentGroup.Children; } return null; }