コード例 #1
0
		/// <summary>
		/// Writes the project files to disk
		/// </summary>
		/// <returns>True if successful</returns>
		protected override bool WriteProjectFiles()
		{
			Log.TraceInformation("Generating project file...");

			// Setup project file content
			var XcodeProjectFileContent = new StringBuilder();

			XcodeProjectFileContent.Append(
				"// !$*UTF8*$!" + ProjectFileGenerator.NewLine +
				"{" + ProjectFileGenerator.NewLine +
				"\tarchiveVersion = 1;" + ProjectFileGenerator.NewLine +
				"\tclasses = {" + ProjectFileGenerator.NewLine +
				"\t};" + ProjectFileGenerator.NewLine +
				"\tobjectVersion = 46;" + ProjectFileGenerator.NewLine +
				"\tobjects = {" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

			// attempt to determine targets for the project
			List<XcodeProjectTarget> ProjectTargets = new List<XcodeProjectTarget> ();
			// add mandatory ones
			XcodeProjectTarget UE4ProjectTarget = new XcodeProjectTarget ("UE4", "UE4", XcodeTargetType.Project, "");
			XcodeProjectTarget UE4XcodeHelperTarget = new XcodeProjectTarget ("UE4XcodeHelper", "UE4XcodeHelper", XcodeTargetType.XcodeHelper, "", "libUE4XcodeHelper.a");
			ProjectTargets.AddRange(new XcodeProjectTarget[] { UE4ProjectTarget, UE4XcodeHelperTarget });

			if (ProjectFilePlatform.HasFlag(XcodeProjectFilePlatform.iOS))
			{
				XcodeProjectTarget UE4CmdLineRunTarget = new XcodeProjectTarget("UE4CmdLineRun", "UE4CmdLineRun", XcodeTargetType.XCTest, "", "UE4CmdLineRun.xctest", UnrealTargetPlatform.IOS);
				ProjectTargets.Add(UE4CmdLineRunTarget);
				// This GUID will be referenced by each app's test action.
				UE4CmdLineGuid = UE4CmdLineRunTarget.Guid;
			}

			List<XcodeTargetDependency> TargetDependencies = new List<XcodeTargetDependency>();
			List<XcodeContainerItemProxy> ContainerItemProxies = new List<XcodeContainerItemProxy>();
            List<XcodeFramework> Frameworks = new List<XcodeFramework>();
            Frameworks.Add(new XcodeFramework("OpenGLES.framework", "System/Library/Frameworks/OpenGLES.framework", "SDKROOT"));
			// @todo metal: putting this into the project will make for VERY slow Metal runtime by default...
//			Frameworks.Add(new XcodeFramework("Metal.framework", "System/Library/Frameworks/Metal.framework", "SDKROOT"));

			XcodeFramework XCTestFramework = new XcodeFramework("XCTest.framework", "Library/Frameworks/XCTest.framework", "DEVELOPER_DIR");
            Frameworks.Add(XCTestFramework);

			var AllTargets = DiscoverTargets();

			PopulateTargets(AllTargets, ProjectTargets, ContainerItemProxies, TargetDependencies, UE4ProjectTarget, Frameworks);

			Log.TraceInformation(string.Format ("Found {0} targets!", ProjectTargets.Count));

			string PBXBuildFileSection = "/* Begin PBXBuildFile section */" + ProjectFileGenerator.NewLine;
			string PBXFileReferenceSection = "/* Begin PBXFileReference section */" + ProjectFileGenerator.NewLine;
			string PBXResourcesBuildPhaseSection = "/* Begin PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
			string PBXSourcesBuildPhaseSection = "/* Begin PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
			string PBXFrameworksBuildPhaseSection = "/* Begin PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine;
			string PBXShellScriptBuildPhaseSection = "/* Begin PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine;
			Dictionary<string, XcodeFileGroup> Groups = new Dictionary<string, XcodeFileGroup>();
			List<string> IncludeDirectories = new List<string>();
			List<string> SystemIncludeDirectories = new List<string>();
			List<string> PreprocessorDefinitions = new List<string>();

            foreach (XcodeFramework Framework in Frameworks)
            {
                // Add file references.
                PBXFileReferenceSection += "\t\t" + Framework.Guid + " /* " + Framework.Name + " */ = {"
                                         + "isa = PBXFileReference; "
                                         + "lastKnownFileType = wrapper.framework; "
                                         + "name = " + Framework.Name + "; "
                                         + "path = " + Framework.Path + "; "
                                         + "sourceTree = " + Framework.SourceTree + "; "
                                         + "};" + ProjectFileGenerator.NewLine;
            }

			// Set up all the test guids that need to be explicitly referenced later
			string UE4CmdLineRunMFileGuid = MakeXcodeGuid();
			UE4CmdLineRunMFileRefGuid = MakeXcodeGuid();
			string XCTestBuildFileGUID = MakeXcodeGuid();

			string TestFrameworkFiles = "\t\t\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */," + ProjectFileGenerator.NewLine;
			PBXBuildFileSection += "\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; "
				+ "fileRef = " + XCTestFramework.Guid + " /* UE4CmdLineRun.m */; };" + ProjectFileGenerator.NewLine;

			AppendBuildPhases(ProjectTargets, ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref PBXResourcesBuildPhaseSection, ref PBXFrameworksBuildPhaseSection,
				ref PBXShellScriptBuildPhaseSection, TestFrameworkFiles, UE4CmdLineRunMFileGuid);

			AppendSourceFiles(ProjectTargets, ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref Groups, UE4XcodeHelperTarget, UE4CmdLineRunMFileGuid,
				ref IncludeDirectories, ref SystemIncludeDirectories, ref PreprocessorDefinitions);

			foreach (XcodeProjectTarget Target in ProjectTargets)
			{
				if ((Target.Type == XcodeTargetType.Native || Target.Type == XcodeTargetType.XCTest))
				{
					string FileType = Target.Type == XcodeTargetType.Native ? "wrapper.application" : "wrapper.cfbundle";
					string PayloadDir = "Engine";
					if (Target.Type == XcodeTargetType.Native && Target.TargetName != "UE4Game")
					{
						PayloadDir = Target.TargetName;
					}

					PBXFileReferenceSection += "\t\t" + Target.ProductGuid + " /* " + Target.ProductName + " */ = {isa = PBXFileReference; explicitFileType = " + FileType + "; includeInIndex = 0; path = " + PayloadDir + "/Binaries/IOS/Payload/" + Target.ProductName + "; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
					if (!string.IsNullOrEmpty(Target.PlistGuid))
					{
						PBXFileReferenceSection += "\t\t" + Target.PlistGuid + " /* " + Target.TargetName + "-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"" + Target.TargetName + "-Info.plist\"; path = " + Target.TargetName + "/Build/IOS/" + Target.TargetName + "-Info.plist; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
					}
				}
			}

			if (bGeneratingRunIOSProject)
			{
				AppendReferenceGroups(ref PBXFileReferenceSection, ref Groups);
			}

			PBXBuildFileSection += "/* End PBXBuildFile section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
			PBXFileReferenceSection += "/* End PBXFileReference section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

			PBXResourcesBuildPhaseSection += "/* End PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
			PBXSourcesBuildPhaseSection += "/* End PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
			PBXFrameworksBuildPhaseSection += "/* End PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
			PBXShellScriptBuildPhaseSection += "/* End PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

			string PBXTargetDependencySection = "/* Begin PBXTargetDependency section */" + ProjectFileGenerator.NewLine;
			CreateTargetDependencySection(ref PBXTargetDependencySection, TargetDependencies);
			PBXTargetDependencySection += "/* End PBXTargetDependency section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

			string PBXContainerItemProxySection = "/* Begin PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine;
			CreateContainerItemProxySection(ref PBXContainerItemProxySection, ContainerItemProxies);
			PBXContainerItemProxySection += "/* End PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

			XcodeProjectFileContent.Append(PBXBuildFileSection);
			XcodeProjectFileContent.Append(PBXFileReferenceSection);
			XcodeProjectFileContent.Append(PBXContainerItemProxySection);
			XcodeProjectFileContent.Append(PBXTargetDependencySection);

			AppendGroups(ref XcodeProjectFileContent, ref Groups, ProjectTargets , Frameworks);

			XcodeProjectFileContent.Append(PBXShellScriptBuildPhaseSection);
			XcodeProjectFileContent.Append(PBXSourcesBuildPhaseSection);
			XcodeProjectFileContent.Append(PBXFrameworksBuildPhaseSection);

			XcodeProjectFileContent.Append("/* Begin PBXLegacyTarget section */" + ProjectFileGenerator.NewLine);
			foreach (var Target in ProjectTargets)
			{
				if (Target.Type == XcodeTargetType.Legacy)
				{
					AppendTarget (ref XcodeProjectFileContent, Target);
				}
			}
			XcodeProjectFileContent.Append("/* End PBXLegacyTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

			XcodeProjectFileContent.Append("/* Begin PBXNativeTarget section */" + ProjectFileGenerator.NewLine);
			AppendTarget(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

			foreach (XcodeProjectTarget Target in ProjectTargets)
			{
				if (Target.Type == XcodeTargetType.Native || Target.Type == XcodeTargetType.XCTest)
				{
					AppendTarget(ref XcodeProjectFileContent, Target);
				}
			}
			XcodeProjectFileContent.Append("/* End PBXNativeTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

			XcodeProjectFileContent.Append(
				"/* Begin PBXProject section */" + ProjectFileGenerator.NewLine +
				"\t\t" + UE4ProjectTarget.Guid + " /* Project object */ = {" + ProjectFileGenerator.NewLine +
				"\t\t\tisa = PBXProject;" + ProjectFileGenerator.NewLine +
				"\t\t\tattributes = {" + ProjectFileGenerator.NewLine +
				"\t\t\t\tLastUpgradeCheck = 0510;" + ProjectFileGenerator.NewLine +
				"\t\t\t\tORGANIZATIONNAME = EpicGames;" + ProjectFileGenerator.NewLine +
				"\t\t\t};" + ProjectFileGenerator.NewLine +
				"\t\t\tbuildConfigurationList = " + UE4ProjectTarget.BuildConfigGuild + " /* Build configuration list for PBXProject \"" + UE4ProjectTarget.DisplayName + "\" */;" + ProjectFileGenerator.NewLine +
				"\t\t\tcompatibilityVersion = \"Xcode 3.2\";" + ProjectFileGenerator.NewLine +
				"\t\t\tdevelopmentRegion = English;" + ProjectFileGenerator.NewLine +
				"\t\t\thasScannedForEncodings = 0;" + ProjectFileGenerator.NewLine +
				"\t\t\tknownRegions = (" + ProjectFileGenerator.NewLine +
				"\t\t\t\ten," + ProjectFileGenerator.NewLine +
				"\t\t\t);" + ProjectFileGenerator.NewLine +
				"\t\t\tmainGroup = " + MainGroupGuid + ";" + ProjectFileGenerator.NewLine +
				"\t\t\tproductRefGroup = " + ProductRefGroupGuid + " /* Products */;" + ProjectFileGenerator.NewLine +
				"\t\t\tprojectDirPath = \"\";" + ProjectFileGenerator.NewLine +
				"\t\t\tprojectRoot = \"\";" + ProjectFileGenerator.NewLine +
				"\t\t\ttargets = (" + ProjectFileGenerator.NewLine
			);

			foreach (var Target in ProjectTargets)
			{
				if (Target != UE4ProjectTarget)
				{
					XcodeProjectFileContent.AppendLine(string.Format ("\t\t\t\t{0} /* {1} */,", Target.Guid, Target.DisplayName));
				}
			}

			XcodeProjectFileContent.Append(
				"\t\t\t);" + ProjectFileGenerator.NewLine +
				"\t\t};" + ProjectFileGenerator.NewLine +
				"/* End PBXProject section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine
			);

			string PreprocessorDefinitionsString = "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (" + ProjectFileGenerator.NewLine;
			foreach (string Definition in PreprocessorDefinitions)
			{
				PreprocessorDefinitionsString += "\t\t\t\t\t\"" + Definition + "\"," + ProjectFileGenerator.NewLine;
			}
			PreprocessorDefinitionsString += "\t\t\t\t\t\"MONOLITHIC_BUILD=1\"," + ProjectFileGenerator.NewLine;
			PreprocessorDefinitionsString += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

			string HeaderSearchPaths = "\t\t\t\tHEADER_SEARCH_PATHS = (" + ProjectFileGenerator.NewLine;
			foreach (string Path in SystemIncludeDirectories)
			{
				HeaderSearchPaths += "\t\t\t\t\t\"" + Path + "\"," + ProjectFileGenerator.NewLine;
			}
			HeaderSearchPaths += "\t\t\t\t);" + ProjectFileGenerator.NewLine;
			HeaderSearchPaths += "\t\t\t\tUSER_HEADER_SEARCH_PATHS = (" + ProjectFileGenerator.NewLine;
			foreach (string Path in IncludeDirectories)
			{
				HeaderSearchPaths += "\t\t\t\t\t\"" + Path + "\"," + ProjectFileGenerator.NewLine;
			}
			HeaderSearchPaths += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

			XcodeProjectFileContent.Append("/* Begin XCBuildConfiguration section */" + ProjectFileGenerator.NewLine);
			AppendBuildConfigs(ref XcodeProjectFileContent, UE4ProjectTarget, HeaderSearchPaths, PreprocessorDefinitionsString);
			foreach (var Target in ProjectTargets)
			{
				if (Target.Type != XcodeTargetType.Project && Target.Type != XcodeTargetType.XcodeHelper)
				{
					AppendBuildConfigs(ref XcodeProjectFileContent, Target);
				}
			}

			AppendBuildConfigs(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

			XcodeProjectFileContent.Append("/* End XCBuildConfiguration section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

			XcodeProjectFileContent.Append("/* Begin XCConfigurationList section */" + ProjectFileGenerator.NewLine);

			foreach (var Target in ProjectTargets)
			{
				if (Target.Type != XcodeTargetType.XcodeHelper)
				{
					AppendConfigList(ref XcodeProjectFileContent, Target);
				}
			}

			AppendConfigList(ref XcodeProjectFileContent, UE4XcodeHelperTarget);

			XcodeProjectFileContent.Append("/* End XCConfigurationList section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

			XcodeProjectFileContent.Append(
				"\t};" + ProjectFileGenerator.NewLine +
				"\trootObject = " + UE4ProjectTarget.Guid + " /* Project object */;" + ProjectFileGenerator.NewLine +
				"}" + ProjectFileGenerator.NewLine);

			WriteProject(XcodeProjectFileContent, ProjectTargets);

			// TODO: add any content for any files in the workspace here
			WriteWorkspace();

			return true;
		}
コード例 #2
0
		public XcodeFrameworkRef(XcodeFramework InFramework)
		{
			Guid = XcodeProjectFileGenerator.MakeXcodeGuid();
			Framework = InFramework;
		}
コード例 #3
0
        /// <summary>
        /// Writes the project files to disk
        /// </summary>
        /// <returns>True if successful</returns>
        protected override bool WriteProjectFiles()
        {
            Log.TraceInformation ("Generating project file...");

            bool bAddSourceFiles = true;
            bool bAddOnlyTargetSources = true;
            bool bOnlyFolderRefs = (ExternalExecution.GetRuntimePlatform() != UnrealTargetPlatform.Mac);

            // Setup project file content
            var XcodeProjectFileContent = new StringBuilder ();

            XcodeProjectFileContent.Append (
                "// !$*UTF8*$!" + ProjectFileGenerator.NewLine +
                "{" + ProjectFileGenerator.NewLine +
                "\tarchiveVersion = 1;" + ProjectFileGenerator.NewLine +
                "\tclasses = {" + ProjectFileGenerator.NewLine +
                "\t};" + ProjectFileGenerator.NewLine +
                "\tobjectVersion = 46;" + ProjectFileGenerator.NewLine +
                "\tobjects = {" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            // attempt to determine targets for the project
            List<XcodeProjectTarget> ProjectTargets = new List<XcodeProjectTarget> ();
            // add mandatory ones
            XcodeProjectTarget UE4ProjectTarget = new XcodeProjectTarget ("UE4", "UE4", "Project");
            XcodeProjectTarget UE4XcodeHelperTarget = new XcodeProjectTarget ("UE4XcodeHelper", "UE4XcodeHelper", "Native", "libUE4XcodeHelper.a");
            ProjectTargets.AddRange(new XcodeProjectTarget[] { UE4ProjectTarget, UE4XcodeHelperTarget });

            if (ProjectFilePlatform.HasFlag(XcodeProjectFilePlatform.iOS))
            {
                XcodeProjectTarget UE4CmdLineRunTarget = new XcodeProjectTarget("UE4CmdLineRun", "UE4CmdLineRun", "XCTest", "UE4CmdLineRun.xctest", UnrealTargetPlatform.IOS);
                ProjectTargets.AddRange(new XcodeProjectTarget[] { UE4ProjectTarget, UE4XcodeHelperTarget, UE4CmdLineRunTarget });
                // This GUID will be referenced by each app's test action.
                UE4CmdLineGuid = UE4CmdLineRunTarget.Guid;
            }

            List<XcodeTargetDependency> TargetDependencies = new List<XcodeTargetDependency>();
            List<XcodeContainerItemProxy> ContainerItemProxies = new List<XcodeContainerItemProxy>();
            List<XcodeFramework> Frameworks = new List<XcodeFramework>();
            Frameworks.Add(new XcodeFramework("OpenGLES.framework", "System/Library/Frameworks/OpenGLES.framework", "SDKROOT"));

            XcodeFramework XCTestFramework = new XcodeFramework("XCTest.framework", "Library/Frameworks/XCTest.framework", "DEVELOPER_DIR");
            Frameworks.Add(XCTestFramework);

            var AllTargets = DiscoverTargets();

            PopulateTargets(AllTargets, ProjectTargets, ContainerItemProxies, TargetDependencies, UE4ProjectTarget, Frameworks);

            Log.TraceInformation (string.Format ("Found {0} targets!", ProjectTargets.Count));

            string PBXBuildFileSection = "/* Begin PBXBuildFile section */" + ProjectFileGenerator.NewLine;
            string PBXFileReferenceSection = "/* Begin PBXFileReference section */" + ProjectFileGenerator.NewLine;
            string PBXResourcesBuildPhaseSection = "/* Begin PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXSourcesBuildPhaseSection = "/* Begin PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXFrameworksBuildPhaseSection = "/* Begin PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine;
            string PBXShellScriptBuildPhaseSection = "/* Begin PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine;
            Dictionary<string, XcodeFileGroup> Groups = new Dictionary<string, XcodeFileGroup>();
            List<string> IncludeDirectories = new List<string>();
            List<string> PreprocessorDefinitions = new List<string>();

            foreach (XcodeFramework Framework in Frameworks)
            {
                // Add file references.
                PBXFileReferenceSection += "\t\t" + Framework.Guid + " /* " + Framework.Name + " */ = {"
                                         + "isa = PBXFileReference; "
                                         + "lastKnownFileType = wrapper.framework; "
                                         + "name = " + Framework.Name + "; "
                                         + "path = " + Framework.Path + "; "
                                         + "sourceTree = " + Framework.SourceTree + "; "
                                         + "};" + ProjectFileGenerator.NewLine;
            }

            // Set up all the test guids that need to be explicitly referenced later
            string UE4CmdLineRunMFileGuid = MakeXcodeGuid();
            UE4CmdLineRunMFileRefGuid = MakeXcodeGuid();
            string XCTestBuildFileGUID = MakeXcodeGuid();

            string TestFrameworkFiles = "";
            {
                PBXBuildFileSection += "\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; "
                                                    + "fileRef = " + XCTestFramework.Guid + " /* UE4CmdLineRun.m */; };" + ProjectFileGenerator.NewLine;

                TestFrameworkFiles += "\t\t\t\t" + XCTestBuildFileGUID + " /* XCTest.framework in Frameworks */," + ProjectFileGenerator.NewLine;
            }

            foreach (XcodeProjectTarget Target in ProjectTargets)
            {
                if (Target.Type == "Native" || Target.Type == "XCTest")
                {
                    // Generate Build references and Framework references for each Framework.
                    string FrameworkFiles = "";
                    foreach (XcodeFrameworkRef FrameworkRef in Target.FrameworkRefs)
                    {
                        XcodeFramework Framework = FrameworkRef.Framework;

                        PBXBuildFileSection += "\t\t" + FrameworkRef.Guid + " /* " + Framework.Name + " in Frameworks */ = {"
                                            + "isa = PBXBuildFile; "
                                            + "fileRef = " + Framework.Guid
                                            + " /* " + Framework.Name + " */;"
                                            + " };" + ProjectFileGenerator.NewLine;

                        FrameworkFiles += "\t\t\t\t" + FrameworkRef.Guid + " /* " + Framework.Name + " in Frameworks */," + ProjectFileGenerator.NewLine;
                    }

                    AppendBuildPhase(ref PBXResourcesBuildPhaseSection, Target.ResourcesPhaseGuid, "Resources", null, null);

                    string Sources = null;

                    if (Target.Type == "XCTest")
                    {
                        // Add the xctest framework.
                        FrameworkFiles += TestFrameworkFiles;

                        // Normally every project either gets all source files compiled into it or none.
                        // We just want one file: UE4CmdLineRun.m
                        Sources = "\t\t\t\t" + UE4CmdLineRunMFileGuid + " /* UE4CmdLineRun.m in Sources */," + ProjectFileGenerator.NewLine;
                    }

                    AppendBuildPhase(ref PBXSourcesBuildPhaseSection, Target.SourcesPhaseGuid, "Sources", Sources, null);

                    AppendBuildPhase(ref PBXFrameworksBuildPhaseSection, Target.FrameworksPhaseGuid, "Frameworks", FrameworkFiles, null);

                    string PayloadDir = "Engine";
                    if (Target.Type == "Native" && Target.TargetName != "UE4Game")
                    {
                        PayloadDir = Target.TargetName;
                    }
                    // add a script for preventing errors during Archive builds
                    // this copies the contents of the app generated by UBT into the archiving app
                    PBXShellScriptBuildPhaseSection += "\t\t" + Target.ShellScriptPhaseGuid + " /* ShellScript */ = {" + ProjectFileGenerator.NewLine +
                        "\t\t\tisa = PBXShellScriptBuildPhase;" + ProjectFileGenerator.NewLine +
                        "\t\t\tbuildActionMask = 2147483647;" + ProjectFileGenerator.NewLine +
                        "\t\t\tfiles = (" + ProjectFileGenerator.NewLine +
                        "\t\t\t);" + ProjectFileGenerator.NewLine +
                        "\t\t\trunOnlyForDeploymentPostprocessing = 0;" + ProjectFileGenerator.NewLine +
                        "\t\t\tshellPath = /bin/sh;" + ProjectFileGenerator.NewLine +
                        "\t\t\tshellScript = \"if [ $DEPLOYMENT_LOCATION = \\\"YES\\\" ]\\nthen\\ncp -R " + PayloadDir +"/Binaries/IOS/Payload/" + Target.ProductName + "/ $DSTROOT/$LOCAL_APPS_DIR/" + Target.ProductName + "\\nfi\";" + ProjectFileGenerator.NewLine +
                        "\t\t};" + ProjectFileGenerator.NewLine;
                }
            }

            if (bAddSourceFiles)
            {
                PBXSourcesBuildPhaseSection += "\t\t" + UE4XcodeHelperTarget.SourcesPhaseGuid + " /* Sources */ = {" + ProjectFileGenerator.NewLine +
                    "\t\t\tisa = PBXSourcesBuildPhase;" + ProjectFileGenerator.NewLine +
                    "\t\t\tbuildActionMask = 2147483647;" + ProjectFileGenerator.NewLine +
                    "\t\t\tfiles = (" + ProjectFileGenerator.NewLine;

                PBXFileReferenceSection += "\t\t" + UE4XcodeHelperTarget.ProductGuid + " /* " + UE4XcodeHelperTarget.ProductName + " */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = " + UE4XcodeHelperTarget.ProductName + "; sourceTree = BUILT_PRODUCTS_DIR; };" + ProjectFileGenerator.NewLine;
                foreach (var CurProject in GeneratedProjectFiles)
                {
                    if (bAddOnlyTargetSources)
                    {
                        bool bHasTarget = false;
                        foreach (var TargetFile in CurProject.ProjectTargets)
                        {
                            if (TargetFile.TargetFilePath == null)
                            {
                                continue;
                            }

                            string TargetFileName = Path.GetFileNameWithoutExtension(TargetFile.TargetFilePath);
                            string TargetFileMinusTarget = TargetFileName.Substring(0, TargetFileName.LastIndexOf(".Target"));
                            foreach (XcodeProjectTarget Target in ProjectTargets)
                            {
                                if (TargetFileMinusTarget == Target.TargetName)
                                {
                                    bHasTarget = true;
                                    break;
                                }
                            }
                            if (bHasTarget)
                            {
                                break;
                            }
                        }

                     if (!bHasTarget)
                    {
                            continue;
                      }
                    }

                    XcodeProjectFile XcodeProject = CurProject as XcodeProjectFile;
                    if (XcodeProject == null)
                    {
                        continue;
                    }

                    // Necessary so that GenerateSectionContents can use the same GUID instead of
                    // auto-generating one for this special-case file.
                    XcodeProject.UE4CmdLineRunFileGuid = UE4CmdLineRunMFileGuid;
                    XcodeProject.UE4CmdLineRunFileRefGuid = UE4CmdLineRunMFileRefGuid;

                    if (bOnlyFolderRefs)
                    {
                        foreach (var CurSourceFile in XcodeProject.SourceFiles)
                        {
                            XcodeSourceFile SourceFile = CurSourceFile as XcodeSourceFile;
                            string GroupPath = Path.GetFullPath(Path.GetDirectoryName(SourceFile.FilePath));
                            XcodeFileGroup Group = XcodeProject.FindGroupByFullPath(ref Groups, GroupPath);
                            if (Group != null)
                            {
                                Group.bReference = true;
                            }

                        }
                    }
                    else
                    {
                    XcodeProject.GenerateSectionsContents (ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref Groups);
                    }

                    foreach (var CurPath in XcodeProject.IntelliSenseIncludeSearchPaths)
                    {
                        AddIncludeDirectory (ref IncludeDirectories, CurPath, Path.GetDirectoryName (XcodeProject.ProjectFilePath));
                    }

                    foreach (var CurDefinition in XcodeProject.IntelliSensePreprocessorDefinitions)
                    {
                        string AlternateDefinition = CurDefinition.Contains("=0") ? CurDefinition.Replace("=0", "=1") :  CurDefinition.Replace("=1", "=0");
                        if (!PreprocessorDefinitions.Contains(CurDefinition) && !PreprocessorDefinitions.Contains(AlternateDefinition) && !CurDefinition.StartsWith("UE_ENGINE_DIRECTORY") && !CurDefinition.StartsWith("ORIGINAL_FILE_NAME"))
                        {
                            PreprocessorDefinitions.Add (CurDefinition);
                        }
                    }
                }
                PBXSourcesBuildPhaseSection += "\t\t\t);" + ProjectFileGenerator.NewLine +
                "\t\t\trunOnlyForDeploymentPostprocessing = 0;" + ProjectFileGenerator.NewLine +
                "\t\t};" + ProjectFileGenerator.NewLine;

                if( !bGeneratingRocketProjectFiles )
                {
                    // Add UnrealBuildTool to the master project
                    string ProjectPath = System.IO.Path.Combine(System.IO.Path.Combine(EngineRelativePath, "Source"), "Programs", "UnrealBuildTool", "UnrealBuildTool_Mono.csproj");
                    AddPreGeneratedProject(ref PBXBuildFileSection, ref PBXFileReferenceSection, ref PBXSourcesBuildPhaseSection, ref Groups, ProjectPath);
                }
            }

            foreach (XcodeProjectTarget Target in ProjectTargets)
            {
                if ((Target.Type == "Native" || Target.Type == "XCTest") && Target != UE4XcodeHelperTarget)
                {
                    string FileType = Target.Type == "Native" ? "wrapper.application" : "wrapper.cfbundle";
                    string PayloadDir = "Engine";
                    if (Target.Type == "Native" && Target.TargetName != "UE4Game")
                    {
                        PayloadDir = Target.TargetName;
                    }

                    PBXFileReferenceSection += "\t\t" + Target.ProductGuid + " /* " + Target.ProductName + " */ = {isa = PBXFileReference; explicitFileType = " + FileType + "; includeInIndex = 0; path = " + PayloadDir + "/Binaries/IOS/Payload/" + Target.ProductName + "; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
                    if (!string.IsNullOrEmpty(Target.PlistGuid))
                    {
                        if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
                        {
                            PBXFileReferenceSection += "\t\t" + Target.PlistGuid + " /* " + Target.TargetName + "-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"" + Target.TargetName + "-Info.plist\"; path = " + Target.TargetName + "/Build/IOS/" + Target.TargetName + "-Info.plist; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
                        }
                        else
                        {
                            PBXFileReferenceSection += "\t\t" + Target.PlistGuid + " /* " + Target.TargetName + "-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = \"" + Target.TargetName + "-Info.plist\"; path = XcodeSupportFiles/" + Target.TargetName + "-Info.plist; sourceTree = \"<group>\"; };" + ProjectFileGenerator.NewLine;
                        }
                    }
                }
            }

            if (bOnlyFolderRefs)
            {
                WriteReferenceGroups(ref PBXFileReferenceSection, ref Groups);
            }

            PBXBuildFileSection += "/* End PBXBuildFile section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXFileReferenceSection += "/* End PBXFileReference section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            PBXResourcesBuildPhaseSection += "/* End PBXResourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXSourcesBuildPhaseSection += "/* End PBXSourcesBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXFrameworksBuildPhaseSection += "/* End PBXFrameworksBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;
            PBXShellScriptBuildPhaseSection += "/* End PBXShellScriptBuildPhase section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            string PBXTargetDependencySection = "/* Begin PBXTargetDependency section */" + ProjectFileGenerator.NewLine;
            CreateTargetDependencySection(ref PBXTargetDependencySection, TargetDependencies);
            PBXTargetDependencySection += "/* End PBXTargetDependency section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            string PBXContainerItemProxySection = "/* Begin PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine;
            CreateContainerItemProxySection(ref PBXContainerItemProxySection, ContainerItemProxies);
            PBXContainerItemProxySection += "/* End PBXContainerItemProxy section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine;

            XcodeProjectFileContent.Append (PBXBuildFileSection);
            XcodeProjectFileContent.Append (PBXFileReferenceSection);
            XcodeProjectFileContent.Append (PBXContainerItemProxySection);
            XcodeProjectFileContent.Append(PBXTargetDependencySection);

            AppendGroups(ref XcodeProjectFileContent, ref Groups, ProjectTargets, UE4XcodeHelperTarget, Frameworks);

            XcodeProjectFileContent.Append(PBXShellScriptBuildPhaseSection);
            XcodeProjectFileContent.Append(PBXSourcesBuildPhaseSection);
            XcodeProjectFileContent.Append(PBXFrameworksBuildPhaseSection);

            XcodeProjectFileContent.Append ("/* Begin PBXLegacyTarget section */" + ProjectFileGenerator.NewLine);
            foreach (var target in ProjectTargets)
            {
                if (target.Type == "Legacy")
                {
                    AppendTarget (ref XcodeProjectFileContent, target);
                }
            }
            XcodeProjectFileContent.Append ("/* End PBXLegacyTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append ("/* Begin PBXNativeTarget section */" + ProjectFileGenerator.NewLine);
            if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
            {
                AppendTarget (ref XcodeProjectFileContent, UE4XcodeHelperTarget);
            }
            foreach (XcodeProjectTarget Target in ProjectTargets)
            {
                if ((Target.Type == "Native" || Target.Type == "XCTest") && Target != UE4XcodeHelperTarget)
                {
                    AppendTarget(ref XcodeProjectFileContent, Target);
                }
            }
            XcodeProjectFileContent.Append ("/* End PBXNativeTarget section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append (
                "/* Begin PBXProject section */" + ProjectFileGenerator.NewLine +
                "\t\t" + UE4ProjectTarget.Guid + " /* Project object */ = {" + ProjectFileGenerator.NewLine +
                "\t\t\tisa = PBXProject;" + ProjectFileGenerator.NewLine +
                "\t\t\tattributes = {" + ProjectFileGenerator.NewLine +
                "\t\t\t\tLastUpgradeCheck = 0440;" + ProjectFileGenerator.NewLine +
                "\t\t\t\tORGANIZATIONNAME = EpicGames;" + ProjectFileGenerator.NewLine +
                "\t\t\t};" + ProjectFileGenerator.NewLine +
                "\t\t\tbuildConfigurationList = " + UE4ProjectTarget.BuildConfigGuild + " /* Build configuration list for PBXProject \"" + UE4ProjectTarget.DisplayName + "\" */;" + ProjectFileGenerator.NewLine +
                "\t\t\tcompatibilityVersion = \"Xcode 3.2\";" + ProjectFileGenerator.NewLine +
                "\t\t\tdevelopmentRegion = English;" + ProjectFileGenerator.NewLine +
                "\t\t\thasScannedForEncodings = 0;" + ProjectFileGenerator.NewLine +
                "\t\t\tknownRegions = (" + ProjectFileGenerator.NewLine +
                "\t\t\t\ten," + ProjectFileGenerator.NewLine +
                "\t\t\t);" + ProjectFileGenerator.NewLine +
                "\t\t\tmainGroup = " + MainGroupGuid + ";" + ProjectFileGenerator.NewLine +
                "\t\t\tproductRefGroup = " + ProductRefGroupGuid + " /* Products */;" + ProjectFileGenerator.NewLine +
                "\t\t\tprojectDirPath = \"\";" + ProjectFileGenerator.NewLine +
                "\t\t\tprojectRoot = \"\";" + ProjectFileGenerator.NewLine +
                "\t\t\ttargets = (" + ProjectFileGenerator.NewLine
            );
            foreach (var target in ProjectTargets)
            {
                if (target == UE4ProjectTarget || target == UE4XcodeHelperTarget)
                {
                    continue;
                }
                XcodeProjectFileContent.AppendLine (string.Format ("\t\t\t\t{0} /* {1} */,", target.Guid, target.DisplayName));
            }
            if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
            {
                XcodeProjectFileContent.Append ("\t\t\t\t" + UE4XcodeHelperTarget.Guid + " /* " + UE4XcodeHelperTarget.DisplayName + " */" + ProjectFileGenerator.NewLine);
            }
            XcodeProjectFileContent.Append (
                "\t\t\t);" + ProjectFileGenerator.NewLine +
                "\t\t};" + ProjectFileGenerator.NewLine +
                "/* End PBXProject section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine
            );

            string PreprocessorDefinitionsString = "\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (" + ProjectFileGenerator.NewLine;
            foreach (string Definition in PreprocessorDefinitions)
            {
                PreprocessorDefinitionsString += "\t\t\t\t\t\"" + Definition + "\"," + ProjectFileGenerator.NewLine;
            }
            PreprocessorDefinitionsString += "\t\t\t\t\t\"MONOLITHIC_BUILD=1\"," + ProjectFileGenerator.NewLine;
            PreprocessorDefinitionsString += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

            string HeaderSearchPaths = "\t\t\t\tUSER_HEADER_SEARCH_PATHS = (" + ProjectFileGenerator.NewLine;
            foreach (string Path in IncludeDirectories)
            {
                HeaderSearchPaths += "\t\t\t\t\t\"" + Path + "\"," + ProjectFileGenerator.NewLine;
            }
            HeaderSearchPaths += "\t\t\t\t);" + ProjectFileGenerator.NewLine;

            XcodeProjectFileContent.Append ("/* Begin XCBuildConfiguration section */" + ProjectFileGenerator.NewLine);
            AppendBuildConfig (ref XcodeProjectFileContent, UE4ProjectTarget, HeaderSearchPaths, PreprocessorDefinitionsString);
            foreach (var target in ProjectTargets)
            {
                if(target == UE4ProjectTarget || target == UE4XcodeHelperTarget)
                {
                    continue;
                }
                AppendBuildConfig (ref XcodeProjectFileContent, target);
            }
            if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
            {
                AppendBuildConfig (ref XcodeProjectFileContent, UE4XcodeHelperTarget);
            }
            XcodeProjectFileContent.Append ("/* End XCBuildConfiguration section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append ("/* Begin XCConfigurationList section */" + ProjectFileGenerator.NewLine);
            //AppendConfigList (ref XcodeProjectFileContent, UE4ProjectTarget);
            foreach (var target in ProjectTargets)
            {
                if(target == UE4XcodeHelperTarget)
                {
                    continue;
                }
                AppendConfigList (ref XcodeProjectFileContent, target);
            }
            if (ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
            {
                AppendConfigList (ref XcodeProjectFileContent, UE4XcodeHelperTarget);
            }
            XcodeProjectFileContent.Append ("/* End XCConfigurationList section */" + ProjectFileGenerator.NewLine + ProjectFileGenerator.NewLine);

            XcodeProjectFileContent.Append (
                "\t};" + ProjectFileGenerator.NewLine +
                "\trootObject = " + UE4ProjectTarget.Guid + " /* Project object */;" + ProjectFileGenerator.NewLine +
                "}" + ProjectFileGenerator.NewLine);

            string PathBranch = "";
            if (ExternalExecution.GetRuntimePlatform() != UnrealTargetPlatform.Mac)
            {
                PathBranch = "/Engine/Intermediate/IOS";
            }
            var XcodeProjectPath = MasterProjectRelativePath + PathBranch + "/" + MasterProjectName + ".xcodeproj";
            if (bGeneratingGameProjectFiles && GameProjectName == "UE4Game" && ExternalExecution.GetRuntimePlatform() == UnrealTargetPlatform.Mac)
            {
                XcodeProjectPath = UnrealBuildTool.GetUProjectPath () + PathBranch + "/" + MasterProjectName + ".xcodeproj";
            }
            if (!Directory.Exists (XcodeProjectPath))
            {
                Directory.CreateDirectory (XcodeProjectPath);
            }

            // load the existing project
            string InnerProjectFileName = XcodeProjectPath + "/project.pbxproj";
            string ExistingProjectContents = "";
            if (File.Exists(InnerProjectFileName))
            {
                ExistingProjectContents = File.ReadAllText(InnerProjectFileName);
            }

            // compare it to the new project
            string NewProjectContents = XcodeProjectFileContent.ToString();
            if (ExistingProjectContents != NewProjectContents)
            {
                Log.TraceInformation("Saving updated project file...");
                File.WriteAllText(InnerProjectFileName, NewProjectContents);
            }
            else
            {
                Log.TraceInformation("Skipping project file write, as it didn't change...");
            }

            // write scheme files for targets
            foreach (var Target in ProjectTargets)
            {
                if(Target == UE4ProjectTarget || Target == UE4XcodeHelperTarget)
                    continue;

                if (UnrealBuildTool.HasUProjectFile() && Target.TargetName.StartsWith(Path.GetFileNameWithoutExtension(UnrealBuildTool.GetUProjectFile())))
                {
                    if (Target.TargetName.EndsWith("Editor"))
                    {
                        WriteSchemeFile(XcodeProjectPath, Target, ".app", "UE4Editor", new List<string>(new string[] { "&quot;" + UnrealBuildTool.GetUProjectFile() + "&quot;" }));
                    }
                    else
                    {
                        string ProjectBinariesDir = UnrealBuildTool.GetUProjectPath() + "/Binaries/Mac/";
                        WriteSchemeFile(XcodeProjectPath, Target, ".app", ProjectBinariesDir + Target.TargetName);
                    }
                }
                else if(Target.TargetName.EndsWith("Game"))
                {
                    string ExeBaseName = Target.TargetName;
                    List<string> Args = null;
                    if (Target.TargetPlatform == UnrealTargetPlatform.Mac)
                    {
                        Args = new List<string>(new string[] { Target.TargetName });
                        ExeBaseName = "UE4";
                    }

                    WriteSchemeFile(XcodeProjectPath, Target, ".app", ExeBaseName, Args);
                }
                else if(Target.TargetName.EndsWith("Editor") && Target.TargetName != "UE4Editor")
                {
                    string GameName = Target.TargetName.Replace("Editor", "");
                    WriteSchemeFile(XcodeProjectPath, Target, ".app", "UE4Editor", new List<string>(new string[] { GameName }));
                }
                else if(TargetsThatNeedApp.Contains(Target.TargetName) || (Target.TargetPlatform == UnrealTargetPlatform.IOS))
                {
                    WriteSchemeFile(XcodeProjectPath, Target, ".app");
                }
                else
                {
                    WriteSchemeFile(XcodeProjectPath, Target);
                }
            }

            return true;
        }