Exemple #1
0
        private void GatherProjects(PlatformProjectGeneratorCollection PlatformProjectGenerators,
                                    List <FileReference> AllGameProjects)
        {
            ProjectFile        EngineProject = null;
            List <ProjectFile> GameProjects  = null;
            List <ProjectFile> ModProjects   = null;
            Dictionary <FileReference, ProjectFile> ProgramProjects = null;

            // Setup buildable projects for all targets
            AddProjectsForAllTargets(PlatformProjectGenerators, AllGameProjects, out EngineProject,
                                     out GameProjects, out ProgramProjects);

            AddProjectsForMods(GameProjects, out ModProjects);
            AddAllGameProjects(GameProjects, null, null);

            // If we're still missing an engine project because we don't have any targets for it, make one up.
            if (EngineProject == null)
            {
                FileReference ProjectFilePath = FileReference.Combine(IntermediateProjectFilesPath,
                                                                      EngineProjectFileNameBase + ProjectFileExtension);

                bool bAlreadyExisted;
                EngineProject = FindOrAddProject(ProjectFilePath, UnrealBuildTool.EngineDirectory, true, out bAlreadyExisted);

                EngineProject.IsForeignProject   = false;
                EngineProject.IsGeneratedProject = true;
                EngineProject.IsStubProject      = true;
            }
        }
        /// <summary>
        /// Writes the project files to disk
        /// </summary>
        /// <returns>True if successful</returns>
        protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            if (!base.WriteProjectFiles(PlatformProjectGenerators))
            {
                return(false);
            }

            // Write AutomationReferences file
            if (AutomationProjectFiles.Any())
            {
                XNamespace NS = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");

                DirectoryReference AutomationToolDir = DirectoryReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Programs", "AutomationTool");
                new XDocument(
                    new XElement(NS + "Project",
                                 new XAttribute("ToolsVersion", VCProjectFileGenerator.GetProjectFileToolVersionString(ProjectFileFormat)),
                                 new XAttribute("DefaultTargets", "Build"),
                                 new XElement(NS + "ItemGroup",
                                              from AutomationProject in AutomationProjectFiles
                                              select new XElement(NS + "ProjectReference",
                                                                  new XAttribute("Include", AutomationProject.ProjectFilePath.MakeRelativeTo(AutomationToolDir)),
                                                                  new XElement(NS + "Project", (AutomationProject as VCSharpProjectFile).ProjectGUID.ToString("B")),
                                                                  new XElement(NS + "Name", AutomationProject.ProjectFilePath.GetFileNameWithoutExtension()),
                                                                  new XElement(NS + "Private", "false")
                                                                  )
                                              )
                                 )
                    ).Save(FileReference.Combine(AutomationToolDir, "AutomationTool.csproj.References").FullName);
            }

            return(true);
        }
Exemple #3
0
        /// <summary>
        /// Write project file info in JSON file.
        /// For every combination of <c>UnrealTargetPlatform</c>, <c>UnrealTargetConfiguration</c> and <c>TargetType</c>
        /// will be generated separate JSON file.
        /// Project file will be stored:
        /// For UE4:  {UE4Root}/Engine/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// For game: {GameRoot}/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// </summary>
        /// <remarks>
        /// * <c>UnrealTargetPlatform.Win32</c> will be always ignored.
        /// * <c>TargetType.Editor</c> will be generated for current platform only and will ignore <c>UnrealTargetConfiguration.Test</c> and <c>UnrealTargetConfiguration.Shipping</c> configurations
        /// * <c>TargetType.Program</c>  will be generated for current platform only and <c>UnrealTargetConfiguration.Development</c> configuration only
        /// </remarks>
        /// <param name="InPlatforms"></param>
        /// <param name="InConfigurations"></param>
        /// <param name="PlatformProjectGenerators"></param>
        /// <returns></returns>
        public override bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms,
                                              List <UnrealTargetConfiguration> InConfigurations,
                                              PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            string             ProjectName       = ProjectFilePath.GetFileNameWithoutAnyExtensions();
            DirectoryReference projectRootFolder = DirectoryReference.Combine(RootPath, ".Rider");
            List <Tuple <FileReference, UEBuildTarget> > fileToTarget = new List <Tuple <FileReference, UEBuildTarget> >();

            foreach (UnrealTargetPlatform Platform in InPlatforms.Where(it => it != UnrealTargetPlatform.Win32))
            {
                foreach (UnrealTargetConfiguration Configuration in InConfigurations)
                {
                    foreach (ProjectTarget ProjectTarget in ProjectTargets)
                    {
                        if (TargetTypes.Any() && !TargetTypes.Contains(ProjectTarget.TargetRules.Type))
                        {
                            continue;
                        }

                        // Skip Programs for all configs except for current platform + Development configuration
                        if (ProjectTarget.TargetRules.Type == TargetType.Program && (BuildHostPlatform.Current.Platform != Platform || Configuration != UnrealTargetConfiguration.Development))
                        {
                            continue;
                        }

                        // Skip Editor for all platforms except for current platform
                        if (ProjectTarget.TargetRules.Type == TargetType.Editor && (BuildHostPlatform.Current.Platform != Platform || (Configuration == UnrealTargetConfiguration.Test || Configuration == UnrealTargetConfiguration.Shipping)))
                        {
                            continue;
                        }

                        DirectoryReference ConfigurationFolder = DirectoryReference.Combine(projectRootFolder, Platform.ToString(), Configuration.ToString());

                        DirectoryReference TargetFolder =
                            DirectoryReference.Combine(ConfigurationFolder, ProjectTarget.TargetRules.Type.ToString());

                        string DefaultArchitecture = UEBuildPlatform
                                                     .GetBuildPlatform(BuildHostPlatform.Current.Platform)
                                                     .GetDefaultArchitecture(ProjectTarget.UnrealProjectFilePath);
                        TargetDescriptor TargetDesc = new TargetDescriptor(ProjectTarget.UnrealProjectFilePath, ProjectTarget.Name,
                                                                           BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development,
                                                                           DefaultArchitecture, Arguments);
                        UEBuildTarget BuildTarget = UEBuildTarget.Create(TargetDesc, false, false);
                        FileReference OutputFile  = FileReference.Combine(TargetFolder, $"{ProjectName}.json");
                        fileToTarget.Add(Tuple.Create(OutputFile, BuildTarget));
                    }
                }
            }
            foreach (Tuple <FileReference, UEBuildTarget> tuple in fileToTarget)
            {
                SerializeTarget(tuple.Item1, tuple.Item2);
            }

            return(true);
        }
        protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            using (ProgressWriter Progress = new ProgressWriter("Writing project files...", true))
            {
                List <ProjectFile> ProjectsToGenerate = new List <ProjectFile>(GeneratedProjectFiles);
                if (ProjectNames.Any())
                {
                    ProjectsToGenerate = ProjectsToGenerate.Where(it =>
                                                                  ProjectNames.Contains(it.ProjectFilePath.GetFileNameWithoutAnyExtensions())).ToList();
                }

                int TotalProjectFileCount = ProjectsToGenerate.Count;

                HashSet <UnrealTargetPlatform> PlatformsToGenerate = new HashSet <UnrealTargetPlatform>(SupportedPlatforms);
                if (Platforms.Any())
                {
                    PlatformsToGenerate.IntersectWith(Platforms);
                }

                List <UnrealTargetPlatform> FilteredPlatforms = PlatformsToGenerate.Where(it =>
                {
                    if (UEBuildPlatform.IsPlatformAvailable(it))
                    {
                        return(true);
                    }
                    Log.TraceWarning(
                        "Platform {0} is not a valid platform to build. Check that the SDK is installed properly",
                        it);
                    Log.TraceWarning("Platform will be ignored in project file generation");
                    return(false);
                }).ToList();

                HashSet <UnrealTargetConfiguration> ConfigurationsToGenerate = new HashSet <UnrealTargetConfiguration>(SupportedConfigurations);
                if (TargetConfigurations.Any())
                {
                    ConfigurationsToGenerate.IntersectWith(TargetConfigurations);
                }

                for (int ProjectFileIndex = 0; ProjectFileIndex < ProjectsToGenerate.Count; ++ProjectFileIndex)
                {
                    ProjectFile CurProject = ProjectsToGenerate[ProjectFileIndex];
                    if (!CurProject.WriteProjectFile(FilteredPlatforms, ConfigurationsToGenerate.ToList(),
                                                     PlatformProjectGenerators))
                    {
                        return(false);
                    }

                    Progress.Write(ProjectFileIndex + 1, TotalProjectFileCount);
                }

                Progress.Write(TotalProjectFileCount, TotalProjectFileCount);
            }

            return(true);
        }
Exemple #5
0
        public override bool GenerateProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators,
                                                  String[] arguments)
        {
            ConfigureProjectFileGeneration();

            if (bGeneratingGameProjectFiles)
            {
                MasterProjectPath = OnlyGameProject.Directory;
                MasterProjectName = OnlyGameProject.GetFileNameWithoutExtension();

                if (!DirectoryReference.Exists(DirectoryReference.Combine(MasterProjectPath, "Source")))
                {
                    if (!DirectoryReference.Exists(DirectoryReference.Combine(MasterProjectPath, "Intermediate",
                                                                              "Source")))
                    {
                        if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                        {
                            MasterProjectPath = UnrealBuildTool.EngineDirectory;
                            GameProjectName   = "UE4Game";
                        }

                        if (!DirectoryReference.Exists(DirectoryReference.Combine(MasterProjectPath, "Source")))
                        {
                            throw new BuildException("Directory '{0}' is missing 'Source' folder.", MasterProjectPath);
                        }
                    }
                }

                IntermediateProjectFilesPath =
                    DirectoryReference.Combine(MasterProjectPath, "Intermediate", "ProjectFiles");
            }

            SetupSupportedPlatformsAndConfigurations();

            Log.TraceVerbose("Detected supported platforms: " + SupportedPlatforms);

            List <FileReference> AllGameProjects = FindGameProjects();

            GatherProjects(PlatformProjectGenerators, AllGameProjects);

            WriteProjectFiles(PlatformProjectGenerators);
            Log.TraceVerbose("Project generation complete ({0} generated, {1} imported)", GeneratedProjectFiles.Count,
                             OtherProjectFiles.Count);

            return(true);
        }
        protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            using (ProgressWriter Progress = new ProgressWriter("Writing project files...", true))
            {
                List <ProjectFile> projectsToGenerate = new List <ProjectFile>(GeneratedProjectFiles);
                if (ProjectNames.Any())
                {
                    projectsToGenerate = projectsToGenerate.Where(it =>
                                                                  ProjectNames.Contains(it.ProjectFilePath.GetFileNameWithoutAnyExtensions())).ToList();
                }

                int TotalProjectFileCount = projectsToGenerate.Count;

                HashSet <UnrealTargetPlatform> platformsToGenerate = new HashSet <UnrealTargetPlatform>(SupportedPlatforms);
                if (Platforms.Any())
                {
                    platformsToGenerate.IntersectWith(Platforms);
                }

                HashSet <UnrealTargetConfiguration> configurationsToGenerate = new HashSet <UnrealTargetConfiguration>(SupportedConfigurations);
                if (TargetConfigurations.Any())
                {
                    configurationsToGenerate.IntersectWith(TargetConfigurations);
                }

                for (int ProjectFileIndex = 0; ProjectFileIndex < projectsToGenerate.Count; ++ProjectFileIndex)
                {
                    ProjectFile CurProject = projectsToGenerate[ProjectFileIndex];
                    if (!CurProject.WriteProjectFile(platformsToGenerate.ToList(), configurationsToGenerate.ToList(),
                                                     PlatformProjectGenerators))
                    {
                        return(false);
                    }

                    Progress.Write(ProjectFileIndex + 1, TotalProjectFileCount);
                }

                Progress.Write(TotalProjectFileCount, TotalProjectFileCount);
            }

            return(true);
        }
Exemple #7
0
        /// <summary>
        /// Writes the project files to disk
        /// </summary>
        /// <returns>True if successful</returns>
        protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            // This can be reset by higher level code when it detects that we don't have
            // VS2015 installed (TODO - add custom format for Mac?)
            ProjectFileFormat = VCProjectFileFormat.VisualStudio2015;

            // we can't generate native projects so clear them here, we will just
            // write out OtherProjectFiles and AutomationProjectFiles
            GeneratedProjectFiles.Clear();

            if (!base.WriteProjectFiles(PlatformProjectGenerators))
            {
                return(false);
            }


            // Write AutomationReferences file
            if (AutomationProjectFiles.Any())
            {
                XNamespace NS = XNamespace.Get("http://schemas.microsoft.com/developer/msbuild/2003");

                DirectoryReference AutomationToolDir = DirectoryReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Programs", "AutomationTool");
                new XDocument(
                    new XElement(NS + "Project",
                                 new XAttribute("ToolsVersion", VCProjectFileGenerator.GetProjectFileToolVersionString(ProjectFileFormat)),
                                 new XAttribute("DefaultTargets", "Build"),
                                 new XElement(NS + "ItemGroup",
                                              from AutomationProject in AutomationProjectFiles
                                              select new XElement(NS + "ProjectReference",
                                                                  new XAttribute("Include", AutomationProject.ProjectFilePath.MakeRelativeTo(AutomationToolDir)),
                                                                  new XElement(NS + "Project", (AutomationProject as VCSharpProjectFile).ProjectGUID.ToString("B")),
                                                                  new XElement(NS + "Name", AutomationProject.ProjectFilePath.GetFileNameWithoutExtension()),
                                                                  new XElement(NS + "Private", "false")
                                                                  )
                                              )
                                 )
                    ).Save(FileReference.Combine(AutomationToolDir, "AutomationTool.csproj.References").FullName);
            }

            return(true);
        }
        protected override void WriteDebugSolutionFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators, DirectoryReference IntermediateProjectFilesPath)
        {
            //build and collect UnrealVS configuration
            StringBuilder UnrealVSContent = new StringBuilder();

            foreach (UnrealTargetPlatform SupportedPlatform in SupportedPlatforms)
            {
                PlatformProjectGenerator ProjGenerator = PlatformProjectGenerators.GetPlatformProjectGenerator(SupportedPlatform, true);
                if (ProjGenerator != null)
                {
                    ProjGenerator.GetUnrealVSConfigurationEntries(UnrealVSContent);
                }
            }
            if (UnrealVSContent.Length > 0)
            {
                UnrealVSContent.Insert(0, "<UnrealVS>" + ProjectFileGenerator.NewLine);
                UnrealVSContent.Append("</UnrealVS>" + ProjectFileGenerator.NewLine);

                string ConfigFilePath = FileReference.Combine(IntermediateProjectFilesPath, "UnrealVS.xml").FullName;
                bool   bSuccess       = ProjectFileGenerator.WriteFileIfChanged(ConfigFilePath, UnrealVSContent.ToString());
            }
        }
Exemple #9
0
 /// <summary>
 /// If found writes a debug project file to disk
 /// </summary>
 /// <param name="InPlatforms">The platforms to write the project files for</param>
 /// <param name="InConfigurations">The configurations to add to the project files</param>
 /// <param name="PlatformProjectGenerators">The registered platform project generators</param>
 /// <returns>List of project files written</returns>
 public virtual List <Tuple <ProjectFile, string> > WriteDebugProjectFiles(List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(null);
 }
        public override bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations, PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            bool bSuccess = false;

            string TargetName = ProjectFilePath.GetFileNameWithoutExtension();

            FileReference GameProjectPath = null;

            foreach (ProjectTarget Target in ProjectTargets)
            {
                if (Target.UnrealProjectFilePath != null)
                {
                    GameProjectPath = Target.UnrealProjectFilePath;
                    break;
                }
            }

            StringBuilder ProjectFileContent = new StringBuilder();

            ProjectFileContent.Append("# @Eddie Workset@" + ProjectFileGenerator.NewLine);
            ProjectFileContent.Append("AddWorkset \"" + this.ToString() + ".wkst\" \"" + ProjectFilePath.FullName + "\"" + ProjectFileGenerator.NewLine);

            ParseSourceFilesIntoGroups();
            EmitProject(ProjectFileContent, Folders);

            bSuccess = ProjectFileGenerator.WriteFileIfChanged(ProjectFilePath.FullName, ProjectFileContent.ToString(), new UTF8Encoding());

            return(bSuccess);
        }
        /// <summary>
        /// Execute the tool mode
        /// </summary>
        /// <param name="Arguments">Command line arguments</param>
        /// <returns>Exit code</returns>
        public override int Execute(CommandLineArguments Arguments)
        {
            // Apply any command line arguments to this class
            Arguments.ApplyTo(this);

            // Apply the XML config to this class
            XmlConfig.ApplyTo(this);

            // Parse rocket-specific arguments.
            FileReference ProjectFile;

            TryParseProjectFileArgument(Arguments, out ProjectFile);

            // If there aren't any formats set, read the default project file format from the config file
            if (ProjectFileFormats.Count == 0)
            {
                // Read from the XML config
                if (!String.IsNullOrEmpty(ProjectFileGeneratorSettings.Format))
                {
                    ProjectFileFormats.UnionWith(ProjectFileGeneratorSettings.ParseFormatList(ProjectFileGeneratorSettings.Format));
                }

                // Read from the editor config
                ProjectFileFormat PreferredSourceCodeAccessor;
                if (ProjectFileGenerator.GetPreferredSourceCodeAccessor(ProjectFile, out PreferredSourceCodeAccessor))
                {
                    ProjectFileFormats.Add(PreferredSourceCodeAccessor);
                }

                // If there's still nothing set, get the default project file format for this platform
                if (ProjectFileFormats.Count == 0)
                {
                    ProjectFileFormats.UnionWith(BuildHostPlatform.Current.GetDefaultProjectFileFormats());
                }
            }

            // Register all the platform project generators
            PlatformProjectGeneratorCollection PlatformProjectGenerators = new PlatformProjectGeneratorCollection();

            foreach (Type CheckType in Assembly.GetExecutingAssembly().GetTypes())
            {
                if (CheckType.IsClass && !CheckType.IsAbstract && CheckType.IsSubclassOf(typeof(PlatformProjectGenerator)))
                {
                    PlatformProjectGenerator Generator = (PlatformProjectGenerator)Activator.CreateInstance(CheckType, Arguments);
                    foreach (UnrealTargetPlatform Platform in Generator.GetPlatforms())
                    {
                        if (DisablePlatformProjectGenerators == null || !DisablePlatformProjectGenerators.Any(x => x.Equals(Platform.ToString(), StringComparison.OrdinalIgnoreCase)))
                        {
                            Log.TraceVerbose("Registering project generator {0} for {1}", CheckType, Platform);
                            PlatformProjectGenerators.RegisterPlatformProjectGenerator(Platform, Generator);
                        }
                    }
                }
            }

            // Create each project generator and run it
            List <ProjectFileGenerator> Generators = new List <ProjectFileGenerator>();

            foreach (ProjectFileFormat ProjectFileFormat in ProjectFileFormats.Distinct())
            {
                ProjectFileGenerator Generator;
                switch (ProjectFileFormat)
                {
                case ProjectFileFormat.Make:
                    Generator = new MakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CMake:
                    Generator = new CMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.QMake:
                    Generator = new QMakefileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.KDevelop:
                    Generator = new KDevelopGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CodeLite:
                    Generator = new CodeLiteGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.Default, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2012:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2012, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2013:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2013, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2015:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2015, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2017:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2017, Arguments);
                    break;

                case ProjectFileFormat.VisualStudio2019:
                    Generator = new VCProjectFileGenerator(ProjectFile, VCProjectFileFormat.VisualStudio2019, Arguments);
                    break;

                case ProjectFileFormat.XCode:
                    Generator = new XcodeProjectFileGenerator(ProjectFile, Arguments);
                    break;

                case ProjectFileFormat.Eddie:
                    Generator = new EddieProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioCode:
                    Generator = new VSCodeProjectFileGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.CLion:
                    Generator = new CLionGenerator(ProjectFile);
                    break;

                case ProjectFileFormat.VisualStudioMac:
                    Generator = new VCMacProjectFileGenerator(ProjectFile, Arguments);
                    break;

                default:
                    throw new BuildException("Unhandled project file type '{0}", ProjectFileFormat);
                }
                Generators.Add(Generator);
            }

            // Check there are no superfluous command line arguments
            // TODO (still pass raw arguments below)
            // Arguments.CheckAllArgumentsUsed();

            // Now generate project files
            ProjectFileGenerator.bGenerateProjectFiles = true;
            foreach (ProjectFileGenerator Generator in Generators)
            {
                if (!Generator.GenerateProjectFiles(PlatformProjectGenerators, Arguments.GetRawArray()))
                {
                    return((int)CompilationResult.OtherCompilationError);
                }
            }
            return((int)CompilationResult.Succeeded);
        }
Exemple #12
0
        private void AddProjectsForAllTargets(
            PlatformProjectGeneratorCollection PlatformProjectGenerators,
            List <FileReference> AllGames,
            out ProjectFile EngineProject,
            out List <ProjectFile> GameProjects,
            out Dictionary <FileReference, ProjectFile> ProgramProjects)
        {
            // As we're creating project files, we'll also keep track of whether we created an "engine" project and return that if we have one
            EngineProject   = null;
            GameProjects    = new List <ProjectFile>();
            ProgramProjects = new Dictionary <FileReference, ProjectFile>();

            // Find all of the target files.  This will filter out any modules or targets that don't
            // belong to platforms we're generating project files for.
            List <FileReference> AllTargetFiles = DiscoverTargets(AllGames);

            // Sort the targets by name. When we have multiple targets of a given type for a project, we'll use the order to determine which goes in the primary project file (so that client names with a suffix will go into their own project).
            AllTargetFiles = AllTargetFiles.OrderBy(x => x.FullName, StringComparer.OrdinalIgnoreCase).ToList();

            foreach (FileReference TargetFilePath in AllTargetFiles)
            {
                string TargetName = TargetFilePath.GetFileNameWithoutAnyExtensions();

                // Check to see if this is an Engine target.  That is, the target is located under the "Engine" folder
                bool IsEngineTarget           = false;
                bool IsEnterpriseTarget       = false;
                bool WantProjectFileForTarget = true;
                if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EngineDirectory))
                {
                    // This is an engine target
                    IsEngineTarget = true;

                    if (TargetFilePath.IsUnderDirectory(EngineSourceProgramsDirectory))
                    {
                        WantProjectFileForTarget = IncludeEnginePrograms;
                    }
                    else if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EngineSourceDirectory))
                    {
                        WantProjectFileForTarget = bIncludeEngineSource;
                    }
                }
                else if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EnterpriseSourceDirectory))
                {
                    // This is an enterprise target
                    IsEnterpriseTarget = true;

                    if (TargetFilePath.IsUnderDirectory(EnterpriseSourceProgramsDirectory))
                    {
                        WantProjectFileForTarget = bIncludeEnterpriseSource && IncludeEnginePrograms;
                    }
                    else
                    {
                        WantProjectFileForTarget = bIncludeEnterpriseSource;
                    }
                }

                if (WantProjectFileForTarget)
                {
                    RulesAssembly RulesAssembly;

                    FileReference CheckProjectFile =
                        AllGames.FirstOrDefault(x => TargetFilePath.IsUnderDirectory(x.Directory));
                    if (CheckProjectFile == null)
                    {
                        if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EnterpriseDirectory))
                        {
                            RulesAssembly = RulesCompiler.CreateEnterpriseRulesAssembly(false, false);
                        }
                        else
                        {
                            RulesAssembly = RulesCompiler.CreateEngineRulesAssembly(false, false);
                        }
                    }
                    else
                    {
                        RulesAssembly = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile, false, false);
                    }

                    // Create target rules for all of the platforms and configuration combinations that we want to enable support for.
                    // Just use the current platform as we only need to recover the target type and both should be supported for all targets...
                    TargetRules TargetRulesObject = RulesAssembly.CreateTargetRules(TargetName,
                                                                                    BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development, "", CheckProjectFile,
                                                                                    null);

                    bool IsProgramTarget = false;

                    DirectoryReference GameFolder = null;
                    string             ProjectFileNameBase;
                    if (TargetRulesObject.Type == TargetType.Program)
                    {
                        IsProgramTarget     = true;
                        ProjectFileNameBase = TargetName;
                    }
                    else if (IsEngineTarget)
                    {
                        ProjectFileNameBase = EngineProjectFileNameBase;
                    }
                    else if (IsEnterpriseTarget)
                    {
                        ProjectFileNameBase = EnterpriseProjectFileNameBase;
                    }
                    else
                    {
                        // Figure out which game project this target belongs to
                        FileReference ProjectInfo = FindGameContainingFile(AllGames, TargetFilePath);
                        if (ProjectInfo == null)
                        {
                            throw new BuildException("Found a non-engine target file (" + TargetFilePath +
                                                     ") that did not exist within any of the known game folders");
                        }

                        GameFolder          = ProjectInfo.Directory;
                        ProjectFileNameBase = ProjectInfo.GetFileNameWithoutExtension();
                    }

                    // Get the suffix to use for this project file. If we have multiple targets of the same type, we'll have to split them out into separate IDE project files.
                    string GeneratedProjectName = TargetRulesObject.GeneratedProjectName;
                    if (GeneratedProjectName == null)
                    {
                        ProjectFile ExistingProjectFile;
                        if (ProjectFileMap.TryGetValue(GetRiderProjectLocation(ProjectFileNameBase), out ExistingProjectFile) &&
                            ExistingProjectFile.ProjectTargets.Any(x => x.TargetRules.Type == TargetRulesObject.Type))
                        {
                            GeneratedProjectName = TargetRulesObject.Name;
                        }
                        else
                        {
                            GeneratedProjectName = ProjectFileNameBase;
                        }
                    }

                    FileReference ProjectFilePath = GetRiderProjectLocation(GeneratedProjectName);
                    if (TargetRulesObject.Type == TargetType.Game || TargetRulesObject.Type == TargetType.Client ||
                        TargetRulesObject.Type == TargetType.Server)
                    {
                        // Allow platforms to generate stub projects here...
                        PlatformProjectGenerators.GenerateGameProjectStubs(
                            InGenerator: this,
                            InTargetName: TargetName,
                            InTargetFilepath: TargetFilePath.FullName,
                            InTargetRules: TargetRulesObject,
                            InPlatforms: SupportedPlatforms,
                            InConfigurations: SupportedConfigurations);
                    }

                    DirectoryReference BaseFolder;
                    if (IsProgramTarget)
                    {
                        BaseFolder = TargetFilePath.Directory;
                    }
                    else if (IsEngineTarget)
                    {
                        BaseFolder = UnrealBuildTool.EngineDirectory;
                    }
                    else if (IsEnterpriseTarget)
                    {
                        BaseFolder = UnrealBuildTool.EnterpriseDirectory;
                    }
                    else
                    {
                        BaseFolder = GameFolder;
                    }

                    bool        bProjectAlreadyExisted;
                    ProjectFile ProjectFile = FindOrAddProject(ProjectFilePath, BaseFolder,
                                                               true, out bProjectAlreadyExisted);
                    ProjectFile.IsForeignProject =
                        CheckProjectFile != null && !NativeProjects.IsNativeProject(CheckProjectFile);
                    ProjectFile.IsGeneratedProject = true;
                    ProjectFile.IsStubProject      = UnrealBuildTool.IsProjectInstalled();
                    if (TargetRulesObject.bBuildInSolutionByDefault.HasValue)
                    {
                        ProjectFile.ShouldBuildByDefaultForSolutionTargets =
                            TargetRulesObject.bBuildInSolutionByDefault.Value;
                    }

                    // Add the project to the right output list
                    if (IsProgramTarget)
                    {
                        ProgramProjects[TargetFilePath] = ProjectFile;
                    }
                    else if (IsEngineTarget)
                    {
                        EngineProject = ProjectFile;
                        if (UnrealBuildTool.IsEngineInstalled())
                        {
                            // Allow engine projects to be created but not built for Installed Engine builds
                            EngineProject.IsForeignProject   = false;
                            EngineProject.IsGeneratedProject = true;
                            EngineProject.IsStubProject      = true;
                        }
                    }
                    else if (IsEnterpriseTarget)
                    {
                        ProjectFile EnterpriseProject = ProjectFile;
                        if (UnrealBuildTool.IsEnterpriseInstalled())
                        {
                            // Allow enterprise projects to be created but not built for Installed Engine builds
                            EnterpriseProject.IsForeignProject   = false;
                            EnterpriseProject.IsGeneratedProject = true;
                            EnterpriseProject.IsStubProject      = true;
                        }
                    }
                    else
                    {
                        if (!bProjectAlreadyExisted)
                        {
                            GameProjects.Add(ProjectFile);

                            // Add the .uproject file for this game/template
                            FileReference UProjectFilePath =
                                FileReference.Combine(BaseFolder, ProjectFileNameBase + ".uproject");
                            if (FileReference.Exists(UProjectFilePath))
                            {
                                ProjectFile.AddFileToProject(UProjectFilePath, BaseFolder);
                            }
                            else
                            {
                                throw new BuildException(
                                          "Not expecting to find a game with no .uproject file.  File '{0}' doesn't exist",
                                          UProjectFilePath);
                            }
                        }
                    }

                    foreach (ProjectTarget ExistingProjectTarget in ProjectFile.ProjectTargets)
                    {
                        if (ExistingProjectTarget.TargetRules.Type == TargetRulesObject.Type)
                        {
                            throw new BuildException(
                                      "Not expecting project {0} to already have a target rules of with configuration name {1} ({2}) while trying to add: {3}",
                                      ProjectFilePath, TargetRulesObject.Type.ToString(),
                                      ExistingProjectTarget.TargetRules.ToString(), TargetRulesObject.ToString());
                        }

                        // Not expecting to have both a game and a program in the same project.  These would alias because we share the project and solution configuration names (just because it makes sense to)
                        if ((ExistingProjectTarget.TargetRules.Type == TargetType.Game &&
                             TargetRulesObject.Type == TargetType.Program) ||
                            (ExistingProjectTarget.TargetRules.Type == TargetType.Program &&
                             TargetRulesObject.Type == TargetType.Game))
                        {
                            throw new BuildException(
                                      "Not expecting project {0} to already have a Game/Program target ({1}) associated with it while trying to add: {2}",
                                      ProjectFilePath, ExistingProjectTarget.TargetRules.ToString(),
                                      TargetRulesObject.ToString());
                        }
                    }

                    ProjectTarget ProjectTarget = new ProjectTarget()
                    {
                        TargetRules           = TargetRulesObject,
                        TargetFilePath        = TargetFilePath,
                        ProjectFilePath       = ProjectFilePath,
                        UnrealProjectFilePath = CheckProjectFile,
                        SupportedPlatforms    = TargetRulesObject.GetSupportedPlatforms()
                                                .Where(x => UEBuildPlatform.GetBuildPlatform(x, true) != null).ToArray(),
                        CreateRulesDelegate = (Platform, Configuration) =>
                                              RulesAssembly.CreateTargetRules(TargetName, Platform, Configuration, "", CheckProjectFile,
                                                                              null)
                    };

                    ProjectFile.ProjectTargets.Add(ProjectTarget);

                    // Make sure the *.Target.cs file is in the project.
                    ProjectFile.AddFileToProject(TargetFilePath, BaseFolder);

                    Log.TraceVerbose("Generating target {0} for {1}", TargetRulesObject.Type.ToString(),
                                     ProjectFilePath);
                }
            }
        }
        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);
        }
        public override bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations, PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            bool   bSuccess            = false;
            string ProjectNameRaw      = ProjectFilePath.GetFileNameWithoutExtension();
            string ProjectPath         = ProjectFilePath.FullName;
            string ProjectExtension    = ProjectFilePath.GetExtension();
            string ProjectPlatformName = BuildHostPlatform.Current.Platform.ToString();

            // Get the output directory
            string EngineRootDirectory = UnrealBuildTool.EngineDirectory.FullName;

            //
            // Build the working directory of the Game executable.
            //

            string GameWorkingDirectory = "";

            if (OnlyGameProject != null)
            {
                GameWorkingDirectory = Path.Combine(Path.GetDirectoryName(OnlyGameProject.FullName), "Binaries", ProjectPlatformName);
            }
            //
            // Build the working directory of the UE4Editor executable.
            //
            string UE4EditorWorkingDirectory = Path.Combine(EngineRootDirectory, "Binaries", ProjectPlatformName);

            //
            // Create the folder where the project files goes if it does not exist
            //
            String FilePath = Path.GetDirectoryName(ProjectFilePath.FullName);

            if ((FilePath.Length > 0) && !Directory.Exists(FilePath))
            {
                Directory.CreateDirectory(FilePath);
            }

            string GameProjectFile = "";

            if (OnlyGameProject != null)
            {
                GameProjectFile = OnlyGameProject.FullName;
            }

            //
            // Write all targets which will be separate projects.
            //
            foreach (ProjectTarget target in ProjectTargets)
            {
                string[]   tmp = target.ToString().Split('.');
                string     ProjectTargetFileName = Path.GetDirectoryName(ProjectFilePath.FullName) + "/" + tmp [0] + ProjectExtension;
                String     TargetName            = tmp [0];
                TargetType ProjectTargetType     = target.TargetRules.Type;

                //
                // Create the CodeLites root element.
                //
                XElement   CodeLiteProject = new XElement("CodeLite_Project");
                XAttribute CodeLiteProjectAttributeName = new XAttribute("Name", TargetName);
                CodeLiteProject.Add(CodeLiteProjectAttributeName);

                //
                // Select only files we want to add.
                // TODO Maybe skipping those files directly in the following foreach loop is faster?
                //
                List <SourceFile> FilterSourceFile = SourceFiles.FindAll(s => (
                                                                             s.Reference.HasExtension(".h") ||
                                                                             s.Reference.HasExtension(".cpp") ||
                                                                             s.Reference.HasExtension(".c") ||
                                                                             s.Reference.HasExtension(".cs") ||
                                                                             s.Reference.HasExtension(".uproject") ||
                                                                             s.Reference.HasExtension(".uplugin") ||
                                                                             s.Reference.HasExtension(".ini") ||
                                                                             s.Reference.HasExtension(".usf") ||
                                                                             s.Reference.HasExtension(".ush")
                                                                             ));

                //
                // Find/Create the correct virtual folder and place the file into it.
                //
                foreach (SourceFile CurrentFile in FilterSourceFile)
                {
                    //
                    // Try to get the correct relative folder representation for the project.
                    //
                    String CurrentFilePath = "";
                    // TODO It seems that the full pathname doesn't work for some files like .ini, .usf, .ush
                    if ((ProjectTargetType == TargetType.Client) ||
                        (ProjectTargetType == TargetType.Editor) ||
                        (ProjectTargetType == TargetType.Game) ||
                        (ProjectTargetType == TargetType.Server))
                    {
                        if (TargetName.Equals("UE4Client") ||
                            TargetName.Equals("UE4Server") ||
                            TargetName.Equals("UE4Game") ||
                            TargetName.Equals("UE4Editor"))
                        {
                            int Idx = UnrealBuildTool.EngineDirectory.FullName.Length;
                            CurrentFilePath = Path.GetDirectoryName(Path.GetFullPath(CurrentFile.Reference.FullName)).Substring(Idx);
                        }
                        else
                        {
                            int Idx = Path.GetDirectoryName(CurrentFile.Reference.FullName).IndexOf(ProjectNameRaw) + ProjectNameRaw.Length;
                            CurrentFilePath = Path.GetDirectoryName(CurrentFile.Reference.FullName).Substring(Idx);
                        }
                    }
                    else if (ProjectTargetType == TargetType.Program)
                    {
                        //
                        // We do not need all the editors subfolders to show the content. Find the correct programs subfolder.
                        //
                        int Idx = Path.GetDirectoryName(CurrentFile.Reference.FullName).IndexOf(TargetName) + TargetName.Length;
                        CurrentFilePath = Path.GetDirectoryName(CurrentFile.Reference.FullName).Substring(Idx);
                    }

                    char[]    Delimiters   = new char[] { '/', '\\' };
                    string [] SplitFolders = CurrentFilePath.Split(Delimiters, StringSplitOptions.RemoveEmptyEntries);
                    //
                    // Set the CodeLite root folder again.
                    //
                    XElement root = CodeLiteProject;

                    //
                    // Iterate through all XElement virtual folders until we find the right place to put the file.
                    // TODO this looks more like a hack to me.
                    //
                    foreach (string FolderName in SplitFolders)
                    {
                        if (FolderName.Equals(""))
                        {
                            continue;
                        }

                        //
                        // Let's look if there is a virtual folder withint the current XElement.
                        //
                        IEnumerable <XElement> tests = root.Elements("VirtualDirectory");
                        if (IsEmpty(tests))
                        {
                            //
                            // No, then we have to create.
                            //
                            XElement   vf  = new XElement("VirtualDirectory");
                            XAttribute vfn = new XAttribute("Name", FolderName);
                            vf.Add(vfn);
                            root.Add(vf);
                            root = vf;
                        }
                        else
                        {
                            //
                            // Yes, then let's find the correct sub XElement.
                            //
                            bool notfound = true;

                            //
                            // We have some virtual directories let's find the correct one.
                            //
                            foreach (XElement element in tests)
                            {
                                //
                                // Look the the following folder
                                XAttribute attribute = element.Attribute("Name");
                                if (attribute.Value == FolderName)
                                {
                                    // Ok, we found the folder as subfolder, let's use it.
                                    root     = element;
                                    notfound = false;
                                    break;
                                }
                            }
                            //
                            // If we are here we didn't find any XElement with that subfolder, then we have to create.
                            //
                            if (notfound)
                            {
                                XElement   vf  = new XElement("VirtualDirectory");
                                XAttribute vfn = new XAttribute("Name", FolderName);
                                vf.Add(vfn);
                                root.Add(vf);
                                root = vf;
                            }
                        }
                    }

                    //
                    // If we are at this point we found the correct XElement folder
                    //
                    XElement   file          = new XElement("File");
                    XAttribute fileAttribute = new XAttribute("Name", CurrentFile.Reference.FullName);
                    file.Add(fileAttribute);
                    root.Add(file);
                }

                XElement CodeLiteSettings = new XElement("Settings");
                CodeLiteProject.Add(CodeLiteSettings);

                XElement CodeLiteGlobalSettings = new XElement("GlobalSettings");
                CodeLiteProject.Add(CodeLiteGlobalSettings);

                foreach (UnrealTargetConfiguration CurConf in InConfigurations)
                {
                    XElement   CodeLiteConfiguration     = new XElement("Configuration");
                    XAttribute CodeLiteConfigurationName = new XAttribute("Name", CurConf.ToString());
                    CodeLiteConfiguration.Add(CodeLiteConfigurationName);

                    //
                    // Create Configuration General part.
                    //
                    XElement CodeLiteConfigurationGeneral = new XElement("General");

                    //
                    // Create the executable filename.
                    //
                    string ExecutableToRun       = "";
                    string PlatformConfiguration = "-" + ProjectPlatformName + "-" + CurConf.ToString();
                    switch (BuildHostPlatform.Current.Platform)
                    {
                    case UnrealTargetPlatform.Linux:
                    {
                        ExecutableToRun = "./" + TargetName;
                        if ((ProjectTargetType == TargetType.Game) ||
                            (ProjectTargetType == TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetType.Editor)
                        {
                            ExecutableToRun = "./UE4Editor";
                            if ((CurConf == UnrealTargetConfiguration.Debug) ||
                                (CurConf == UnrealTargetConfiguration.Shipping) ||
                                (CurConf == UnrealTargetConfiguration.Test))
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                    }
                    break;

                    case UnrealTargetPlatform.Mac:
                    {
                        ExecutableToRun = "./" + TargetName;
                        if ((ProjectTargetType == TargetType.Game) || (ProjectTargetType == TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                            ExecutableToRun += ".app/Contents/MacOS/" + TargetName;
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetType.Editor)
                        {
                            ExecutableToRun = "./UE4Editor";
                            if ((CurConf == UnrealTargetConfiguration.Debug) ||
                                (CurConf == UnrealTargetConfiguration.Shipping) ||
                                (CurConf == UnrealTargetConfiguration.Test))
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                            ExecutableToRun += ".app/Contents/MacOS/UE4Editor";
                            if ((CurConf != UnrealTargetConfiguration.Development) && (CurConf != UnrealTargetConfiguration.DebugGame))
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                    }
                    break;

                    case UnrealTargetPlatform.Win64:
                    case UnrealTargetPlatform.Win32:
                    {
                        ExecutableToRun = TargetName;
                        if ((ProjectTargetType == TargetType.Game) || (ProjectTargetType == TargetType.Program))
                        {
                            if (CurConf != UnrealTargetConfiguration.Development)
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }
                        else if (ProjectTargetType == TargetType.Editor)
                        {
                            ExecutableToRun = "UE4Editor";
                            if ((CurConf == UnrealTargetConfiguration.Debug) ||
                                (CurConf == UnrealTargetConfiguration.Shipping) ||
                                (CurConf == UnrealTargetConfiguration.Test))
                            {
                                ExecutableToRun += PlatformConfiguration;
                            }
                        }

                        ExecutableToRun += ".exe";
                    }
                    break;

                    default:
                        throw new BuildException("Unsupported platform.");
                    }


                    // Is this project a Game type?
                    XAttribute GeneralExecutableToRun = new XAttribute("Command", ExecutableToRun);
                    if (ProjectTargetType == TargetType.Game)
                    {
                        if (CurConf.ToString().Contains("Debug"))
                        {
                            string     commandArguments = " -debug";
                            XAttribute GeneralExecutableToRunArguments = new XAttribute("CommandArguments", commandArguments);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableToRunArguments);
                        }
                        if (TargetName.Equals("UE4Game"))
                        {
                            XAttribute GeneralExecutableWorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableWorkingDirectory);
                        }
                        else
                        {
                            XAttribute GeneralExecutableWorkingDirectory = new XAttribute("WorkingDirectory", GameWorkingDirectory);
                            CodeLiteConfigurationGeneral.Add(GeneralExecutableWorkingDirectory);
                        }
                    }
                    else if (ProjectTargetType == TargetType.Editor)
                    {
                        if (TargetName != "UE4Editor" && GameProjectFile != "")
                        {
                            string     commandArguments = "\"" + GameProjectFile + "\"" + " -game";
                            XAttribute CommandArguments = new XAttribute("CommandArguments", commandArguments);
                            CodeLiteConfigurationGeneral.Add(CommandArguments);
                        }
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetType.Program)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetType.Client)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    else if (ProjectTargetType == TargetType.Server)
                    {
                        XAttribute WorkingDirectory = new XAttribute("WorkingDirectory", UE4EditorWorkingDirectory);
                        CodeLiteConfigurationGeneral.Add(WorkingDirectory);
                    }
                    CodeLiteConfigurationGeneral.Add(GeneralExecutableToRun);

                    CodeLiteConfiguration.Add(CodeLiteConfigurationGeneral);

                    //
                    // End of Create Configuration General part.
                    //

                    //
                    // Create Configuration Custom Build part.
                    //
                    XElement CodeLiteConfigurationCustomBuild = new XElement("CustomBuild");
                    CodeLiteConfiguration.Add(CodeLiteConfigurationGeneral);
                    XAttribute CodeLiteConfigurationCustomBuildEnabled = new XAttribute("Enabled", "yes");
                    CodeLiteConfigurationCustomBuild.Add(CodeLiteConfigurationCustomBuildEnabled);

                    //
                    // Add the working directory for the custom build commands.
                    //
                    XElement CustomBuildWorkingDirectory  = new XElement("WorkingDirectory");
                    XText    CustuomBuildWorkingDirectory = new XText(UnrealBuildTool.GetUBTPath().Directory.FullName);
                    CustomBuildWorkingDirectory.Add(CustuomBuildWorkingDirectory);
                    CodeLiteConfigurationCustomBuild.Add(CustomBuildWorkingDirectory);

                    //
                    // End of Add the working directory for the custom build commands.
                    //



                    //
                    // Make Build Target.
                    //
                    XElement CustomBuildCommand = new XElement("BuildCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomBuildCommand);

                    string BuildTarget = UnrealBuildTool.GetUBTPath().GetFileName() + " " + TargetName + " " + ProjectPlatformName + " " + CurConf.ToString();
                    if ((BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Win64) &&
                        (BuildHostPlatform.Current.Platform != UnrealTargetPlatform.Win32))
                    {
                        BuildTarget = "mono " + BuildTarget;
                    }

                    if (GameProjectFile.Length > 0)
                    {
                        BuildTarget += " -project=" + "\"" + GameProjectFile + "\"";
                    }

                    XText commandLine = new XText(BuildTarget);
                    CustomBuildCommand.Add(commandLine);

                    //
                    // End of Make Build Target
                    //

                    //
                    // Clean Build Target.
                    //
                    XElement CustomCleanCommand = new XElement("CleanCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomCleanCommand);

                    string CleanTarget      = BuildTarget + " -clean";
                    XText  CleanCommandLine = new XText(CleanTarget);

                    CustomCleanCommand.Add(CleanCommandLine);


                    //
                    // End of Clean Build Target.
                    //

                    //
                    // Rebuild Build Target.
                    //
                    XElement CustomRebuildCommand = new XElement("RebuildCommand");
                    CodeLiteConfigurationCustomBuild.Add(CustomRebuildCommand);

                    string RebuildTarget      = CleanTarget + "\n" + BuildTarget;
                    XText  RebuildCommandLine = new XText(RebuildTarget);

                    CustomRebuildCommand.Add(RebuildCommandLine);

                    //
                    // End of Clean Build Target.
                    //


                    //
                    // Some other fun Custom Targets.
                    //
                    if (ProjectTargetType == TargetType.Game)
                    {
                        string CookGameCommandLine = "mono AutomationTool.exe BuildCookRun ";

                        // Projects filename
                        if (OnlyGameProject != null)
                        {
                            CookGameCommandLine += "-project=\"" + OnlyGameProject.FullName + "\" ";
                        }

                        // Disables Perforce functionality
                        CookGameCommandLine += "-noP4 ";

                        // Do not kill any spawned processes on exit
                        CookGameCommandLine += "-nokill ";
                        CookGameCommandLine += "-clientconfig=" + CurConf.ToString() + " ";
                        CookGameCommandLine += "-serverconfig=" + CurConf.ToString() + " ";
                        CookGameCommandLine += "-platform=" + ProjectPlatformName + " ";
                        CookGameCommandLine += "-targetplatform=" + ProjectPlatformName + " ";                                 // TODO Maybe I can add all the supported one.
                        CookGameCommandLine += "-nocompile ";
                        CookGameCommandLine += "-compressed -stage -deploy";

                        //
                        // Cook Game.
                        //
                        XElement   CookGame        = new XElement("Target");
                        XAttribute CookGameName    = new XAttribute("Name", "Cook Game");
                        XText      CookGameCommand = new XText(CookGameCommandLine + " -cook");
                        CookGame.Add(CookGameName);
                        CookGame.Add(CookGameCommand);
                        CodeLiteConfigurationCustomBuild.Add(CookGame);

                        XElement   CookGameOnTheFly         = new XElement("Target");
                        XAttribute CookGameNameOnTheFlyName = new XAttribute("Name", "Cook Game on the fly");
                        XText      CookGameOnTheFlyCommand  = new XText(CookGameCommandLine + " -cookonthefly");
                        CookGameOnTheFly.Add(CookGameNameOnTheFlyName);
                        CookGameOnTheFly.Add(CookGameOnTheFlyCommand);
                        CodeLiteConfigurationCustomBuild.Add(CookGameOnTheFly);

                        XElement   SkipCook        = new XElement("Target");
                        XAttribute SkipCookName    = new XAttribute("Name", "Skip Cook Game");
                        XText      SkipCookCommand = new XText(CookGameCommandLine + " -skipcook");
                        SkipCook.Add(SkipCookName);
                        SkipCook.Add(SkipCookCommand);
                        CodeLiteConfigurationCustomBuild.Add(SkipCook);
                    }
                    //
                    // End of Some other fun Custom Targets.
                    //
                    CodeLiteConfiguration.Add(CodeLiteConfigurationCustomBuild);

                    //
                    // End of Create Configuration Custom Build part.
                    //

                    CodeLiteSettings.Add(CodeLiteConfiguration);
                }

                CodeLiteSettings.Add(CodeLiteGlobalSettings);

                //
                // Save the XML file.
                //
                CodeLiteProject.Save(ProjectTargetFileName);

                bSuccess = true;
            }
            return(bSuccess);
        }
Exemple #15
0
 /// <summary>
 /// Writes the master project file (e.g. Visual Studio Solution file)
 /// </summary>
 /// <param name="UBTProject">The UnrealBuildTool project</param>
 /// <param name="PlatformProjectGenerators">The registered platform project generators</param>
 /// <returns>True if successful</returns>
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(true);
 }
Exemple #16
0
        /// <summary>
        /// Write project file info in JSON file.
        /// For every combination of <c>UnrealTargetPlatform</c>, <c>UnrealTargetConfiguration</c> and <c>TargetType</c>
        /// will be generated separate JSON file.
        /// Project file will be stored:
        /// For UE4:  {UE4Root}/Engine/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// For game: {GameRoot}/Intermediate/ProjectFiles/.Rider/{Platform}/{Configuration}/{TargetType}/{ProjectName}.json
        /// </summary>
        /// <remarks>
        /// * <c>UnrealTargetPlatform.Win32</c> will be always ignored.
        /// * <c>TargetType.Editor</c> will be generated for current platform only and will ignore <c>UnrealTargetConfiguration.Test</c> and <c>UnrealTargetConfiguration.Shipping</c> configurations
        /// * <c>TargetType.Program</c>  will be generated for current platform only and <c>UnrealTargetConfiguration.Development</c> configuration only
        /// </remarks>
        /// <param name="InPlatforms"></param>
        /// <param name="InConfigurations"></param>
        /// <param name="PlatformProjectGenerators"></param>
        /// <param name="Minimize"></param>
        /// <returns></returns>
        public bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms,
                                     List <UnrealTargetConfiguration> InConfigurations,
                                     PlatformProjectGeneratorCollection PlatformProjectGenerators, JsonWriterStyle Minimize)
        {
            string             ProjectName       = ProjectFilePath.GetFileNameWithoutAnyExtensions();
            DirectoryReference ProjectRootFolder = RootPath;
            List <Tuple <FileReference, UEBuildTarget> > FileToTarget = new List <Tuple <FileReference, UEBuildTarget> >();

            foreach (UnrealTargetPlatform Platform in InPlatforms)
            {
                foreach (UnrealTargetConfiguration Configuration in InConfigurations)
                {
                    foreach (ProjectTarget ProjectTarget in ProjectTargets)
                    {
                        if (TargetTypes.Any() && !TargetTypes.Contains(ProjectTarget.TargetRules.Type))
                        {
                            continue;
                        }

                        // Skip Programs for all configs except for current platform + Development & Debug configurations
                        if (ProjectTarget.TargetRules.Type == TargetType.Program &&
                            (BuildHostPlatform.Current.Platform != Platform ||
                             !(Configuration == UnrealTargetConfiguration.Development || Configuration == UnrealTargetConfiguration.Debug)))
                        {
                            continue;
                        }

                        // Skip Editor for all platforms except for current platform
                        if (ProjectTarget.TargetRules.Type == TargetType.Editor && (BuildHostPlatform.Current.Platform != Platform || (Configuration == UnrealTargetConfiguration.Test || Configuration == UnrealTargetConfiguration.Shipping)))
                        {
                            continue;
                        }

                        DirectoryReference ConfigurationFolder = DirectoryReference.Combine(ProjectRootFolder, Platform.ToString(), Configuration.ToString());

                        DirectoryReference TargetFolder =
                            DirectoryReference.Combine(ConfigurationFolder, ProjectTarget.TargetRules.Type.ToString());

                        string DefaultArchitecture = UEBuildPlatform
                                                     .GetBuildPlatform(Platform)
                                                     .GetDefaultArchitecture(ProjectTarget.UnrealProjectFilePath);
                        TargetDescriptor TargetDesc = new TargetDescriptor(ProjectTarget.UnrealProjectFilePath, ProjectTarget.Name,
                                                                           Platform, Configuration, DefaultArchitecture, Arguments);
                        try
                        {
                            UEBuildTarget BuildTarget = UEBuildTarget.Create(TargetDesc, false, false);

                            FileReference OutputFile = FileReference.Combine(TargetFolder, $"{ProjectName}.json");
                            FileToTarget.Add(Tuple.Create(OutputFile, BuildTarget));
                        }
                        catch (Exception Ex)
                        {
                            Log.TraceWarning("Exception while generating include data for Target:{0}, Platform: {1}, Configuration: {2}", TargetDesc.Name, Platform.ToString(), Configuration.ToString());
                            Log.TraceWarning(Ex.ToString());
                        }
                    }
                }
            }
            foreach (Tuple <FileReference, UEBuildTarget> tuple in FileToTarget)
            {
                try
                {
                    CurrentTarget = tuple.Item2;
                    CurrentTarget.PreBuildSetup();
                    SerializeTarget(tuple.Item1, CurrentTarget, Minimize);
                }
                catch (Exception Ex)
                {
                    Log.TraceWarning("Exception while generating include data for Target:{0}, Platform: {1}, Configuration: {2}", tuple.Item2.AppName, tuple.Item2.Platform.ToString(), tuple.Item2.Configuration.ToString());
                    Log.TraceWarning(Ex.ToString());
                }
            }

            return(true);
        }
Exemple #17
0
 /// ProjectFileGenerator interface
 //protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
 protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(WriteQMakePro());
 }
Exemple #18
0
 /// <summary>
 /// Writes a project file to disk
 /// </summary>
 /// <param name="InPlatforms">The platforms to write the project files for</param>
 /// <param name="InConfigurations">The configurations to add to the project files</param>
 /// <param name="PlatformProjectGenerators">The registered platform project generators</param>
 /// <returns>True on success</returns>
 public virtual bool WriteProjectFile(List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     throw new BuildException("UnrealBuildTool cannot automatically generate this project type because WriteProjectFile() was not overridden.");
 }
Exemple #19
0
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(WriteEddieWorkset());
 }
 /// <summary>
 /// The only valid configuration for these to be run in is Debug|ARM
 /// </summary>
 /// <param name="SolutionTarget">The solution target type</param>
 /// <param name="SolutionConfiguration">The solution configuration</param>
 /// <param name="SolutionPlatform">The solution platform</param>
 /// <param name="PlatformProjectGenerators">Set of platform project generators</param>
 /// <returns>Project context matching the given solution context</returns>
 public override MSBuildProjectContext GetMatchingProjectContext(TargetType SolutionTarget, UnrealTargetConfiguration SolutionConfiguration, UnrealTargetPlatform SolutionPlatform, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(new MSBuildProjectContext("Debug", "ARM")
     {
         bBuildByDefault = (SolutionPlatform == UnrealTargetPlatform.Android)
     });
 }
Exemple #21
0
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            bool bSuccess = true;

            return(bSuccess);
        }
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            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);
        }