/// <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; }
public XcodeFrameworkRef(XcodeFramework InFramework) { Guid = XcodeProjectFileGenerator.MakeXcodeGuid(); Framework = InFramework; }
/// <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[] { """ + UnrealBuildTool.GetUProjectFile() + """ })); } 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; }