Пример #1
0
 /// <summary>
 /// Attempt to register a build platform, checking whether it is a valid platform in installed builds
 /// </summary>
 public void TryRegisterBuildPlatforms(SDKOutputLevel OutputLevel, bool bValidatingPlatforms)
 {
     // We need all platforms to be registered when we run -validateplatform command to check SDK status of each
     if (bValidatingPlatforms || InstalledPlatformInfo.IsValidPlatform(TargetPlatform))
     {
         RegisterBuildPlatforms(OutputLevel);
     }
 }
Пример #2
0
        /// <summary>
        /// Finds all the UEBuildPlatformFactory types in this assembly and uses them to register all the available platforms
        /// </summary>
        /// <param name="bIncludeNonInstalledPlatforms">Whether to register platforms that are not installed</param>
        /// <param name="bHostPlatformOnly">Only register the host platform</param>
        public static void RegisterPlatforms(bool bIncludeNonInstalledPlatforms, bool bHostPlatformOnly)
        {
            // Initialize the installed platform info
            using (Timeline.ScopeEvent("Initializing InstalledPlatformInfo"))
            {
                InstalledPlatformInfo.Initialize();
            }

            // Find and register all tool chains and build platforms that are present
            Type[] AllTypes;
            using (Timeline.ScopeEvent("Querying types"))
            {
                AllTypes = Assembly.GetExecutingAssembly().GetTypes();
            }

            // register all build platforms first, since they implement SDK-switching logic that can set environment variables
            foreach (Type CheckType in AllTypes)
            {
                if (CheckType.IsClass && !CheckType.IsAbstract)
                {
                    if (CheckType.IsSubclassOf(typeof(UEBuildPlatformFactory)))
                    {
                        Log.TraceVerbose("    Registering build platform: {0}", CheckType.ToString());
                        using (Timeline.ScopeEvent(CheckType.Name))
                        {
                            UEBuildPlatformFactory TempInst = (UEBuildPlatformFactory)Activator.CreateInstance(CheckType);

                            if (bHostPlatformOnly && TempInst.TargetPlatform != BuildHostPlatform.Current.Platform)
                            {
                                continue;
                            }


                            // We need all platforms to be registered when we run -validateplatform command to check SDK status of each
                            if (bIncludeNonInstalledPlatforms || InstalledPlatformInfo.IsValidPlatform(TempInst.TargetPlatform))
                            {
                                TempInst.RegisterBuildPlatforms();
                            }
                        }
                    }
                }
            }
        }
Пример #3
0
        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);
        }
Пример #5
0
        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);
        }
Пример #7
0
        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>
        /// Parse a list of target descriptors from the command line
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <param name="bUsePrecompiled">Whether to use a precompiled engine distribution</param>
        /// <param name="bSkipRulesCompile">Whether to skip compiling rules assemblies</param>
        /// <param name="TargetDescriptors">List of target descriptors</param>
        public static void ParseSingleCommandLine(CommandLineArguments Arguments, bool bUsePrecompiled, bool bSkipRulesCompile, List <TargetDescriptor> TargetDescriptors)
        {
            List <UnrealTargetPlatform>      Platforms      = new List <UnrealTargetPlatform>();
            List <UnrealTargetConfiguration> Configurations = new List <UnrealTargetConfiguration>();
            List <string> TargetNames = new List <string>();
            FileReference ProjectFile = Arguments.GetFileReferenceOrDefault("-Project=", null);

            // Settings for creating/using static libraries for the engine
            for (int ArgumentIndex = 0; ArgumentIndex < Arguments.Count; ArgumentIndex++)
            {
                string Argument = Arguments[ArgumentIndex];
                if (Argument.Length > 0 && Argument[0] != '-')
                {
                    // Mark this argument as used. We'll interpret it as one thing or another.
                    Arguments.MarkAsUsed(ArgumentIndex);

                    // Check if it's a project file argument
                    if (Argument.EndsWith(".uproject", StringComparison.OrdinalIgnoreCase))
                    {
                        FileReference NewProjectFile = new FileReference(Argument);
                        if (ProjectFile != null && ProjectFile != NewProjectFile)
                        {
                            throw new BuildException("Multiple project files specified on command line (first {0}, then {1})", ProjectFile, NewProjectFile);
                        }
                        ProjectFile = new FileReference(Argument);
                        continue;
                    }

                    // Split it into separate arguments
                    string[] InlineArguments = Argument.Split('+');

                    // Try to parse them as platforms
                    UnrealTargetPlatform ParsedPlatform;
                    if (UnrealTargetPlatform.TryParse(InlineArguments[0], out ParsedPlatform))
                    {
                        Platforms.Add(ParsedPlatform);
                        for (int InlineArgumentIdx = 1; InlineArgumentIdx < InlineArguments.Length; InlineArgumentIdx++)
                        {
                            Platforms.Add(UnrealTargetPlatform.Parse(InlineArguments[InlineArgumentIdx]));
                        }
                        continue;
                    }

                    // Try to parse them as configurations
                    UnrealTargetConfiguration ParsedConfiguration;
                    if (Enum.TryParse(InlineArguments[0], true, out ParsedConfiguration))
                    {
                        Configurations.Add(ParsedConfiguration);
                        for (int InlineArgumentIdx = 1; InlineArgumentIdx < InlineArguments.Length; InlineArgumentIdx++)
                        {
                            string InlineArgument = InlineArguments[InlineArgumentIdx];
                            if (!Enum.TryParse(InlineArgument, true, out ParsedConfiguration))
                            {
                                throw new BuildException("Invalid configuration '{0}'", InlineArgument);
                            }
                            Configurations.Add(ParsedConfiguration);
                        }
                        continue;
                    }

                    // Otherwise assume they are target names
                    TargetNames.AddRange(InlineArguments);
                }
            }

            if (Platforms.Count == 0)
            {
                throw new BuildException("No platforms specified for target");
            }
            if (Configurations.Count == 0)
            {
                throw new BuildException("No configurations specified for target");
            }

            // Make sure the project file exists, and make sure we're using the correct case.
            if (ProjectFile != null)
            {
                FileInfo ProjectFileInfo = FileUtils.FindCorrectCase(ProjectFile.ToFileInfo());
                if (!ProjectFileInfo.Exists)
                {
                    throw new BuildException("Unable to find project '{0}'.", ProjectFile);
                }
                ProjectFile = new FileReference(ProjectFileInfo);
            }

            // Expand all the platforms, architectures and configurations
            foreach (UnrealTargetPlatform Platform in Platforms)
            {
                // Make sure the platform is valid
                if (!InstalledPlatformInfo.IsValid(null, Platform, null, EProjectType.Code, InstalledPlatformState.Downloaded))
                {
                    if (!InstalledPlatformInfo.IsValid(null, Platform, null, EProjectType.Code, InstalledPlatformState.Supported))
                    {
                        throw new BuildException("The {0} platform is not supported from this engine distribution.", Platform);
                    }
                    else
                    {
                        throw new BuildException("Missing files required to build {0} targets. Enable {0} as an optional download component in the Epic Games Launcher.", Platform);
                    }
                }

                // Parse the architecture parameter, or get the default for the platform
                List <string> Architectures = new List <string>(Arguments.GetValues("-Architecture=", '+'));
                if (Architectures.Count == 0)
                {
                    Architectures.Add(UEBuildPlatform.GetBuildPlatform(Platform).GetDefaultArchitecture(ProjectFile));
                }

                foreach (string Architecture in Architectures)
                {
                    foreach (UnrealTargetConfiguration Configuration in Configurations)
                    {
                        // Create all the target descriptors for targets specified by type
                        foreach (string TargetTypeString in Arguments.GetValues("-TargetType="))
                        {
                            TargetType TargetType;
                            if (!Enum.TryParse(TargetTypeString, out TargetType))
                            {
                                throw new BuildException("Invalid target type '{0}'", TargetTypeString);
                            }

                            if (ProjectFile == null)
                            {
                                throw new BuildException("-TargetType=... requires a project file to be specified");
                            }
                            else
                            {
                                TargetNames.Add(RulesCompiler.CreateProjectRulesAssembly(ProjectFile, bUsePrecompiled, bSkipRulesCompile).GetTargetNameByType(TargetType, Platform, Configuration, Architecture, ProjectFile));
                            }
                        }

                        // Make sure we could parse something
                        if (TargetNames.Count == 0)
                        {
                            throw new BuildException("No target name was specified on the command-line.");
                        }

                        // Create all the target descriptors
                        foreach (string TargetName in TargetNames)
                        {
                            // If a project file was not specified see if we can find one
                            if (ProjectFile == null && NativeProjects.TryGetProjectForTarget(TargetName, out ProjectFile))
                            {
                                Log.TraceVerbose("Found project file for {0} - {1}", TargetName, ProjectFile);
                            }

                            // Create the target descriptor
                            TargetDescriptors.Add(new TargetDescriptor(ProjectFile, TargetName, Platform, Configuration, Architecture, Arguments));
                        }
                    }
                }
            }
        }
        /// <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++;
                }
            }
        }