private bool WriteQMakePro() { // Some more stuff borrowed from Mac side of things. List <string> IncludeDirectories = new List <string>(); List <string> SystemIncludeDirectories = new List <string>(); List <string> DefinesAndValues = new List <string>(); // DefineList.Add (""); string QMakeIncludesFileName = MasterProjectName + "Includes.pri"; StringBuilder QMakeIncludesPriFileContent = new StringBuilder(); string QMakeDefinesFileName = MasterProjectName + "Defines.pri"; StringBuilder QMakeDefinesPriFileContent = new StringBuilder(); string GameProjectPath = ""; string GameProjectFile = ""; string GameProjectRootPath = ""; string BuildCommand = ""; string QMakeGameProjectFile = ""; foreach (ProjectFile CurProject in GeneratedProjectFiles) { QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile; if (QMakeProject == null) { Log.TraceInformation("QMakeProject == null"); continue; } foreach (string CurPath in QMakeProject.IntelliSenseIncludeSearchPaths) { AddIncludeDirectory(ref IncludeDirectories, CurPath, Path.GetDirectoryName(QMakeProject.ProjectFilePath.FullName)); // System.Console.WriteLine ("Not empty now? CurPath == ", CurPath); } foreach (string CurPath in QMakeProject.IntelliSenseSystemIncludeSearchPaths) { AddIncludeDirectory(ref SystemIncludeDirectories, CurPath, Path.GetDirectoryName(QMakeProject.ProjectFilePath.FullName)); } } // Remove duplicate paths from include dir and system include dir list IncludeDirectories = IncludeDirectories.Distinct().ToList(); SystemIncludeDirectories = SystemIncludeDirectories.Distinct().ToList(); // Iterate through all the defines for the projects that are generated by // UnrealBuildTool.exe // !RAKE: move to seperate function QMakeDefinesPriFileContent.Append("DEFINES += \\\n"); foreach (ProjectFile CurProject in GeneratedProjectFiles) { QMakefileProjectFile QMakeProject = CurProject as QMakefileProjectFile; if (QMakeProject == null) { Log.TraceInformation("QMakeProject == null"); continue; } foreach (string CurDefine in QMakeProject.IntelliSensePreprocessorDefinitions) { String define = ""; String value = ""; SplitDefinitionAndValue(CurDefine, out define, out value); if (!DefinesAndValues.Contains(define)) { // Log.TraceInformation (CurDefine); if (string.IsNullOrEmpty(value)) { DefinesAndValues.Add("\t"); DefinesAndValues.Add(String.Format("{0}=", define)); DefinesAndValues.Add(" \\\n"); } else { DefinesAndValues.Add("\t"); DefinesAndValues.Add(define); DefinesAndValues.Add("="); DefinesAndValues.Add(value); DefinesAndValues.Add(" \\\n"); } } } } foreach (string Def in DefinesAndValues) { QMakeDefinesPriFileContent.Append(Def); } // Iterate through all the include paths that // UnrealBuildTool.exe generates // !RAKE: Move to seperate function QMakeIncludesPriFileContent.Append("INCLUDEPATH += \\\n"); foreach (string CurPath in IncludeDirectories) { QMakeIncludesPriFileContent.Append("\t"); QMakeIncludesPriFileContent.Append(CurPath); QMakeIncludesPriFileContent.Append(" \\\n"); } foreach (string CurPath in SystemIncludeDirectories) { QMakeIncludesPriFileContent.Append("\t"); QMakeIncludesPriFileContent.Append(CurPath); QMakeIncludesPriFileContent.Append(" \\\n"); } QMakeIncludesPriFileContent.Append("\n"); if (!String.IsNullOrEmpty(GameProjectName)) { GameProjectPath = OnlyGameProject.Directory.FullName; GameProjectFile = OnlyGameProject.FullName; QMakeGameProjectFile = "gameProjectFile=" + GameProjectFile + "\n"; BuildCommand = "build=bash $$unrealRootPath/Engine/Build/BatchFiles/Linux/RunMono.sh $$unrealRootPath/Engine/Binaries/DotNET/UnrealBuildTool.exe\n\n"; } else { BuildCommand = "build=bash $$unrealRootPath/Engine/Build/BatchFiles/Linux/Build.sh\n"; } string UnrealRootPath = UnrealBuildTool.RootDirectory.FullName; string FileName = MasterProjectName + ".pro"; string QMakeSourcePriFileName = MasterProjectName + "Source.pri"; string QMakeHeaderPriFileName = MasterProjectName + "Header.pri"; string QMakeConfigPriFileName = MasterProjectName + "Config.pri"; StringBuilder QMakeFileContent = new StringBuilder(); StringBuilder QMakeSourcePriFileContent = new StringBuilder(); StringBuilder QMakeHeaderPriFileContent = new StringBuilder(); StringBuilder QMakeConfigPriFileContent = new StringBuilder(); string QMakeSectionEnd = " \n\n"; string QMakeSourceFilesList = "SOURCES += \\ \n"; string QMakeHeaderFilesList = "HEADERS += \\ \n"; string QMakeConfigFilesList = "OTHER_FILES += \\ \n"; string QMakeTargetList = "QMAKE_EXTRA_TARGETS += \\ \n"; if (!String.IsNullOrEmpty(GameProjectName)) { GameProjectRootPath = GameProjectName + "RootPath=" + GameProjectPath + "\n\n"; } QMakeFileContent.Append( "# UnrealEngine.pro generated by QMakefileGenerator.cs\n" + "# *DO NOT EDIT*\n\n" + "TEMPLATE = aux\n" + "CONFIG += c++14\n" + "CONFIG -= console\n" + "CONFIG -= app_bundle\n" + "CONFIG -= qt\n\n" + "TARGET = UE4 \n\n" + "unrealRootPath=" + UnrealRootPath + "\n" + GameProjectRootPath + QMakeGameProjectFile + BuildCommand + "args=$(ARGS)\n\n" + "include(" + QMakeSourcePriFileName + ")\n" + "include(" + QMakeHeaderPriFileName + ")\n" + "include(" + QMakeConfigPriFileName + ")\n" + "include(" + QMakeIncludesFileName + ")\n" + "include(" + QMakeDefinesFileName + ")\n\n" ); // Create SourceFiles, HeaderFiles, and ConfigFiles sections. List <FileReference> AllModuleFiles = DiscoverModules(FindGameProjects()); foreach (FileReference CurModuleFile in AllModuleFiles) { List <FileReference> FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile); foreach (FileReference CurSourceFile in FoundFiles) { string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory); // Exclude some directories that we don't compile (note that we still want Windows/Mac etc for code navigation) if (!SourceFileRelativeToRoot.Contains("Source/ThirdParty/")) { if (SourceFileRelativeToRoot.EndsWith(".cpp")) { if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot)) { QMakeSourceFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n"); } else { if (String.IsNullOrEmpty(GameProjectName)) { QMakeSourceFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n"); } else { QMakeSourceFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n"); } } } if (SourceFileRelativeToRoot.EndsWith(".h")) { if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot)) { // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot; QMakeHeaderFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n"); } else { if (String.IsNullOrEmpty(GameProjectName)) { // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3); QMakeHeaderFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n"); } else { QMakeHeaderFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n"); } } } if (SourceFileRelativeToRoot.EndsWith(".cs")) { if (!SourceFileRelativeToRoot.StartsWith("..") && !Path.IsPathRooted(SourceFileRelativeToRoot)) { // SourceFileRelativeToRoot = "Engine/" + SourceFileRelativeToRoot; QMakeConfigFilesList += ("\t\"" + "$$unrealRootPath/Engine/" + SourceFileRelativeToRoot + "\" \\\n"); } else { if (String.IsNullOrEmpty(GameProjectName)) { // SourceFileRelativeToRoot = SourceFileRelativeToRoot.Substring (3); QMakeConfigFilesList += ("\t\"" + SourceFileRelativeToRoot.Substring(3) + "\" \\\n"); } else { QMakeConfigFilesList += ("\t\"$$" + GameProjectName + "RootPath/" + Utils.MakePathRelativeTo(CurSourceFile.FullName, GameProjectPath) + "\" \\\n"); } } } } } } // Add section end to section strings; QMakeSourceFilesList += QMakeSectionEnd; QMakeHeaderFilesList += QMakeSectionEnd; QMakeConfigFilesList += QMakeSectionEnd; // Append sections to the QMakeLists.txt file QMakeSourcePriFileContent.Append(QMakeSourceFilesList); QMakeHeaderPriFileContent.Append(QMakeHeaderFilesList); QMakeConfigPriFileContent.Append(QMakeConfigFilesList); string QMakeProjectCmdArg = ""; foreach (ProjectFile Project in GeneratedProjectFiles) { foreach (ProjectTarget TargetFile in Project.ProjectTargets) { if (TargetFile.TargetFilePath == null) { continue; } string TargetName = TargetFile.TargetFilePath.GetFileNameWithoutAnyExtensions(); // Remove both ".cs" and ". foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor")) { QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\""; } string ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); QMakeFileContent.Append(String.Format("{0}-Linux-{1}.commands = $$build {0} Linux {1} {2} $$args\n", TargetName, ConfName, QMakeProjectCmdArg)); QMakeTargetList += "\t" + TargetName + "-Linux-" + ConfName + " \\\n"; // , TargetName, ConfName); } } } if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor")) { QMakeProjectCmdArg = " -project=\"\\\"$$gameProjectFile\\\"\""; } QMakeFileContent.Append(String.Format("{0}.commands = $$build {0} Linux Development {1} $$args\n\n", TargetName, QMakeProjectCmdArg)); QMakeTargetList += "\t" + TargetName + " \\\n"; } } QMakeFileContent.Append(QMakeTargetList.TrimEnd('\\')); string FullFileName = Path.Combine(MasterProjectPath.FullName, FileName); string FullQMakeDefinesFileName = Path.Combine(MasterProjectPath.FullName, QMakeDefinesFileName); string FullQMakeIncludesFileName = Path.Combine(MasterProjectPath.FullName, QMakeIncludesFileName); string FullQMakeSourcePriFileName = Path.Combine(MasterProjectPath.FullName, QMakeSourcePriFileName); string FullQMakeHeaderPriFileName = Path.Combine(MasterProjectPath.FullName, QMakeHeaderPriFileName); string FullQMakeConfigPriFileName = Path.Combine(MasterProjectPath.FullName, QMakeConfigPriFileName); WriteFileIfChanged(FullQMakeDefinesFileName, QMakeDefinesPriFileContent.ToString()); WriteFileIfChanged(FullQMakeIncludesFileName, QMakeIncludesPriFileContent.ToString()); WriteFileIfChanged(FullQMakeSourcePriFileName, QMakeSourcePriFileContent.ToString()); WriteFileIfChanged(FullQMakeHeaderPriFileName, QMakeHeaderPriFileContent.ToString()); WriteFileIfChanged(FullQMakeConfigPriFileName, QMakeConfigPriFileContent.ToString()); return(WriteFileIfChanged(FullFileName, QMakeFileContent.ToString())); }
protected override bool WriteMasterProjectFile(ProjectFile UBTProject) { string SolutionFileName = MasterProjectName + SolutionExtension; string CodeCompletionFile = MasterProjectName + CodeCompletionFileName; string CodeCompletionPreProcessorFile = MasterProjectName + CodeCompletionPreProcessorFileName; string FullCodeLiteMasterFile = Path.Combine(MasterProjectPath.FullName, SolutionFileName); string FullCodeLiteCodeCompletionFile = Path.Combine(MasterProjectPath.FullName, CodeCompletionFile); string FullCodeLiteCodeCompletionPreProcessorFile = Path.Combine(MasterProjectPath.FullName, CodeCompletionPreProcessorFile); // // HACK // TODO This is for now a hack. According to the original submitter, Eranif (a CodeLite developer) will support code completion folders in *.workspace files. // We create a separate file with all the folder name in it to copy manually into the code completion // filed of CodeLite workspace. (Workspace Settings/Code Completion -> copy the content of the file threre.) List <string> IncludeDirectories = new List <string>(); List <string> PreProcessor = new List <string>(); foreach (ProjectFile CurProject in GeneratedProjectFiles) { CodeLiteProject Project = CurProject as CodeLiteProject; if (Project == null) { continue; } foreach (string CurrentPath in Project.IntelliSenseIncludeSearchPaths) { // Convert relative path into absolute. DirectoryReference IntelliSenseIncludeSearchPath = DirectoryReference.Combine(Project.ProjectFilePath.Directory, CurrentPath); IncludeDirectories.Add(IntelliSenseIncludeSearchPath.FullName); } foreach (string CurrentPath in Project.IntelliSenseSystemIncludeSearchPaths) { // Convert relative path into absolute. DirectoryReference IntelliSenseSystemIncludeSearchPath = DirectoryReference.Combine(Project.ProjectFilePath.Directory, CurrentPath); IncludeDirectories.Add(IntelliSenseSystemIncludeSearchPath.FullName); } foreach (string CurDef in Project.IntelliSensePreprocessorDefinitions) { if (!PreProcessor.Contains(CurDef)) { PreProcessor.Add(CurDef); } } } // // Write code completions data into files. // File.WriteAllLines(FullCodeLiteCodeCompletionFile, IncludeDirectories); File.WriteAllLines(FullCodeLiteCodeCompletionPreProcessorFile, PreProcessor); // // Write CodeLites Workspace // XmlWriterSettings settings = new XmlWriterSettings(); settings.Indent = true; XElement CodeLiteWorkspace = new XElement("CodeLite_Workspace"); XAttribute CodeLiteWorkspaceName = new XAttribute("Name", MasterProjectName); XAttribute CodeLiteWorkspaceSWTLW = new XAttribute("SWTLW", "Yes"); // This flag will only work in CodeLite version > 8.0. See below CodeLiteWorkspace.Add(CodeLiteWorkspaceName); CodeLiteWorkspace.Add(CodeLiteWorkspaceSWTLW); // // ATTN This part will work for the next release of CodeLite. That may // be CodeLite version > 8.0. CodeLite 8.0 does not have this functionality. // TODO Macros are ignored for now. // // Write Code Completion folders into the WorkspaceParserPaths section. // XElement CodeLiteWorkspaceParserPaths = new XElement("WorkspaceParserPaths"); foreach (string CurrentPath in IncludeDirectories) { XElement CodeLiteWorkspaceParserPathInclude = new XElement("Include"); XAttribute CodeLiteWorkspaceParserPath = new XAttribute("Path", CurrentPath); CodeLiteWorkspaceParserPathInclude.Add(CodeLiteWorkspaceParserPath); CodeLiteWorkspaceParserPaths.Add(CodeLiteWorkspaceParserPathInclude); } CodeLiteWorkspace.Add(CodeLiteWorkspaceParserPaths); // // Write project file information into CodeLite's workspace file. // XElement CodeLiteWorkspaceTargetEngine = null; XElement CodeLiteWorkspaceTargetPrograms = null; XElement CodeLiteWorkspaceTargetGame = null; foreach (ProjectFile CurProject in AllProjectFiles) { string ProjectExtension = CurProject.ProjectFilePath.GetExtension(); // // TODO For now ignore C# project files. // if (ProjectExtension == ".csproj") { continue; } // // Iterate through all targets. // foreach (ProjectTarget CurrentTarget in CurProject.ProjectTargets) { string[] tmp = CurrentTarget.ToString().Split('.'); string ProjectTargetFileName = CurProject.ProjectFilePath.Directory.MakeRelativeTo(MasterProjectPath) + "/" + tmp[0] + ProjectExtension; String ProjectName = tmp[0]; XElement CodeLiteWorkspaceProject = new XElement("Project"); XAttribute CodeLiteWorkspaceProjectName = new XAttribute("Name", ProjectName); XAttribute CodeLiteWorkspaceProjectPath = new XAttribute("Path", ProjectTargetFileName); XAttribute CodeLiteWorkspaceProjectActive = new XAttribute("Active", "No"); CodeLiteWorkspaceProject.Add(CodeLiteWorkspaceProjectName); CodeLiteWorkspaceProject.Add(CodeLiteWorkspaceProjectPath); CodeLiteWorkspaceProject.Add(CodeLiteWorkspaceProjectActive); // // For CodeLite 10 we can use virtual folder to group projects. // if (ProjectFileFormat == CodeliteProjectFileFormat.CodeLite10) { if ((CurrentTarget.TargetRules.Type == TargetType.Client) || (CurrentTarget.TargetRules.Type == TargetType.Server) || (CurrentTarget.TargetRules.Type == TargetType.Editor) || (CurrentTarget.TargetRules.Type == TargetType.Game)) { if (ProjectName.Equals("UE4Client") || ProjectName.Equals("UE4Server") || ProjectName.Equals("UE4Game") || ProjectName.Equals("UE4Editor")) { if (CodeLiteWorkspaceTargetEngine == null) { CodeLiteWorkspaceTargetEngine = new XElement("VirtualDirectory"); XAttribute CodeLiteWorkspaceTargetEngineName = new XAttribute("Name", "Engine"); CodeLiteWorkspaceTargetEngine.Add(CodeLiteWorkspaceTargetEngineName); } CodeLiteWorkspaceTargetEngine.Add(CodeLiteWorkspaceProject); } else { if (CodeLiteWorkspaceTargetGame == null) { CodeLiteWorkspaceTargetGame = new XElement("VirtualDirectory"); XAttribute CodeLiteWorkspaceTargetGameName = new XAttribute("Name", "Game"); CodeLiteWorkspaceTargetGame.Add(CodeLiteWorkspaceTargetGameName); } CodeLiteWorkspaceTargetGame.Add(CodeLiteWorkspaceProject); } } else if (CurrentTarget.TargetRules.Type == TargetType.Program) { if (CodeLiteWorkspaceTargetPrograms == null) { CodeLiteWorkspaceTargetPrograms = new XElement("VirtualDirectory"); XAttribute CodeLiteWorkspaceTargetProgramsName = new XAttribute("Name", "Programs"); CodeLiteWorkspaceTargetPrograms.Add(CodeLiteWorkspaceTargetProgramsName); } CodeLiteWorkspaceTargetPrograms.Add(CodeLiteWorkspaceProject); } } else if (ProjectFileFormat == CodeliteProjectFileFormat.CodeLite9) { CodeLiteWorkspace.Add(CodeLiteWorkspaceProject); } } } if (ProjectFileFormat == CodeliteProjectFileFormat.CodeLite10) { if (CodeLiteWorkspaceTargetEngine != null) { CodeLiteWorkspace.Add(CodeLiteWorkspaceTargetEngine); } if (CodeLiteWorkspaceTargetPrograms != null) { CodeLiteWorkspace.Add(CodeLiteWorkspaceTargetPrograms); } if (CodeLiteWorkspaceTargetGame != null) { CodeLiteWorkspace.Add(CodeLiteWorkspaceTargetGame); } } // // We need to create the configuration matrix. That will assign the project configuration to // the samge workspace configuration. // XElement CodeLiteWorkspaceBuildMatrix = new XElement("BuildMatrix"); foreach (UnrealTargetConfiguration CurConfiguration in SupportedConfigurations) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { XElement CodeLiteWorkspaceBuildMatrixConfiguration = new XElement("WorkspaceConfiguration"); XAttribute CodeLiteWorkspaceProjectName = new XAttribute("Name", CurConfiguration.ToString()); XAttribute CodeLiteWorkspaceProjectSelected = new XAttribute("Selected", "no"); CodeLiteWorkspaceBuildMatrixConfiguration.Add(CodeLiteWorkspaceProjectName); CodeLiteWorkspaceBuildMatrixConfiguration.Add(CodeLiteWorkspaceProjectSelected); foreach (ProjectFile CurProject in AllProjectFiles) { string ProjectExtension = CurProject.ProjectFilePath.GetExtension(); // // TODO For now ignore C# project files. // if (ProjectExtension == ".csproj") { continue; } foreach (ProjectTarget target in CurProject.ProjectTargets) { string[] tmp = target.ToString().Split('.'); String ProjectName = tmp[0]; XElement CodeLiteWorkspaceBuildMatrixConfigurationProject = new XElement("Project"); XAttribute CodeLiteWorkspaceBuildMatrixConfigurationProjectName = new XAttribute("Name", ProjectName); XAttribute CodeLiteWorkspaceBuildMatrixConfigurationProjectConfigName = new XAttribute("ConfigName", CurConfiguration.ToString()); CodeLiteWorkspaceBuildMatrixConfigurationProject.Add(CodeLiteWorkspaceBuildMatrixConfigurationProjectName); CodeLiteWorkspaceBuildMatrixConfigurationProject.Add(CodeLiteWorkspaceBuildMatrixConfigurationProjectConfigName); CodeLiteWorkspaceBuildMatrixConfiguration.Add(CodeLiteWorkspaceBuildMatrixConfigurationProject); } } CodeLiteWorkspaceBuildMatrix.Add(CodeLiteWorkspaceBuildMatrixConfiguration); } } CodeLiteWorkspace.Add(CodeLiteWorkspaceBuildMatrix); CodeLiteWorkspace.Save(FullCodeLiteMasterFile); return(true); }
private bool WriteMakefile() { string GameProjectFile = ""; string BuildCommand = ""; string ProjectBuildCommand = ""; string MakeGameProjectFile = ""; string UnrealRootPath = UnrealBuildTool.RootDirectory.FullName; if (!String.IsNullOrEmpty(GameProjectName)) { GameProjectFile = OnlyGameProject.FullName; MakeGameProjectFile = "GAMEPROJECTFILE =" + GameProjectFile + "\n"; ProjectBuildCommand = "PROJECTBUILD = bash \"$(UNREALROOTPATH)/Engine/Build/BatchFiles/Linux/RunMono.sh\" \"$(UNREALROOTPATH)/Engine/Binaries/DotNET/UnrealBuildTool.exe\"\n"; } BuildCommand = "BUILD = bash \"$(UNREALROOTPATH)/Engine/Build/BatchFiles/Linux/Build.sh\"\n"; string FileName = "Makefile"; // MasterProjectName + ".mk"; StringBuilder MakefileContent = new StringBuilder(); MakefileContent.Append( "# Makefile generated by MakefileGenerator.cs\n" + "# *DO NOT EDIT*\n\n" + "UNREALROOTPATH = " + UnrealRootPath + "\n" + MakeGameProjectFile + "\n" + "TARGETS =" ); String MakeProjectCmdArg = ""; String MakeBuildCommand = ""; foreach (ProjectFile Project in GeneratedProjectFiles) { foreach (ProjectTarget TargetFile in Project.ProjectTargets) { if (TargetFile.TargetFilePath == null) { continue; } string TargetFileName = TargetFile.TargetFilePath.GetFileNameWithoutExtension(); string Basename = TargetFileName.Substring(0, TargetFileName.LastIndexOf(".Target", StringComparison.InvariantCultureIgnoreCase)); foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { string Confname = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); MakefileContent.Append(String.Format(" \\\n\t{0}-Linux-{1} ", Basename, Confname)); } } } MakefileContent.Append(" \\\n\t" + Basename); } } MakefileContent.Append("\\\n\tconfigure"); MakefileContent.Append("\n\n" + BuildCommand + ProjectBuildCommand + "\n" + "all: StandardSet\n\n" + "RequiredTools: CrashReportClient-Linux-Shipping ShaderCompileWorker UnrealLightmass\n\n" + "StandardSet: RequiredTools UnrealFrontend UE4Editor\n\n" + "DebugSet: RequiredTools UnrealFrontend-Linux-Debug UE4Editor-Linux-Debug\n\n" ); foreach (ProjectFile Project in GeneratedProjectFiles) { foreach (ProjectTarget TargetFile in Project.ProjectTargets) { if (TargetFile.TargetFilePath == null) { continue; } string TargetFileName = TargetFile.TargetFilePath.GetFileNameWithoutExtension(); string Basename = TargetFileName.Substring(0, TargetFileName.LastIndexOf(".Target", StringComparison.InvariantCultureIgnoreCase)); if (Basename == GameProjectName || Basename == (GameProjectName + "Editor")) { MakeProjectCmdArg = " -project=\"$(GAMEPROJECTFILE)\""; MakeBuildCommand = "$(PROJECTBUILD)"; } else { MakeBuildCommand = "$(BUILD)"; } foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (Basename == GameProjectName || Basename == (GameProjectName + "Editor")) { MakeProjectCmdArg = " -project=\"$(GAMEPROJECTFILE)\""; MakeBuildCommand = "$(PROJECTBUILD)"; } else { MakeBuildCommand = "$(BUILD)"; } if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { string Confname = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); MakefileContent.Append(String.Format("\n{1}-Linux-{2}:\n\t {0} {1} Linux {2} {3} $(ARGS)\n", MakeBuildCommand, Basename, Confname, MakeProjectCmdArg)); } } } MakefileContent.Append(String.Format("\n{1}:\n\t {0} {1} Linux Development {2} $(ARGS)\n", MakeBuildCommand, Basename, MakeProjectCmdArg)); } } MakefileContent.Append("\nconfigure:\n"); if (!String.IsNullOrEmpty(GameProjectName)) { // Make sure UBT is updated. MakefileContent.Append("\txbuild /property:Configuration=Development /verbosity:quiet /nologo "); MakefileContent.Append("\"$(UNREALROOTPATH)/Engine/Source/Programs/UnrealBuildTool/UnrealBuildTool.csproj\"\n"); MakefileContent.Append("\t$(PROJECTBUILD) -projectfiles -project=\"\\\"$(GAMEPROJECTFILE)\\\"\" -game -engine \n"); } else { MakefileContent.Append("\tbash \"$(UNREALROOTPATH)/GenerateProjectFiles.sh\" \n"); } MakefileContent.Append("\n.PHONY: $(TARGETS)\n"); FileReference FullFileName = FileReference.Combine(MasterProjectPath, FileName); return(WriteFileIfChanged(FullFileName.FullName, MakefileContent.ToString())); }
protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators) { bool bSuccess = true; string SolutionFileName = MasterProjectName + ".sln"; // Setup solution file content StringBuilder VCSolutionFileContent = new StringBuilder(); // Solution file header. Note that a leading newline is required for file type detection to work correclty in the shell. if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2019) { VCSolutionFileContent.AppendLine(); VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); VCSolutionFileContent.AppendLine("# Visual Studio Version 16"); VCSolutionFileContent.AppendLine("VisualStudioVersion = 16.0.28315.86"); VCSolutionFileContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); } else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2017) { VCSolutionFileContent.AppendLine(); VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); VCSolutionFileContent.AppendLine("# Visual Studio 15"); VCSolutionFileContent.AppendLine("VisualStudioVersion = 15.0.25807.0"); VCSolutionFileContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); } else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2015) { VCSolutionFileContent.AppendLine(); VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); VCSolutionFileContent.AppendLine("# Visual Studio 14"); VCSolutionFileContent.AppendLine("VisualStudioVersion = 14.0.22310.1"); VCSolutionFileContent.AppendLine("MinimumVisualStudioVersion = 10.0.40219.1"); } else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2013) { VCSolutionFileContent.AppendLine(); VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); VCSolutionFileContent.AppendLine("# Visual Studio 2013"); } else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2012) { VCSolutionFileContent.AppendLine(); VCSolutionFileContent.AppendLine("Microsoft Visual Studio Solution File, Format Version 12.00"); VCSolutionFileContent.AppendLine("# Visual Studio 2012"); } else { throw new BuildException("Unexpected ProjectFileFormat"); } // Solution folders, files and project entries { // This the GUID that Visual Studio uses to identify a solution folder string SolutionFolderEntryGUID = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}"; // Solution folders { List <MasterProjectFolder> AllSolutionFolders = new List <MasterProjectFolder>(); System.Action <List <MasterProjectFolder> /* Folders */> GatherFoldersFunction = null; GatherFoldersFunction = FolderList => { AllSolutionFolders.AddRange(FolderList); foreach (MasterProjectFolder CurSubFolder in FolderList) { GatherFoldersFunction(CurSubFolder.SubFolders); } }; GatherFoldersFunction(RootFolder.SubFolders); AllSolutionFolders.Sort((Lhs, Rhs) => Lhs.FolderName.CompareTo(Rhs.FolderName)); foreach (VisualStudioSolutionFolder CurFolder in AllSolutionFolders) { string FolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant(); VCSolutionFileContent.AppendLine("Project(\"" + SolutionFolderEntryGUID + "\") = \"" + CurFolder.FolderName + "\", \"" + CurFolder.FolderName + "\", \"" + FolderGUIDString + "\""); // Add any files that are inlined right inside the solution folder if (CurFolder.Files.Count > 0) { VCSolutionFileContent.AppendLine(" ProjectSection(SolutionItems) = preProject"); foreach (string CurFile in CurFolder.Files) { // Syntax is: <relative file path> = <relative file path> VCSolutionFileContent.AppendLine(" "+ CurFile + " = " + CurFile); } VCSolutionFileContent.AppendLine(" EndProjectSection"); } VCSolutionFileContent.AppendLine("EndProject"); } } // Project files List <MSBuildProjectFile> AllProjectFilesSorted = AllProjectFiles.OrderBy((ProjFile) => ProjFile.ProjectFilePath.GetFileNameWithoutExtension()).Cast <MSBuildProjectFile>().ToList(); foreach (MSBuildProjectFile CurProject in AllProjectFiles) { // Visual Studio uses different GUID types depending on the project type string ProjectTypeGUID = CurProject.ProjectTypeGUID; // NOTE: The project name in the solution doesn't actually *have* to match the project file name on disk. However, // we prefer it when it does match so we use the actual file name here. string ProjectNameInSolution = CurProject.ProjectFilePath.GetFileNameWithoutExtension(); // Use the existing project's GUID that's already known to us string ProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant(); VCSolutionFileContent.AppendLine("Project(\"" + ProjectTypeGUID + "\") = \"" + ProjectNameInSolution + "\", \"" + CurProject.ProjectFilePath.MakeRelativeTo(ProjectFileGenerator.MasterProjectPath) + "\", \"" + ProjectGUID + "\""); // Setup dependency on UnrealBuildTool, if we need that. This makes sure that UnrealBuildTool is // freshly compiled before kicking off any build operations on this target project if (!CurProject.IsStubProject) { List <ProjectFile> Dependencies = new List <ProjectFile>(); if (CurProject.IsGeneratedProject && UBTProject != null && CurProject != UBTProject) { Dependencies.Add(UBTProject); Dependencies.AddRange(UBTProject.DependsOnProjects); } Dependencies.AddRange(CurProject.DependsOnProjects); if (Dependencies.Count > 0) { VCSolutionFileContent.AppendLine("\tProjectSection(ProjectDependencies) = postProject"); // Setup any addition dependencies this project has... foreach (ProjectFile DependsOnProject in Dependencies) { string DependsOnProjectGUID = ((MSBuildProjectFile)DependsOnProject).ProjectGUID.ToString("B").ToUpperInvariant(); VCSolutionFileContent.AppendLine("\t\t" + DependsOnProjectGUID + " = " + DependsOnProjectGUID); } VCSolutionFileContent.AppendLine("\tEndProjectSection"); } } VCSolutionFileContent.AppendLine("EndProject"); } // Get the path to the visualizers file. Try to make it relative to the solution directory, but fall back to a full path if it's a foreign project. FileReference VisualizersFile = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "VisualStudioDebugging", "UE4.natvis"); // Add the visualizers at the solution level. Doesn't seem to be picked up from a makefile project in VS2017 15.8.5. VCSolutionFileContent.AppendLine(String.Format("Project(\"{{2150E333-8FDC-42A3-9474-1A3956D46DE8}}\") = \"Visualizers\", \"Visualizers\", \"{0}\"", Guid.NewGuid().ToString("B").ToUpperInvariant())); VCSolutionFileContent.AppendLine("\tProjectSection(SolutionItems) = preProject"); VCSolutionFileContent.AppendLine("\t\t{0} = {0}", VisualizersFile.MakeRelativeTo(MasterProjectPath)); VCSolutionFileContent.AppendLine("\tEndProjectSection"); VCSolutionFileContent.AppendLine("EndProject"); } // Solution configuration platforms. This is just a list of all of the platforms and configurations that // appear in Visual Studio's build configuration selector. List <VCSolutionConfigCombination> SolutionConfigCombinations = new List <VCSolutionConfigCombination>(); // The "Global" section has source control, solution configurations, project configurations, // preferences, and project hierarchy data { VCSolutionFileContent.AppendLine("Global"); { { VCSolutionFileContent.AppendLine(" GlobalSection(SolutionConfigurationPlatforms) = preSolution"); Dictionary <string, Tuple <UnrealTargetConfiguration, TargetType> > SolutionConfigurationsValidForProjects = new Dictionary <string, Tuple <UnrealTargetConfiguration, TargetType> >(); HashSet <UnrealTargetPlatform> PlatformsValidForProjects = new HashSet <UnrealTargetPlatform>(); foreach (UnrealTargetConfiguration CurConfiguration in SupportedConfigurations) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { foreach (UnrealTargetPlatform CurPlatform in SupportedPlatforms) { if (InstalledPlatformInfo.IsValidPlatform(CurPlatform, EProjectType.Code)) { foreach (ProjectFile CurProject in AllProjectFiles) { if (!CurProject.IsStubProject) { if (CurProject.ProjectTargets.Count == 0) { throw new BuildException("Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!"); } // Figure out the set of valid target configuration names foreach (ProjectTarget ProjectTarget in CurProject.ProjectTargets) { if (VCProjectFile.IsValidProjectPlatformAndConfiguration(ProjectTarget, CurPlatform, CurConfiguration, PlatformProjectGenerators)) { PlatformsValidForProjects.Add(CurPlatform); // Default to a target configuration name of "Game", since that will collapse down to an empty string TargetType TargetType = TargetType.Game; if (ProjectTarget.TargetRules != null) { TargetType = ProjectTarget.TargetRules.Type; } string SolutionConfigName = MakeSolutionConfigurationName(CurConfiguration, TargetType); SolutionConfigurationsValidForProjects[SolutionConfigName] = new Tuple <UnrealTargetConfiguration, TargetType>(CurConfiguration, TargetType); } } } } } } } } foreach (UnrealTargetPlatform CurPlatform in PlatformsValidForProjects) { foreach (KeyValuePair <string, Tuple <UnrealTargetConfiguration, TargetType> > SolutionConfigKeyValue in SolutionConfigurationsValidForProjects) { // e.g. "Development|Win64 = Development|Win64" string SolutionConfigName = SolutionConfigKeyValue.Key; UnrealTargetConfiguration Configuration = SolutionConfigKeyValue.Value.Item1; TargetType TargetType = SolutionConfigKeyValue.Value.Item2; string SolutionPlatformName = CurPlatform.ToString(); string SolutionConfigAndPlatformPair = SolutionConfigName + "|" + SolutionPlatformName; SolutionConfigCombinations.Add( new VCSolutionConfigCombination { VCSolutionConfigAndPlatformName = SolutionConfigAndPlatformPair, Configuration = Configuration, Platform = CurPlatform, TargetConfigurationName = TargetType } ); } } // Sort the list of solution platform strings alphabetically (Visual Studio prefers it) SolutionConfigCombinations.Sort( new Comparison <VCSolutionConfigCombination>( (x, y) => { return(String.Compare(x.VCSolutionConfigAndPlatformName, y.VCSolutionConfigAndPlatformName, StringComparison.InvariantCultureIgnoreCase)); } ) ); HashSet <string> AppendedSolutionConfigAndPlatformNames = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase); foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations) { // We alias "Game" and "Program" to both have the same solution configuration, so we're careful not to add the same combination twice. if (!AppendedSolutionConfigAndPlatformNames.Contains(SolutionConfigCombination.VCSolutionConfigAndPlatformName)) { VCSolutionFileContent.AppendLine(" "+ SolutionConfigCombination.VCSolutionConfigAndPlatformName + " = " + SolutionConfigCombination.VCSolutionConfigAndPlatformName); AppendedSolutionConfigAndPlatformNames.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName); } } VCSolutionFileContent.AppendLine(" EndGlobalSection"); } // Assign each project's "project configuration" to our "solution platform + configuration" pairs. This // also sets up which projects are actually built when building the solution. { VCSolutionFileContent.AppendLine(" GlobalSection(ProjectConfigurationPlatforms) = postSolution"); foreach (MSBuildProjectFile CurProject in AllProjectFiles) { foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations) { // Get the context for the current solution context MSBuildProjectContext ProjectContext = CurProject.GetMatchingProjectContext(SolutionConfigCombination.TargetConfigurationName, SolutionConfigCombination.Configuration, SolutionConfigCombination.Platform, PlatformProjectGenerators); // Write the solution mapping (e.g. "{4232C52C-680F-4850-8855-DC39419B5E9B}.Debug|iOS.ActiveCfg = iOS_Debug|Win32") string CurProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant(); VCSolutionFileContent.AppendLine(" {0}.{1}.ActiveCfg = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name); if (ProjectContext.bBuildByDefault) { VCSolutionFileContent.AppendLine(" {0}.{1}.Build.0 = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name); if (ProjectContext.bDeployByDefault) { VCSolutionFileContent.AppendLine(" {0}.{1}.Deploy.0 = {2}", CurProjectGUID, SolutionConfigCombination.VCSolutionConfigAndPlatformName, ProjectContext.Name); } } } } VCSolutionFileContent.AppendLine(" EndGlobalSection"); } // Setup other solution properties { // HideSolutionNode sets whether or not the top-level solution entry is completely hidden in the UI. // We don't want that, as we need users to be able to right click on the solution tree item. VCSolutionFileContent.AppendLine(" GlobalSection(SolutionProperties) = preSolution"); VCSolutionFileContent.AppendLine(" HideSolutionNode = FALSE"); VCSolutionFileContent.AppendLine(" EndGlobalSection"); } // Solution directory hierarchy { VCSolutionFileContent.AppendLine(" GlobalSection(NestedProjects) = preSolution"); // Every entry in this section is in the format "Guid1 = Guid2". Guid1 is the child project (or solution // filter)'s GUID, and Guid2 is the solution filter directory to parent the child project (or solution // filter) to. This sets up the hierarchical solution explorer tree for all solution folders and projects. System.Action <StringBuilder /* VCSolutionFileContent */, List <MasterProjectFolder> /* Folders */> FolderProcessorFunction = null; FolderProcessorFunction = (LocalVCSolutionFileContent, LocalMasterProjectFolders) => { foreach (VisualStudioSolutionFolder CurFolder in LocalMasterProjectFolders) { string CurFolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant(); foreach (MSBuildProjectFile ChildProject in CurFolder.ChildProjects) { // e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}" LocalVCSolutionFileContent.AppendLine(" "+ ChildProject.ProjectGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString); } foreach (VisualStudioSolutionFolder SubFolder in CurFolder.SubFolders) { // e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}" LocalVCSolutionFileContent.AppendLine(" "+ SubFolder.FolderGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString); } // Recurse into subfolders FolderProcessorFunction(LocalVCSolutionFileContent, CurFolder.SubFolders); } }; FolderProcessorFunction(VCSolutionFileContent, RootFolder.SubFolders); VCSolutionFileContent.AppendLine(" EndGlobalSection"); } } VCSolutionFileContent.AppendLine("EndGlobal"); } // Save the solution file if (bSuccess) { string SolutionFilePath = FileReference.Combine(MasterProjectPath, SolutionFileName).FullName; bSuccess = WriteFileIfChanged(SolutionFilePath, VCSolutionFileContent.ToString()); } // Save a solution config file which selects the development editor configuration by default. if (bSuccess && bWriteSolutionOptionFile) { // Figure out the filename for the SUO file. VS will automatically import the options from earlier versions if necessary. FileReference SolutionOptionsFileName; switch (ProjectFileFormat) { case VCProjectFileFormat.VisualStudio2012: SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, Path.ChangeExtension(SolutionFileName, "v11.suo")); break; case VCProjectFileFormat.VisualStudio2013: SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, Path.ChangeExtension(SolutionFileName, "v12.suo")); break; case VCProjectFileFormat.VisualStudio2015: SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, ".vs", Path.GetFileNameWithoutExtension(SolutionFileName), "v14", ".suo"); break; case VCProjectFileFormat.VisualStudio2017: SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, ".vs", Path.GetFileNameWithoutExtension(SolutionFileName), "v15", ".suo"); break; case VCProjectFileFormat.VisualStudio2019: SolutionOptionsFileName = FileReference.Combine(MasterProjectPath, ".vs", Path.GetFileNameWithoutExtension(SolutionFileName), "v15", ".suo"); // Still uses v15 break; default: throw new BuildException("Unsupported Visual Studio version"); } // Check it doesn't exist before overwriting it. Since these files store the user's preferences, it'd be bad form to overwrite them. if (!FileReference.Exists(SolutionOptionsFileName)) { DirectoryReference.CreateDirectory(SolutionOptionsFileName.Directory); VCSolutionOptions Options = new VCSolutionOptions(ProjectFileFormat); // Set the default configuration and startup project VCSolutionConfigCombination DefaultConfig = SolutionConfigCombinations.Find(x => x.Configuration == UnrealTargetConfiguration.Development && x.Platform == UnrealTargetPlatform.Win64 && x.TargetConfigurationName == TargetType.Editor); if (DefaultConfig != null) { List <VCBinarySetting> Settings = new List <VCBinarySetting>(); Settings.Add(new VCBinarySetting("ActiveCfg", DefaultConfig.VCSolutionConfigAndPlatformName)); if (DefaultProject != null) { Settings.Add(new VCBinarySetting("StartupProject", ((MSBuildProjectFile)DefaultProject).ProjectGUID.ToString("B"))); } Options.SetConfiguration(Settings); } // Mark all the projects as closed by default, apart from the startup project VCSolutionExplorerState ExplorerState = new VCSolutionExplorerState(); if (ProjectFileFormat >= VCProjectFileFormat.VisualStudio2017) { BuildSolutionExplorerState_VS2017(RootFolder, "", ExplorerState, DefaultProject); } else { BuildSolutionExplorerState_VS2015(AllProjectFiles, ExplorerState, DefaultProject, IncludeEnginePrograms); } Options.SetExplorerState(ExplorerState); // Write the file if (Options.Sections.Count > 0) { Options.Write(SolutionOptionsFileName.FullName); } } } return(bSuccess); }
private bool WriteCMakeLists() { string BuildCommand; const string CMakeSectionEnd = " )\n\n"; StringBuilder CMakefileContent = new StringBuilder(); // Create Engine/Project specific lists StringBuilder CMakeEngineSourceFilesList = new StringBuilder("set(ENGINE_SOURCE_FILES \n"); StringBuilder CMakeProjectSourceFilesList = new StringBuilder("set(PROJECT_SOURCE_FILES \n"); StringBuilder CMakeEngineHeaderFilesList = new StringBuilder("set(ENGINE_HEADER_FILES \n"); StringBuilder CMakeProjectHeaderFilesList = new StringBuilder("set(PROJECT_HEADER_FILES \n"); StringBuilder CMakeEngineCSFilesList = new StringBuilder("set(ENGINE_CSHARP_FILES \n"); StringBuilder CMakeProjectCSFilesList = new StringBuilder("set(PROJECT_CSHARP_FILES \n"); StringBuilder CMakeEngineConfigFilesList = new StringBuilder("set(ENGINE_CONFIG_FILES \n"); StringBuilder CMakeProjectConfigFilesList = new StringBuilder("set(PROJECT_CONFIG_FILES \n"); StringBuilder CMakeEngineShaderFilesList = new StringBuilder("set(ENGINE_SHADER_FILES \n"); StringBuilder CMakeProjectShaderFilesList = new StringBuilder("set(PROJECT_SHADER_FILES \n"); StringBuilder IncludeDirectoriesList = new StringBuilder("include_directories( \n"); StringBuilder PreprocessorDefinitionsList = new StringBuilder("add_definitions( \n"); string UE4RootPath = Utils.CleanDirectorySeparators(UnrealBuildTool.RootDirectory.FullName, '/'); string CMakeGameRootPath = ""; string GameProjectPath = ""; string CMakeGameProjectFile = ""; string HostArchitecture; string SetCompiler = ""; switch (BuildHostPlatform.Current.Platform) { case UnrealTargetPlatform.Win64: { HostArchitecture = "Win64"; BuildCommand = "call \"" + UE4RootPath + "/Engine/Build/BatchFiles/Build.bat\""; break; } case UnrealTargetPlatform.Mac: { HostArchitecture = "Mac"; BuildCommand = "cd \"" + UE4RootPath + "\" && bash \"" + UE4RootPath + "/Engine/Build/BatchFiles/" + HostArchitecture + "/Build.sh\""; bIncludeIOSTargets = true; bIncludeTVOSTargets = true; break; } case UnrealTargetPlatform.Linux: { HostArchitecture = "Linux"; BuildCommand = "cd \"" + UE4RootPath + "\" && bash \"" + UE4RootPath + "/Engine/Build/BatchFiles/" + HostArchitecture + "/Build.sh\""; string CompilerPath = LinuxCommon.WhichClang(); if (CompilerPath == null) { CompilerPath = LinuxCommon.WhichGcc(); } SetCompiler = "set(CMAKE_CXX_COMPILER " + CompilerPath + ")\n\n"; break; } default: { throw new BuildException("ERROR: CMakefileGenerator does not support this platform"); } } if (IsProjectBuild) { GameProjectPath = OnlyGameProject.Directory.FullName; CMakeGameRootPath = Utils.CleanDirectorySeparators(OnlyGameProject.Directory.FullName, '/'); CMakeGameProjectFile = Utils.CleanDirectorySeparators(OnlyGameProject.FullName, '/'); } // Additional CMake file definitions string EngineHeadersFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeEngineHeadersFileName).ToNormalizedPath(); string ProjectHeadersFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectHeadersFileName).ToNormalizedPath(); string EngineSourcesFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeEngineSourcesFileName).ToNormalizedPath(); string ProjectSourcesFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectSourcesFileName).ToNormalizedPath(); string ProjectFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectSourcesFileName).ToNormalizedPath(); string IncludeFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeIncludesFileName).ToNormalizedPath(); string EngineConfigsFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeEngineConfigsFileName).ToNormalizedPath(); string ProjectConfigsFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectConfigsFileName).ToNormalizedPath(); string EngineCSFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeEngineCSFileName).ToNormalizedPath(); string ProjectCSFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectCSFileName).ToNormalizedPath(); string EngineShadersFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeEngineShadersFileName).ToNormalizedPath(); string ProjectShadersFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeProjectShadersFileName).ToNormalizedPath(); string DefinitionsFilePath = FileReference.Combine(IntermediateProjectFilesPath, CMakeDefinitionsFileName).ToNormalizedPath(); CMakefileContent.Append( "# Makefile generated by CMakefileGenerator.cs (v1.2)\n" + "# *DO NOT EDIT*\n\n" + "cmake_minimum_required (VERSION 2.6)\n" + "project (UE4)\n\n" + "# CMake Flags\n" + "set(CMAKE_CXX_STANDARD 14)\n" + // Need to keep this updated "set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_OBJECTS 1 CACHE BOOL \"\" FORCE)\n" + "set(CMAKE_CXX_USE_RESPONSE_FILE_FOR_INCLUDES 1 CACHE BOOL \"\" FORCE)\n\n" + SetCompiler + "# Standard Includes\n" + "include(\"" + IncludeFilePath + "\")\n" + "include(\"" + DefinitionsFilePath + "\")\n" + "include(\"" + EngineHeadersFilePath + "\")\n" + "include(\"" + ProjectHeadersFilePath + "\")\n" + "include(\"" + EngineSourcesFilePath + "\")\n" + "include(\"" + ProjectSourcesFilePath + "\")\n" + "include(\"" + EngineCSFilePath + "\")\n" + "include(\"" + ProjectCSFilePath + "\")\n\n" ); List <string> IncludeDirectories = new List <string>(); List <string> PreprocessorDefinitions = new List <string>(); foreach (ProjectFile CurProject in GeneratedProjectFiles) { foreach (string IncludeSearchPath in CurProject.IntelliSenseIncludeSearchPaths) { string IncludeDirectory = GetIncludeDirectory(IncludeSearchPath, Path.GetDirectoryName(CurProject.ProjectFilePath.FullName)); if (IncludeDirectory != null && !IncludeDirectories.Contains(IncludeDirectory)) { if (IncludeDirectory.Contains(UnrealBuildTool.RootDirectory.FullName)) { IncludeDirectories.Add(IncludeDirectory.Replace(UnrealBuildTool.RootDirectory.FullName, UE4RootPath)); } else { // If the path isn't rooted, then it is relative to the game root if (!Path.IsPathRooted(IncludeDirectory)) { IncludeDirectories.Add(CMakeGameRootPath + "/" + IncludeDirectory); } else { // This is a rooted path like /usr/local/sometool/include IncludeDirectories.Add(IncludeDirectory); } } } } foreach (string PreProcessorDefinition in CurProject.IntelliSensePreprocessorDefinitions) { string Definition = PreProcessorDefinition.Replace("TEXT(\"", "").Replace("\")", "").Replace("()=", "="); string AlternateDefinition = Definition.Contains("=0") ? Definition.Replace("=0", "=1") : Definition.Replace("=1", "=0"); if (Definition.Equals("WITH_EDITORONLY_DATA=0")) { Definition = AlternateDefinition; } if (!PreprocessorDefinitions.Contains(Definition) && !PreprocessorDefinitions.Contains(AlternateDefinition) && !Definition.StartsWith("UE_ENGINE_DIRECTORY") && !Definition.StartsWith("ORIGINAL_FILE_NAME")) { PreprocessorDefinitions.Add(Definition); } } } // Create SourceFiles, HeaderFiles, and ConfigFiles sections. List <FileReference> AllModuleFiles = DiscoverModules(FindGameProjects()); foreach (FileReference CurModuleFile in AllModuleFiles) { List <FileReference> FoundFiles = SourceFileSearch.FindModuleSourceFiles(CurModuleFile); foreach (FileReference CurSourceFile in FoundFiles) { string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory); // Exclude files/folders on a per-platform basis. if (!IsPathExcludedOnPlatform(SourceFileRelativeToRoot, BuildHostPlatform.Current.Platform)) { if (SourceFileRelativeToRoot.EndsWith(".cpp")) { AppendCleanedPathToList(CMakeEngineSourceFilesList, CMakeProjectSourceFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } else if (SourceFileRelativeToRoot.EndsWith(".h")) { AppendCleanedPathToList(CMakeEngineHeaderFilesList, CMakeProjectHeaderFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } else if (SourceFileRelativeToRoot.EndsWith(".cs")) { AppendCleanedPathToList(CMakeEngineCSFilesList, CMakeProjectCSFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } else if (SourceFileRelativeToRoot.EndsWith(".usf") || SourceFileRelativeToRoot.EndsWith(".ush")) { AppendCleanedPathToList(CMakeEngineShaderFilesList, CMakeProjectShaderFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } else if (SourceFileRelativeToRoot.EndsWith(".ini")) { AppendCleanedPathToList(CMakeEngineConfigFilesList, CMakeProjectConfigFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } } } } foreach (string IncludeDirectory in IncludeDirectories) { IncludeDirectoriesList.Append("\t\"" + Utils.CleanDirectorySeparators(IncludeDirectory, '/') + "\"\n"); } foreach (string PreprocessorDefinition in PreprocessorDefinitions) { int EqPos = PreprocessorDefinition.IndexOf("="); if (EqPos >= 0) { string Key = PreprocessorDefinition.Substring(0, EqPos); string Value = PreprocessorDefinition.Substring(EqPos).Replace("\"", "\\\""); PreprocessorDefinitionsList.Append("\t\"-D" + Key + Value + "\"\n"); } else { PreprocessorDefinitionsList.Append("\t\"-D" + PreprocessorDefinition + "\"\n"); } } // Add Engine/Shaders files (game are added via modules) List <FileReference> EngineShaderFiles = SourceFileSearch.FindFiles(DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Shaders")); foreach (FileReference CurSourceFile in EngineShaderFiles) { string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory); if (SourceFileRelativeToRoot.EndsWith(".usf") || SourceFileRelativeToRoot.EndsWith(".ush")) { AppendCleanedPathToList(CMakeEngineShaderFilesList, CMakeProjectShaderFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } } // Add Engine/Config ini files (game are added via modules) List <FileReference> EngineConfigFiles = SourceFileSearch.FindFiles(DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Config")); foreach (FileReference CurSourceFile in EngineConfigFiles) { string SourceFileRelativeToRoot = CurSourceFile.MakeRelativeTo(UnrealBuildTool.EngineDirectory); if (SourceFileRelativeToRoot.EndsWith(".ini")) { AppendCleanedPathToList(CMakeEngineConfigFilesList, CMakeProjectConfigFilesList, SourceFileRelativeToRoot, CurSourceFile.FullName, GameProjectPath, UE4RootPath, CMakeGameRootPath); } } // Add section end to section strings; CMakeEngineSourceFilesList.Append(CMakeSectionEnd); CMakeEngineHeaderFilesList.Append(CMakeSectionEnd); CMakeEngineCSFilesList.Append(CMakeSectionEnd); CMakeEngineConfigFilesList.Append(CMakeSectionEnd); CMakeEngineShaderFilesList.Append(CMakeSectionEnd); CMakeProjectSourceFilesList.Append(CMakeSectionEnd); CMakeProjectHeaderFilesList.Append(CMakeSectionEnd); CMakeProjectCSFilesList.Append(CMakeSectionEnd); CMakeProjectConfigFilesList.Append(CMakeSectionEnd); CMakeProjectShaderFilesList.Append(CMakeSectionEnd); IncludeDirectoriesList.Append(CMakeSectionEnd); PreprocessorDefinitionsList.Append(CMakeSectionEnd); if (bIncludeShaderSource) { CMakefileContent.Append("# Optional Shader Include\n"); if (!IsProjectBuild || bIncludeEngineSource) { CMakefileContent.Append("include(\"" + EngineShadersFilePath + "\")\n"); CMakefileContent.Append("set_source_files_properties(${ENGINE_SHADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)\n"); } CMakefileContent.Append("include(\"" + ProjectShadersFilePath + "\")\n"); CMakefileContent.Append("set_source_files_properties(${PROJECT_SHADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)\n"); CMakefileContent.Append("source_group(\"Shader Files\" REGULAR_EXPRESSION .*.usf)\n\n"); } if (bIncludeConfigFiles) { CMakefileContent.Append("# Optional Config Include\n"); if (!IsProjectBuild || bIncludeEngineSource) { CMakefileContent.Append("include(\"" + EngineConfigsFilePath + "\")\n"); CMakefileContent.Append("set_source_files_properties(${ENGINE_CONFIG_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)\n"); } CMakefileContent.Append("include(\"" + ProjectConfigsFilePath + "\")\n"); CMakefileContent.Append("set_source_files_properties(${PROJECT_CONFIG_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)\n"); CMakefileContent.Append("source_group(\"Config Files\" REGULAR_EXPRESSION .*.ini)\n\n"); } string CMakeProjectCmdArg = ""; string UBTArguements = ""; if (bGeneratingGameProjectFiles) { UBTArguements += " -game"; } // Should the builder output progress ticks if (ProgressWriter.bWriteMarkup) { UBTArguements += " -progress"; } foreach (ProjectFile Project in GeneratedProjectFiles) { foreach (ProjectTarget TargetFile in Project.ProjectTargets) { if (TargetFile.TargetFilePath == null) { continue; } string TargetName = TargetFile.TargetFilePath.GetFileNameWithoutAnyExtensions(); // Remove both ".cs" and ". foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code) && !IsTargetExcluded(TargetName, BuildHostPlatform.Current.Platform, CurConfiguration)) { if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor")) { CMakeProjectCmdArg = "\"-project=" + CMakeGameProjectFile + "\""; } string ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); CMakefileContent.Append(String.Format("add_custom_target({0}-{3}-{1} {5} {0} {3} {1} {2}{4} -buildscw VERBATIM)\n", TargetName, ConfName, CMakeProjectCmdArg, HostArchitecture, UBTArguements, BuildCommand)); // Add iOS and TVOS targets if valid if (bIncludeIOSTargets && !IsTargetExcluded(TargetName, UnrealTargetPlatform.IOS, CurConfiguration)) { CMakefileContent.Append(String.Format("add_custom_target({0}-{3}-{1} {5} {0} {3} {1} {2}{4} VERBATIM)\n", TargetName, ConfName, CMakeProjectCmdArg, UnrealTargetPlatform.IOS, UBTArguements, BuildCommand)); } if (bIncludeTVOSTargets && !IsTargetExcluded(TargetName, UnrealTargetPlatform.TVOS, CurConfiguration)) { CMakefileContent.Append(String.Format("add_custom_target({0}-{3}-{1} {5} {0} {3} {1} {2}{4} VERBATIM)\n", TargetName, ConfName, CMakeProjectCmdArg, UnrealTargetPlatform.TVOS, UBTArguements, BuildCommand)); } } } } if (!IsTargetExcluded(TargetName, BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development)) { if (TargetName == GameProjectName || TargetName == (GameProjectName + "Editor")) { CMakeProjectCmdArg = "\"-project=" + CMakeGameProjectFile + "\""; } CMakefileContent.Append(String.Format("add_custom_target({0} {4} {0} {2} Development {1}{3} -buildscw VERBATIM)\n\n", TargetName, CMakeProjectCmdArg, HostArchitecture, UBTArguements, BuildCommand)); // Add iOS and TVOS targets if valid if (bIncludeIOSTargets && !IsTargetExcluded(TargetName, UnrealTargetPlatform.IOS, UnrealTargetConfiguration.Development)) { CMakefileContent.Append(String.Format("add_custom_target({0}-{3} {5} {0} {3} {1} {2}{4} VERBATIM)\n", TargetName, UnrealTargetConfiguration.Development, CMakeProjectCmdArg, UnrealTargetPlatform.IOS, UBTArguements, BuildCommand)); } if (bIncludeTVOSTargets && !IsTargetExcluded(TargetName, UnrealTargetPlatform.TVOS, UnrealTargetConfiguration.Development)) { CMakefileContent.Append(String.Format("add_custom_target({0}-{3} {5} {0} {3} {1} {2}{4} VERBATIM)\n", TargetName, UnrealTargetConfiguration.Development, CMakeProjectCmdArg, UnrealTargetPlatform.TVOS, UBTArguements, BuildCommand)); } } } } // Create Build Template if (IsProjectBuild && !bIncludeEngineSource) { CMakefileContent.AppendLine("add_executable(FakeTarget ${PROJECT_HEADER_FILES} ${PROJECT_SOURCE_FILES} ${PROJECT_CSHARP_FILES} ${PROJECT_SHADER_FILES} ${PROJECT_CONFIG_FILES})"); } else { CMakefileContent.AppendLine("add_executable(FakeTarget ${ENGINE_HEADER_FILES} ${ENGINE_SOURCE_FILES} ${ENGINE_CSHARP_FILES} ${ENGINE_SHADER_FILES} ${ENGINE_CONFIG_FILES} ${PROJECT_HEADER_FILES} ${PROJECT_SOURCE_FILES} ${PROJECT_CSHARP_FILES} ${PROJECT_SHADER_FILES} ${PROJECT_CONFIG_FILES})"); } string FullFileName = Path.Combine(MasterProjectPath.FullName, ProjectFileName); // Write out CMake files bool bWriteMakeList = WriteFileIfChanged(FullFileName, CMakefileContent.ToString()); bool bWriteEngineHeaders = WriteFileIfChanged(EngineHeadersFilePath, CMakeEngineHeaderFilesList.ToString()); bool bWriteProjectHeaders = WriteFileIfChanged(ProjectHeadersFilePath, CMakeProjectHeaderFilesList.ToString()); bool bWriteEngineSources = WriteFileIfChanged(EngineSourcesFilePath, CMakeEngineSourceFilesList.ToString()); bool bWriteProjectSources = WriteFileIfChanged(ProjectSourcesFilePath, CMakeProjectSourceFilesList.ToString()); bool bWriteIncludes = WriteFileIfChanged(IncludeFilePath, IncludeDirectoriesList.ToString()); bool bWriteDefinitions = WriteFileIfChanged(DefinitionsFilePath, PreprocessorDefinitionsList.ToString()); bool bWriteEngineConfigs = WriteFileIfChanged(EngineConfigsFilePath, CMakeEngineConfigFilesList.ToString()); bool bWriteProjectConfigs = WriteFileIfChanged(ProjectConfigsFilePath, CMakeProjectConfigFilesList.ToString()); bool bWriteEngineShaders = WriteFileIfChanged(EngineShadersFilePath, CMakeEngineShaderFilesList.ToString()); bool bWriteProjectShaders = WriteFileIfChanged(ProjectShadersFilePath, CMakeProjectShaderFilesList.ToString()); bool bWriteEngineCS = WriteFileIfChanged(EngineCSFilePath, CMakeEngineCSFilesList.ToString()); bool bWriteProjectCS = WriteFileIfChanged(ProjectCSFilePath, CMakeProjectCSFilesList.ToString()); // Return success flag if all files were written out successfully return(bWriteMakeList && bWriteEngineHeaders && bWriteProjectHeaders && bWriteEngineSources && bWriteProjectSources && bWriteEngineConfigs && bWriteProjectConfigs && bWriteEngineCS && bWriteProjectCS && bWriteEngineShaders && bWriteProjectShaders && bWriteIncludes && bWriteDefinitions); }
/// <summary> /// Write the Command section for a .kdev4/$ProjectName.kdev4 file. /// </summary> /// <param name="FileContent">File content.</param> private void WriteCommandSection(ref StringBuilder FileContent) { int BuildConfigIndex = 1; string UnrealRootPath = UnrealBuildTool.RootDirectory.FullName; FileContent.Append("[CustomBuildSystem]\n"); FileContent.Append("CurrentConfiguration=BuildConfig0\n\n"); // // The Basics to get up and running with the editor, utilizing the Makefile. FileContent.Append(String.Format("[CustomBuildSystem][BuildConfig0]\nBuildDir=file://{0}\n", UnrealRootPath)); FileContent.Append("Title=BuildMeFirst\n\n"); FileContent.Append("[CustomBuildSystem][BuildConfig0][ToolBuild]\n"); FileContent.Append("Arguments=-f Makefile UE4Editor UE4Game ShaderCompileWorker UnrealLightmass UnrealPak\n"); FileContent.Append("Enabled=true\n"); FileContent.Append("Environment=\n"); FileContent.Append("Executable=make\n"); FileContent.Append("Type=0\n\n"); FileContent.Append("[CustomBuildSystem][BuildConfig0][ToolClean]\n"); FileContent.Append("Arguments=-f Makefile UE4Editor UE4Game ShaderCompileWorker UnrealLightmass UnrealPak -clean\n"); FileContent.Append("Enabled=true\n"); FileContent.Append("Environment=\n"); FileContent.Append("Executable=make\n"); FileContent.Append("Type=3\n\n"); FileContent.Append("[CustomBuildSystem][BuildConfig0][ToolConfigure]\n"); FileContent.Append("Arguments=./GenerateProjectFiles.sh\n"); FileContent.Append("Enabled=true\n"); FileContent.Append("Environment=\n"); FileContent.Append("Executable=bash\n"); FileContent.Append("Type=1\n\n"); foreach (ProjectFile Project in GeneratedProjectFiles) { foreach (ProjectTarget TargetFile in Project.ProjectTargets) { if (TargetFile.TargetFilePath == null) { continue; } string TargetName = TargetFile.TargetFilePath.GetFileNameWithoutAnyExtensions(); // Remove both ".cs" and ". foreach (UnrealTargetConfiguration CurConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (CurConfiguration != UnrealTargetConfiguration.Unknown && CurConfiguration != UnrealTargetConfiguration.Development) { if (InstalledPlatformInfo.IsValidConfiguration(CurConfiguration, EProjectType.Code)) { string ConfName = Enum.GetName(typeof(UnrealTargetConfiguration), CurConfiguration); FileContent.Append(String.Format("[CustomBuildSystem][BuildConfig{0}]\nBuildDir=file://{1}\n", BuildConfigIndex, UnrealRootPath)); if (TargetName == GameProjectName) { FileContent.Append(String.Format("Title={0}-Linux-{1}\n\n", TargetName, ConfName)); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 3); } else if (TargetName == (GameProjectName + "Editor")) { FileContent.Append(String.Format("Title={0}-Linux-{1}\n\n", TargetName, ConfName)); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 3); } else { FileContent.Append(String.Format("Title={0}-Linux-{1}\n\n", TargetName, ConfName)); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, ConfName, BuildConfigIndex, 3); } BuildConfigIndex++; } } } FileContent.Append(String.Format("[CustomBuildSystem][BuildConfig{0}]\nBuildDir=file://{1}\n", BuildConfigIndex, UnrealRootPath)); if (TargetName == GameProjectName) { FileContent.Append(String.Format("Title={0}\n\n", TargetName)); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 3); } else if (TargetName == (GameProjectName + "Editor")) { FileContent.Append(String.Format("Title={0}\n\n", TargetName)); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 3); } else { FileContent.Append(String.Format("Title={0}\n\n", TargetName)); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 0); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 1); WriteCommandSubSection(ref FileContent, TargetName, "Development", BuildConfigIndex, 3); } BuildConfigIndex++; } } }