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); }
/// <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); }
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); }
/// <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()); } }
/// <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); }
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); }
/// <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); }
/// <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); }
/// ProjectFileGenerator interface //protected override bool WriteMasterProjectFile( ProjectFile UBTProject ) protected override bool WriteProjectFiles(PlatformProjectGeneratorCollection PlatformProjectGenerators) { return(WriteQMakePro()); }
/// <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."); }
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) }); }
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); }