/// <summary>
		/// Recursively searches for the specified project and returns the folder that it lives in, or null if not found
		/// </summary>
		/// <param name="Project">The project file to look for</param>
		/// <returns>The found folder that the project is in, or null</returns>
		public MasterProjectFolder FindFolderForProject( ProjectFile Project )
		{
			foreach( var CurFolder in SubFolders )
			{
				MasterProjectFolder FoundFolder = CurFolder.FindFolderForProject( Project );
				if( FoundFolder != null )
				{
					return FoundFolder;
				}
			}

			foreach( var ChildProject in ChildProjects )
			{
				if( ChildProject == Project )
				{
					return this;
				}
			}

			return null;
		}
        protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
        {
            var SolutionFileName = MasterProjectName + SolutionExtension;
            var CodeCompletionFile = MasterProjectName + CodeCompletionFileName;
            var CodeCompletionPreProcessorFile = MasterProjectName + CodeCompletionPreProcessorFileName;

            var FullCodeLiteMasterFile = Path.Combine(MasterProjectRelativePath, SolutionFileName);
            var FullCodeLiteCodeCompletionFile = Path.Combine(MasterProjectRelativePath, CodeCompletionFile);
            var FullCodeLiteCodeCompletionPreProcessorFile = Path.Combine(MasterProjectRelativePath, 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 seperate 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 (var CurProject in GeneratedProjectFiles)
            {
                CodeLiteProject Project = CurProject as CodeLiteProject;
                if (Project == null)
                {
                    continue;
                }

                foreach (var CurrentPath in Project.IntelliSenseIncludeSearchPaths)
                {
                    // Convert relative path into abosulte.
                    string IntelliSenseIncludeSearchPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(Project.ProjectFilePath)), CurrentPath));
                    IncludeDirectories.Add(IntelliSenseIncludeSearchPath);
                }
                foreach (var CurrentPath in Project.IntelliSenseSystemIncludeSearchPaths)
                {
                    // Convert relative path into abosulte.
                    string IntelliSenseSystemIncludeSearchPath = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(Project.ProjectFilePath)), CurrentPath));
                    IncludeDirectories.Add (IntelliSenseSystemIncludeSearchPath);
                }

                foreach( var 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 (var 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.
            //
            foreach( var CurProject in AllProjectFiles )
            {
                var ProjectExtension = Path.GetExtension (CurProject.ProjectFilePath);

                //
                // 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 = Path.GetDirectoryName (CurProject.RelativeProjectFilePath) + "/" + 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);
                    CodeLiteWorkspace.Add(CodeLiteWorkspaceProject);
                }
            }

            //
            // 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 (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                {
                    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( var CurProject in AllProjectFiles )
                    {
                        var ProjectExtension = Path.GetExtension (CurProject.ProjectFilePath);

                        //
                        // 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;
        }
        protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
        {
            bool bSuccess = true;

            var SolutionFileName = MasterProjectName + ".sln";

            // Setup solution file content
            var VCSolutionFileContent = new StringBuilder();

            // Solution file header
            if( ProjectFileFormat == VCProjectFileFormat.VisualStudio2013 )
            {
                VCSolutionFileContent.Append(
                    ProjectFileGenerator.NewLine +
                    "Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
                    "# Visual Studio 2013" + ProjectFileGenerator.NewLine );

                /* This is not required by VS 2013 to load the projects
                VCSolutionFileContent.Append(
                    "VisualStudioVersion = 12.0.20617.1 PREVIEW" + ProjectFileGenerator.NewLine +
                    "MinimumVisualStudioVersion = 10.0.40219.1" + ProjectFileGenerator.NewLine );*/
            }
            else if( ProjectFileFormat == VCProjectFileFormat.VisualStudio2012 )
            {
                VCSolutionFileContent.Append(
                    ProjectFileGenerator.NewLine +
                    "Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
                    "# Visual Studio 2012" + ProjectFileGenerator.NewLine );
            }
            else
            {
                throw new BuildException( "Unexpected ProjectFileFormat" );
            }

            // Solution folders, files and project entries
            {
                // This the GUID that Visual Studio uses to identify a solution folder
                var SolutionFolderEntryGUID = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";

                // Solution folders
                {
                    var AllSolutionFolders = new List<MasterProjectFolder>();
                    System.Action< List<MasterProjectFolder> /* Folders */ > GatherFoldersFunction = null;
                    GatherFoldersFunction = FolderList =>
                        {
                            AllSolutionFolders.AddRange( FolderList );
                            foreach( var CurSubFolder in FolderList )
                            {
                                GatherFoldersFunction( CurSubFolder.SubFolders );
                            }
                        };
                    GatherFoldersFunction( RootFolder.SubFolders );

                    foreach( VisualStudioSolutionFolder CurFolder in AllSolutionFolders )
                    {
                        var FolderGUIDString = CurFolder.FolderGUID.ToString( "B" ).ToUpperInvariant();
                        VCSolutionFileContent.Append(
                                "Project(\"" + SolutionFolderEntryGUID + "\") = \"" + CurFolder.FolderName + "\", \"" + CurFolder.FolderName + "\", \"" + FolderGUIDString + "\"" + ProjectFileGenerator.NewLine );

                        // Add any files that are inlined right inside the solution folder
                        if( CurFolder.Files.Count > 0 )
                        {
                            VCSolutionFileContent.Append(
                                    "	ProjectSection(SolutionItems) = preProject" + ProjectFileGenerator.NewLine );
                            foreach( var CurFile in CurFolder.Files )
                            {
                                // Syntax is:  <relative file path> = <relative file path>
                                VCSolutionFileContent.Append(
                                    "		" + CurFile + " = " + CurFile + ProjectFileGenerator.NewLine );
                            }
                            VCSolutionFileContent.Append(
                                    "	EndProjectSection" + ProjectFileGenerator.NewLine );
                        }

                        VCSolutionFileContent.Append(
                                "EndProject" + ProjectFileGenerator.NewLine
                            );
                    }
                }

                // Project files
                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.
                    var ProjectNameInSolution = Path.GetFileNameWithoutExtension(CurProject.ProjectFilePath);

                    // Use the existing project's GUID that's already known to us
                    var ProjectGUID = CurProject.ProjectGUID.ToString( "B" ).ToUpperInvariant();

                    VCSolutionFileContent.Append(
                            "Project(\"" + ProjectTypeGUID + "\") = \"" + ProjectNameInSolution + "\", \"" + CurProject.RelativeProjectFilePath + "\", \"" + ProjectGUID + "\"" + ProjectFileGenerator.NewLine );

                    // 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 )
                    {
                        // Don't add self as a project dependency!
                        if ((CurProject != UBTProject) && (CurProject.IsGeneratedProject || (CurProject.DependsOnProjects.Count > 0)))
                        {
                            VCSolutionFileContent.Append(
                                    "	ProjectSection(ProjectDependencies) = postProject" + ProjectFileGenerator.NewLine);

                            if (CurProject.IsGeneratedProject && UBTProject != null)
                            {
                                var UBTProjectGUID = ((MSBuildProjectFile)UBTProject).ProjectGUID.ToString("B").ToUpperInvariant();
                                VCSolutionFileContent.Append(
                                        "		" + UBTProjectGUID + " = " + UBTProjectGUID + ProjectFileGenerator.NewLine);
                            }

                            // Setup any addition dependencies this project has...
                            foreach (var DependsOnProject in CurProject.DependsOnProjects)
                            {
                                var DependsOnProjectGUID = ((MSBuildProjectFile)DependsOnProject).ProjectGUID.ToString("B").ToUpperInvariant();
                                VCSolutionFileContent.Append(
                                    "		" + DependsOnProjectGUID + " = " + DependsOnProjectGUID + ProjectFileGenerator.NewLine);
                            }

                            VCSolutionFileContent.Append(
                                    "	EndProjectSection" + ProjectFileGenerator.NewLine);
                        }
                    }

                    VCSolutionFileContent.Append(
                            "EndProject" + ProjectFileGenerator.NewLine
                        );
                }
            }

            // Solution configuration platforms.  This is just a list of all of the platforms and configurations that
            // appear in Visual Studio's build configuration selector.
            var SolutionConfigCombinations = new List<VCSolutionConfigCombination>();

            // The "Global" section has source control, solution configurations, project configurations,
            // preferences, and project hierarchy data
            {
                VCSolutionFileContent.Append(
                    "Global" + ProjectFileGenerator.NewLine );
                {
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(SolutionConfigurationPlatforms) = preSolution" + ProjectFileGenerator.NewLine );

                        var SolutionConfigurationsValidForProjects = new Dictionary<string, Tuple< UnrealTargetConfiguration, string>>();
                        var PlatformsValidForProjects = new HashSet<UnrealTargetPlatform>();

                        foreach( var CurConfiguration in SupportedConfigurations )
                        {
                            if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                            {
                                foreach (var CurPlatform in SupportedPlatforms)
                                {
                                    if (UnrealBuildTool.IsValidPlatform(CurPlatform))
                                    {
                                        foreach( var 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( var ProjectTarget in CurProject.ProjectTargets )
                                                {
                                                    if( VCProjectFile.IsValidProjectPlatformAndConfiguration( ProjectTarget, CurPlatform, CurConfiguration ) )
                                                    {
                                                        PlatformsValidForProjects.Add( CurPlatform );

                                                        // Default to a target configuration name of "Game", since that will collapse down to an empty string
                                                        var TargetConfigurationName = TargetRules.TargetType.Game.ToString();
                                                        if( ProjectTarget.TargetRules != null )
                                                        {
                                                            TargetConfigurationName = ProjectTarget.TargetRules.ConfigurationName;
                                                        }

                                                        var SolutionConfigName = MakeSolutionConfigurationName( CurConfiguration, TargetConfigurationName );
                                                        SolutionConfigurationsValidForProjects[ SolutionConfigName ] = new Tuple<UnrealTargetConfiguration, string>( CurConfiguration, TargetConfigurationName );
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach( var CurPlatform in PlatformsValidForProjects )
                        {
                            foreach( var SolutionConfigKeyValue in SolutionConfigurationsValidForProjects )
                            {
                                // e.g.  "Development|Win64 = Development|Win64"
                                var SolutionConfigName = SolutionConfigKeyValue.Key;
                                var Configuration = SolutionConfigKeyValue.Value.Item1;
                                var TargetConfigurationName = SolutionConfigKeyValue.Value.Item2;

                                var SolutionPlatformName = CurPlatform.ToString();

                                // For Rocket, there are currently no targets that are valid to build both for Win32 and Win64.  So we simply things by
                                // only displaying a "Windows" platform and building for the appropriate Windows platform automatically based on whichever
                                // configuration they have selected.
                                if( UnrealBuildTool.RunningRocket() && ( CurPlatform == UnrealTargetPlatform.Win32 || CurPlatform == UnrealTargetPlatform.Win64 ) )
                                {
                                    SolutionPlatformName = "Windows";
                                    if( Configuration == UnrealTargetConfiguration.Shipping )
                                    {
                                        if(CurPlatform != UnrealTargetPlatform.Win32)
                                        {
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        if(CurPlatform != UnrealTargetPlatform.Win64)
                                        {
                                            continue;
                                        }
                                    }
                                }

                                var SolutionConfigAndPlatformPair = SolutionConfigName + "|" + SolutionPlatformName;
                                SolutionConfigCombinations.Add(
                                        new VCSolutionConfigCombination
                                        {
                                            VCSolutionConfigAndPlatformName = SolutionConfigAndPlatformPair,
                                            Configuration = Configuration,
                                            Platform = CurPlatform,
                                            TargetConfigurationName = TargetConfigurationName
                                        }
                                    );
                            }
                        }

                        // 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 ); }
                                )
                            );

                        var AppendedSolutionConfigAndPlatformNames = new HashSet<string>( StringComparer.InvariantCultureIgnoreCase );
                        foreach( var 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.Append(
                                    "		" + SolutionConfigCombination.VCSolutionConfigAndPlatformName + " = " + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ProjectFileGenerator.NewLine );
                                AppendedSolutionConfigAndPlatformNames.Add( SolutionConfigCombination.VCSolutionConfigAndPlatformName );
                            }
                        }

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection" + ProjectFileGenerator.NewLine );
                    }

                    // 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.Append(
                            "	GlobalSection(ProjectConfigurationPlatforms) = postSolution" + ProjectFileGenerator.NewLine );

                        var CombinationsThatWereMatchedToProjects = new List<VCSolutionConfigCombination>();

                        foreach( MSBuildProjectFile CurProject in AllProjectFiles )
                        {
                            // NOTE: We don't emit solution configuration entries for "stub" projects.  Those projects are only
                            // built using UnrealBuildTool and don't require a presence in the solution project list

                            // NOTE: We also process projects that were "imported" here, hoping to match those to our solution
                            //       configurations.  In some cases this may not be successful though.  Imported projects
                            //       should always be carefully setup to match our project generator's solution configs.
                            if( !CurProject.IsStubProject )
                            {
                                if( CurProject.ProjectTargets.Count == 0 )
                                {
                                    throw new BuildException( "Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!" );
                                }
                                var IsProgramProject = CurProject.ProjectTargets[ 0 ].TargetRules != null && CurProject.ProjectTargets[ 0 ].TargetRules.Type == TargetRules.TargetType.Program;

                                var GameOrProgramConfigsAlreadyMapped = new HashSet<string>();
                                foreach( var SolutionConfigCombination in SolutionConfigCombinations )
                                {
                                    // Handle aliasing of Program and Game target configuration names
                                    if( ( IsProgramProject && GameOrProgramConfigsAlreadyMapped.Add( SolutionConfigCombination.VCSolutionConfigAndPlatformName ) ) ||
                                        IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Game.ToString() ||
                                        !IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Program.ToString() )
                                    {
                                        var TargetConfigurationName = SolutionConfigCombination.TargetConfigurationName;
                                        if( IsProgramProject && TargetConfigurationName == TargetRules.TargetType.Game.ToString() )
                                        {
                                            TargetConfigurationName = TargetRules.TargetType.Program.ToString();
                                        }

                                        // Now, we want to find a target in this project that maps to the current solution config combination.  Only up to one target should
                                        // and every solution config combination should map to at least one target in one project (otherwise we shouldn't have added it!).
                                        ProjectTarget MatchingProjectTarget = null;
                                        foreach( var ProjectTarget in CurProject.ProjectTargets )
                                        {
                                            bool IsMatchingCombination = VCProjectFile.IsValidProjectPlatformAndConfiguration( ProjectTarget, SolutionConfigCombination.Platform, SolutionConfigCombination.Configuration );
                                            if( ProjectTarget.TargetRules != null )
                                            {
                                                if( TargetConfigurationName != ProjectTarget.TargetRules.ConfigurationName )
                                                {
                                                    // Solution configuration name for this combination doesn't match this target's configuration name.  It's not buildable.
                                                    IsMatchingCombination = false;
                                                }
                                            }
                                            else
                                            {
                                                // UBT gets a pass because it is a dependency of every single configuration combination
                                                if( CurProject != UBTProject &&
                                                    TargetConfigurationName != TargetRules.TargetType.Game.ToString() )
                                                {
                                                    // Can't build non-generated project in configurations except for the default (Game)
                                                    IsMatchingCombination = false;
                                                }
                                            }

                                            if( IsMatchingCombination )
                                            {
                                                if( MatchingProjectTarget != null )
                                                {
                                                    // Not expecting more than one target to match a single solution configuration per project!
                                                    throw new BuildException( "Not expecting more than one target for project " + CurProject.ProjectFilePath + " to match solution configuration " + SolutionConfigCombination.VCSolutionConfigAndPlatformName );
                                                }

                                                MatchingProjectTarget = ProjectTarget;

                                                // NOTE: For faster perf, we could "break" here and bail out early, but that would circumvent the error checking
                                                //		 for multiple targets within a project that may map to a single solution configuration.
                                            }
                                        }

                                        var SolutionConfiguration = SolutionConfigCombination.Configuration;
                                        var SolutionPlatform = SolutionConfigCombination.Platform;

                                        if( MatchingProjectTarget == null )
                                        {
                                            // The current configuration/platform and target configuration name doesn't map to anything our project actually supports.
                                            // We'll map it to a default config.
                                            SolutionConfiguration = UnrealTargetConfiguration.Development;

                                            // Prefer using Win64 as the default, but fall back to a platform the project file actually supports if needed.  This is for
                                            // projects that can never be compiled in Windows, such as UnrealLaunchDaemon which is an iOS-only program
                                            SolutionPlatform = UnrealTargetPlatform.Win64;
                                            if( CurProject.ProjectTargets[0].TargetRules != null )
                                            {
                                                var ProjectSupportedPlatforms = new List<UnrealTargetPlatform>();
                                                CurProject.ProjectTargets[0].TargetRules.GetSupportedPlatforms( ref ProjectSupportedPlatforms );
                                                if( !ProjectSupportedPlatforms.Contains( SolutionPlatform ) )
                                                {
                                                    SolutionPlatform = ProjectSupportedPlatforms[ 0 ];
                                                }
                                            }

                                            if( IsProgramProject )
                                            {
                                                TargetConfigurationName = TargetRules.TargetType.Program.ToString();
                                            }
                                            else
                                            {
                                                TargetConfigurationName = TargetRules.TargetType.Game.ToString();
                                            }
                                        }

                                        // If the project wants to always build in "Development", regardless of what the solution
                                        // configuration is set to, then we'll do that here.  This is used for projects like
                                        // UnrealBuildTool and ShaderCompileWorker
                                        if( MatchingProjectTarget != null )
                                        {
                                            if( MatchingProjectTarget.ForceDevelopmentConfiguration )
                                            {
                                                SolutionConfiguration = UnrealTargetConfiguration.Development;
                                            }
                                        }

                                        string ProjectConfigName;
                                        string ProjectPlatformName;
                                        CurProject.MakeProjectPlatformAndConfigurationNames( SolutionPlatform, SolutionConfiguration, TargetConfigurationName, out ProjectPlatformName, out ProjectConfigName );

                                        var ProjectConfigAndPlatformPair = ProjectConfigName.ToString() + "|" + ProjectPlatformName.ToString();

                                        // e.g.  "{4232C52C-680F-4850-8855-DC39419B5E9B}.Debug|iOS.ActiveCfg = iOS_Debug|Win32"
                                        var CurProjectGUID = CurProject.ProjectGUID.ToString( "B" ).ToUpperInvariant();
                                        VCSolutionFileContent.Append(
                                            "		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".ActiveCfg = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine );

                                        // Set whether this project configuration should be built when the user initiates "build solution"
                                        if( MatchingProjectTarget != null )
                                        {
                                            VCSolutionFileContent.Append(
                                                    "		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Build.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine );

                                            var ProjGen = UEPlatformProjectGenerator.GetPlatformProjectGenerator(SolutionConfigCombination.Platform, true);
                                            if (MatchingProjectTarget.ProjectDeploys ||
                                                ((ProjGen != null) && (ProjGen.GetVisualStudioDeploymentEnabled(SolutionPlatform, SolutionConfiguration) == true)))
                                            {
                                                VCSolutionFileContent.Append(
                                                        "		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Deploy.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine );
                                            }
                                        }

                                        CombinationsThatWereMatchedToProjects.Add( SolutionConfigCombination );
                                    }
                                }
                            }
                        }

                        // Check for problems
                        foreach( var SolutionConfigCombination in SolutionConfigCombinations )
                        {
                            if( !CombinationsThatWereMatchedToProjects.Contains( SolutionConfigCombination ) )
                            {
                                throw new BuildException( "Unable to find a ProjectTarget that matches the solution configuration/platform mapping: " + SolutionConfigCombination.Configuration.ToString() + ", " + SolutionConfigCombination.Platform.ToString() + ", " + SolutionConfigCombination.TargetConfigurationName );
                            }
                        }
                        VCSolutionFileContent.Append(
                            "	EndGlobalSection" + ProjectFileGenerator.NewLine );
                    }

                    // Setup other solution properties
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(SolutionProperties) = preSolution" + ProjectFileGenerator.NewLine );

                        // 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.Append(
                            "		HideSolutionNode = FALSE" + ProjectFileGenerator.NewLine );

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection" + ProjectFileGenerator.NewLine );
                    }

                    // Solution directory hierarchy
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(NestedProjects) = preSolution" + ProjectFileGenerator.NewLine );

                        // 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 )
                                {
                                    var 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.Append(
                                            "		" + ChildProject.ProjectGUID.ToString( "B" ).ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine );
                                    }

                                    foreach( VisualStudioSolutionFolder SubFolder in CurFolder.SubFolders )
                                    {
                                        //	e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}"
                                        LocalVCSolutionFileContent.Append(
                                            "		" + SubFolder.FolderGUID.ToString( "B" ).ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine );
                                    }

                                    // Recurse into subfolders
                                    FolderProcessorFunction( LocalVCSolutionFileContent, CurFolder.SubFolders );
                                }
                            };
                        FolderProcessorFunction( VCSolutionFileContent, RootFolder.SubFolders );

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection" + ProjectFileGenerator.NewLine );
                    }
                }

                VCSolutionFileContent.Append(
                    "EndGlobal" + ProjectFileGenerator.NewLine );
            }

            // Save the solution file
            if( bSuccess )
            {
                var SolutionFilePath = Path.Combine( MasterProjectRelativePath, SolutionFileName );
                bSuccess = WriteFileIfChanged( SolutionFilePath, VCSolutionFileContent.ToString() );
            }

            // Save a solution config file which selects the development editor configuration by default.
            if (bSuccess && ProjectFileFormat == VCProjectFileFormat.VisualStudio2013)
            {
                VCSolutionConfigCombination DefaultConfig = SolutionConfigCombinations.Find(x => x.Configuration == UnrealTargetConfiguration.Development && x.Platform == UnrealTargetPlatform.Win64 && x.TargetConfigurationName == "Editor");
                if (DefaultConfig != null)
                {
                    string SolutionOptionsFileName = Path.Combine(MasterProjectRelativePath, Path.ChangeExtension(SolutionFileName, "v12.suo"));
                    if(!File.Exists(SolutionOptionsFileName))
                    {
                        VCSolutionOptions Options = new VCSolutionOptions();
                        Options.SolutionConfiguration.Add(new VCBinarySetting("ActiveCfg", DefaultConfig.VCSolutionConfigAndPlatformName));
                        Options.Write(SolutionOptionsFileName);
                    }
                }
            }

            return bSuccess;
        }
Example #4
0
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
        {
            bool bSuccess = true;

            return(bSuccess);
        }
Example #5
0
        /// <summary>
        /// Adds the given project to the OtherProjects list
        /// </summary>
        /// <param name="InProject">The project to add</param>
        /// <returns>True if successful</returns>
        public void AddExistingProjectFile(ProjectFile InProject, bool bNeedsAllPlatformAndConfigurations = false, bool bForceDevelopmentConfiguration = false, bool bProjectDeploys = false, List<UnrealTargetPlatform> InSupportedPlatforms = null, List<UnrealTargetConfiguration> InSupportedConfigurations = null)
        {
            if( InProject.ProjectTargets.Count != 0 )
            {
                throw new BuildException( "Expecting existing project to not have any ProjectTargets defined yet." );
            }

            var ProjectTarget = new ProjectTarget();
            if( bForceDevelopmentConfiguration )
            {
                ProjectTarget.ForceDevelopmentConfiguration = true;
            }
            ProjectTarget.ProjectDeploys = bProjectDeploys;

            if (bNeedsAllPlatformAndConfigurations)
            {
                // Add all platforms
                var AllPlatforms = Enum.GetValues(typeof(UnrealTargetPlatform));
                foreach (UnrealTargetPlatform CurPlatfrom in AllPlatforms)
                {
                    ProjectTarget.ExtraSupportedPlatforms.Add(CurPlatfrom);
                }

                // Add all configurations
                var AllConfigurations = Enum.GetValues(typeof(UnrealTargetConfiguration));
                foreach (UnrealTargetConfiguration CurConfiguration in AllConfigurations)
                {
                    ProjectTarget.ExtraSupportedConfigurations.Add( CurConfiguration );
                }
            }
            else if (InSupportedPlatforms != null || InSupportedConfigurations != null)
            {
                if (InSupportedPlatforms != null)
                {
                    // Add all explicitly specified platforms
                    foreach (UnrealTargetPlatform CurPlatfrom in InSupportedPlatforms)
                    {
                        ProjectTarget.ExtraSupportedPlatforms.Add(CurPlatfrom);
                    }
                }
                else
                {
                    // Otherwise, add all platforms
                    var AllPlatforms = Enum.GetValues(typeof(UnrealTargetPlatform));
                    foreach (UnrealTargetPlatform CurPlatfrom in AllPlatforms)
                    {
                        ProjectTarget.ExtraSupportedPlatforms.Add(CurPlatfrom);
                    }
                }

                if (InSupportedConfigurations != null)
                {
                    // Add all explicitly specified configurations
                    foreach (UnrealTargetConfiguration CurConfiguration in InSupportedConfigurations)
                    {
                        ProjectTarget.ExtraSupportedConfigurations.Add(CurConfiguration);
                    }
                }
                else
                {
                    // Otherwise, add all configurations
                    var AllConfigurations = Enum.GetValues(typeof(UnrealTargetConfiguration));
                    foreach (UnrealTargetConfiguration CurConfiguration in AllConfigurations)
                    {
                        ProjectTarget.ExtraSupportedConfigurations.Add(CurConfiguration);
                    }
                }
            }
            else
            {
                // For existing project files, just support the default desktop platforms and configurations
                UnrealBuildTool.GetAllDesktopPlatforms(ref ProjectTarget.ExtraSupportedPlatforms, false);
                // Debug and Development only
                ProjectTarget.ExtraSupportedConfigurations.Add(UnrealTargetConfiguration.Debug);
                ProjectTarget.ExtraSupportedConfigurations.Add(UnrealTargetConfiguration.Development);
            }

            InProject.ProjectTargets.Add( ProjectTarget );

            // Existing projects must always have a GUID.  This will throw an exception if one isn't found.
            InProject.LoadGUIDFromExistingProject();

            OtherProjectFiles.Add( InProject );
        }
Example #6
0
        /// Adds shader source code to the specified project
        protected void AddEngineShaderSource( ProjectFile EngineProject )
        {
            // Setup a project file entry for this module's project.  Remember, some projects may host multiple modules!
            var ShadersDirectory = Path.Combine( EngineRelativePath, "Shaders" );

            var DirectoriesToSearch = new List<string>();
            DirectoriesToSearch.Add( ShadersDirectory );
            var SubdirectoryNamesToExclude = new List<string>();
            {
                // Don't include binary shaders in the project file.
                SubdirectoryNamesToExclude.Add( "Binaries" );
                // We never want shader intermediate files in our project file
                SubdirectoryNamesToExclude.Add( "PDBDump" );
                SubdirectoryNamesToExclude.Add( "WorkingDirectory" );
            }
            EngineProject.AddFilesToProject( SourceFileSearch.FindFiles(
                DirectoriesToSearch: DirectoriesToSearch,
                ExcludeNoRedistFiles: bExcludeNoRedistFiles,
                SubdirectoryNamesToExclude: SubdirectoryNamesToExclude ), EngineRelativePath );
        }
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
        {
            var SolutionFileName               = MasterProjectName + SolutionExtension;
            var CodeCompletionFile             = MasterProjectName + CodeCompletionFileName;
            var CodeCompletionPreProcessorFile = MasterProjectName + CodeCompletionPreProcessorFileName;

            var FullCodeLiteMasterFile                     = Path.Combine(MasterProjectPath.FullName, SolutionFileName);
            var FullCodeLiteCodeCompletionFile             = Path.Combine(MasterProjectPath.FullName, CodeCompletionFile);
            var 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 (var CurProject in GeneratedProjectFiles)
            {
                CodeLiteProject Project = CurProject as CodeLiteProject;
                if (Project == null)
                {
                    continue;
                }

                foreach (var CurrentPath in Project.IntelliSenseIncludeSearchPaths)
                {
                    // Convert relative path into absolute.
                    DirectoryReference IntelliSenseIncludeSearchPath = DirectoryReference.Combine(Project.ProjectFilePath.Directory, CurrentPath);
                    IncludeDirectories.Add(IntelliSenseIncludeSearchPath.FullName);
                }
                foreach (var CurrentPath in Project.IntelliSenseSystemIncludeSearchPaths)
                {
                    // Convert relative path into absolute.
                    DirectoryReference IntelliSenseSystemIncludeSearchPath = DirectoryReference.Combine(Project.ProjectFilePath.Directory, CurrentPath);
                    IncludeDirectories.Add(IntelliSenseSystemIncludeSearchPath.FullName);
                }

                foreach (var 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 (var 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 (var CurProject in AllProjectFiles)
            {
                var 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 (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                {
                    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 (var CurProject in AllProjectFiles)
                    {
                        var 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);
        }
Example #8
0
        /// <summary>
        /// Creates project entries for all known targets (*.Target.cs files)
        /// </summary>
        /// <param name="AllGameFolders">All game folders</param>
        /// <param name="EngineProject">The engine project we created</param>
        /// <param name="GameProjects">Map of game folder name to all of the game projects we created</param>
        /// <param name="ProgramProjects">Map of program names to all of the program projects we created</param>
        /// <param name="TemplateGameProjects">Set of template game projects we found.  These will also be in the GameProjects map</param>
        private void AddProjectsForAllTargets( List<UProjectInfo> AllGames, out ProjectFile EngineProject, out Dictionary<string, ProjectFile> GameProjects, out Dictionary<string, ProjectFile> ProgramProjects, out HashSet<ProjectFile> TemplateGameProjects )
        {
            // 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 Dictionary<string,ProjectFile>( StringComparer.InvariantCultureIgnoreCase );
            ProgramProjects = new Dictionary<string,ProjectFile>( StringComparer.InvariantCultureIgnoreCase );
            TemplateGameProjects = new HashSet<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.
            var AllTargetFiles = DiscoverTargets();

            foreach( var TargetFilePath in AllTargetFiles )
            {
                var TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath);		// Remove both ".cs" and ".Target"

                // Check to see if this is an Engine target.  That is, the target is located under the "Engine" folder
                bool IsEngineTarget = false;
                string TargetFileRelativeToEngineDirectory = Utils.MakePathRelativeTo(TargetFilePath, Path.Combine(EngineRelativePath), AlwaysTreatSourceAsDirectory: false);
                if (!TargetFileRelativeToEngineDirectory.StartsWith( ".." ) && !Path.IsPathRooted( TargetFileRelativeToEngineDirectory ))
                {
                    // This is an engine target
                    IsEngineTarget = true;
                }

                if (IsEngineTarget && bGeneratingRocketProjectFiles)
                {
                    // Rocket project file must never include engine targets.
                    continue;
                }

                bool WantProjectFileForTarget = true;
                if(TargetFileRelativeToEngineDirectory.StartsWith(Path.Combine("Source", "Programs"), StringComparison.InvariantCultureIgnoreCase))
                {
                    WantProjectFileForTarget = IncludeEnginePrograms;
                }
                else if(TargetFileRelativeToEngineDirectory.StartsWith(Path.Combine("Source"), StringComparison.InvariantCultureIgnoreCase))
                {
                    WantProjectFileForTarget = IncludeEngineSource;
                }

                if (WantProjectFileForTarget)
                {
                    // 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...
                    string UnusedTargetFilePath;
                    var TargetRulesObject = RulesCompiler.CreateTargetRules(TargetName, new TargetInfo(BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development), false, out UnusedTargetFilePath);

                    // Exclude client and server targets under binary Rocket; it's impossible to build without precompiled engine binaries
                    if (!UnrealBuildTool.RunningRocket() || (TargetRulesObject.Type != TargetRules.TargetType.Client && TargetRulesObject.Type != TargetRules.TargetType.Server))
                    {
                        bool IsProgramTarget = false;

                        string GameFolder = null;
                        string ProjectFileNameBase = null;
                        if (TargetRulesObject.Type == TargetRules.TargetType.Program)
                        {
                            IsProgramTarget = true;
                            ProjectFileNameBase = TargetName;
                        }
                        else if (IsEngineTarget)
                        {
                            ProjectFileNameBase = EngineProjectFileNameBase;
                        }
                        else
                        {
                            // Figure out which game project this target belongs to
                            UProjectInfo 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.Folder;
                            ProjectFileNameBase = ProjectInfo.GameName;
                        }

                        // @todo projectfiles: We should move all of the Target.cs files out of sub-folders to clean up the project directories a bit (e.g. GameUncooked folder)

                        var ProjectFilePath = Path.Combine(IntermediateProjectFilesPath, ProjectFileNameBase + ProjectFileExtension);

                        if (TargetRules.IsGameType(TargetRulesObject.Type) &&
                            (TargetRules.IsEditorType(TargetRulesObject.Type) == false))
                        {
                            // Allow platforms to generate stub projects here...
                            UEPlatformProjectGenerator.GenerateGameProjectStubs(
                                InGenerator: this,
                                InTargetName: TargetName,
                                InTargetFilepath: TargetFilePath,
                                InTargetRules: TargetRulesObject,
                                InPlatforms: SupportedPlatforms,
                                InConfigurations: SupportedConfigurations);
                        }

                        ProjectFilePath = Utils.MakePathRelativeTo(ProjectFilePath, MasterProjectRelativePath);

                        bool bProjectAlreadyExisted;
                        var ProjectFile = FindOrAddProject(ProjectFilePath, IncludeInGeneratedProjects: true, bAlreadyExisted: out bProjectAlreadyExisted);
                        ProjectFile.IsForeignProject = bGeneratingGameProjectFiles && UnrealBuildTool.HasUProjectFile() && Utils.IsFileUnderDirectory(TargetFilePath, UnrealBuildTool.GetUProjectPath());
                        ProjectFile.IsGeneratedProject = true;
                        ProjectFile.IsStubProject = false;

                        bool IsTemplateTarget = false;
                        {
                            // Check to see if this is a template target.  That is, the target is located under the "Templates" folder
                            string TargetFileRelativeToTemplatesDirectory = Utils.MakePathRelativeTo(TargetFilePath, Path.Combine(RootRelativePath, "Templates"));
                            if (!TargetFileRelativeToTemplatesDirectory.StartsWith("..") && !Path.IsPathRooted(TargetFileRelativeToTemplatesDirectory))
                            {
                                IsTemplateTarget = true;
                            }
                        }
                        string BaseFolder = null;
                        if (IsProgramTarget)
                        {
                            ProgramProjects[TargetName] = ProjectFile;
                            BaseFolder = Path.GetDirectoryName(TargetFilePath);
                        }
                        else if (IsEngineTarget)
                        {
                            EngineProject = ProjectFile;
                            BaseFolder = EngineRelativePath;
                        }
                        else
                        {
                            GameProjects[GameFolder] = ProjectFile;
                            if (IsTemplateTarget)
                            {
                                TemplateGameProjects.Add(ProjectFile);
                            }
                            BaseFolder = GameFolder;

                            if (!bProjectAlreadyExisted)
                            {
                                // Add the .uproject file for this game/template
                                var UProjectFilePath = Path.Combine(BaseFolder, ProjectFileNameBase + ".uproject");
                                if (File.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 (var ExistingProjectTarget in ProjectFile.ProjectTargets)
                        {
                            if (ExistingProjectTarget.TargetRules.ConfigurationName.Equals(TargetRulesObject.ConfigurationName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                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.ConfigurationName, 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 == TargetRules.TargetType.Game && ExistingProjectTarget.TargetRules.Type == TargetRules.TargetType.Program ||
                                ExistingProjectTarget.TargetRules.Type == TargetRules.TargetType.Program && ExistingProjectTarget.TargetRules.Type == TargetRules.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());
                            }
                        }

                        var ProjectTarget = new ProjectTarget()
                            {
                                TargetRules = TargetRulesObject,
                                TargetFilePath = TargetFilePath
                            };

                        if (TargetName == "ShaderCompileWorker")		// @todo projectfiles: Ideally, the target rules file should set this
                        {
                            ProjectTarget.ForceDevelopmentConfiguration = true;
                        }

                        ProjectFile.ProjectTargets.Add(ProjectTarget);

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

                        // We special case ShaderCompileWorker.  It needs to always be compiled in Development mode.
                        Log.TraceVerbose("Generating target {0} for {1}", TargetRulesObject.Type.ToString(), ProjectFilePath);
                    }
                }
            }
        }
        /// <summary>
        /// For additional Project file *PROJECTNAME*-AndroidRun.androidproj that needs to be written out.  This is currently used only on Android.
        /// </summary>
        /// <param name="ProjectFile">ProjectFile object</param>
        public override Tuple <ProjectFile, string> WriteAdditionalProjFile(ProjectFile ProjectFile)
        {
            if (!IsVSAndroidSupportInstalled())
            {
                return(null);
            }

            string ProjectName = ProjectFile.ProjectFilePath.GetFileNameWithoutExtension() + "-AndroidRun";

            string FileName = ProjectName + ".androidproj";

            string FileText = "<?xml version=\"1.0\" encoding=\"utf-8\"?> " + ProjectFileGenerator.NewLine +
                              "<Project DefaultTargets=\"Build\" ToolsVersion=\"14.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\"> " + ProjectFileGenerator.NewLine +
                              "	<ItemGroup Label=\"ProjectConfigurations\"> " + ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Debug|ARM\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Debug</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Development|ARM\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Development</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Release|ARM\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Release</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Debug|ARM64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Debug</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Development|ARM64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Development</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Release|ARM64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Release</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>ARM64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Debug|x64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Debug</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Development|x64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Development</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Release|x64\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Release</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x64</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Debug|x86\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Debug</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x86</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Development|x86\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Development</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x86</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectConfiguration Include=\"Release|x86\"> "+ ProjectFileGenerator.NewLine +
                              "			<Configuration>Release</Configuration> "+ ProjectFileGenerator.NewLine +
                              "			<Platform>x86</Platform> "+ ProjectFileGenerator.NewLine +
                              "		</ProjectConfiguration> "+ ProjectFileGenerator.NewLine +
                              "	</ItemGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Label=\"Globals\"> " + ProjectFileGenerator.NewLine +
                              "		<RootNamespace>"+ ProjectName + "</RootNamespace> " + ProjectFileGenerator.NewLine +
                              "		<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion> "+ ProjectFileGenerator.NewLine +
                              "		<ProjectVersion>1.0</ProjectVersion> "+ ProjectFileGenerator.NewLine +

                              //Set the project guid
                              "		<ProjectGuid>"+ System.Guid.NewGuid().ToString("B").ToUpper() + "</ProjectGuid> " + ProjectFileGenerator.NewLine +

                              "		<ConfigurationType>Application</ConfigurationType> "+ ProjectFileGenerator.NewLine +
                              "		<_PackagingProjectWithoutNativeComponent>true</_PackagingProjectWithoutNativeComponent> "+ ProjectFileGenerator.NewLine +
                              "		<LaunchActivity Condition=\"\'$(LaunchActivity)\' == \'\'\">com."+ ProjectName + "." + ProjectName + "</LaunchActivity> " + ProjectFileGenerator.NewLine +
                              "		<JavaSourceRoots>src</JavaSourceRoots> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<Import Project=\"$(AndroidTargetsPath)\\Android.Default.props\" /> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>true</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>true</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>true</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x64\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x86\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>true</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x86\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x86\'\" Label=\"Configuration\"> " + ProjectFileGenerator.NewLine +
                              "		<UseDebugLibraries>false</UseDebugLibraries> "+ ProjectFileGenerator.NewLine +
                              "		<TargetName>$(RootNamespace)</TargetName> "+ ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<Import Project=\"$(AndroidTargetsPath)\\Android.props\" /> " + ProjectFileGenerator.NewLine +
                              "	<ImportGroup Label=\"ExtensionSettings\" /> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Label=\"UserMacros\" /> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<PropertyGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "	</PropertyGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|ARM64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x64\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Debug|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Development|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<ItemDefinitionGroup Condition=\"\'$(Configuration)|$(Platform)\'==\'Release|x86\'\"> " + ProjectFileGenerator.NewLine +
                              "		<AntPackage> "+ ProjectFileGenerator.NewLine +
                              "			<AndroidAppLibName /> "+ ProjectFileGenerator.NewLine +
                              "		</AntPackage> "+ ProjectFileGenerator.NewLine +
                              "	</ItemDefinitionGroup> " + ProjectFileGenerator.NewLine +
                              "	<Import Project=\"$(AndroidTargetsPath)\\Android.targets\" /> " + ProjectFileGenerator.NewLine +
                              "	<ImportGroup Label=\"ExtensionTargets\" /> " + ProjectFileGenerator.NewLine +
                              "</Project>";

            bool Success = ProjectFileGenerator.WriteFileIfChanged(ProjectFileGenerator.IntermediateProjectFilesPath + "\\" + FileName, FileText);

            FileReference           ProjectFilePath = FileReference.Combine(ProjectFileGenerator.IntermediateProjectFilesPath, FileName);
            AndroidDebugProjectFile Project         = new AndroidDebugProjectFile(ProjectFilePath);

            Project.ShouldBuildForAllSolutionTargets       = false;
            Project.ShouldBuildByDefaultForSolutionTargets = false;

            return(Success ? new Tuple <ProjectFile, string>(Project, "UE4 Android Debug Projects") : null);
        }
 /// <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);
 }
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
        {
            bool bSuccess = true;

            return(bSuccess);
        }
		/// <summary>
		/// Writes the master project file (e.g. Visual Studio Solution file)
		/// </summary>
		/// <param name="UBTProject">The UnrealBuildTool project</param>
		/// <returns>True if successful</returns>
		protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
		{
			return true;
		}
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
 {
     return(WriteEddieWorkset());
 }
		/// <summary>
		/// Adds Extra files that are specific to Visual Studio projects
		/// </summary>
		/// <param name="EngineProject">Project to add files to</param>
		protected override void AddEngineExtrasFiles(ProjectFile EngineProject)
		{
			base.AddEngineExtrasFiles(EngineProject);

			// Add our UE4.natvis file
			var NatvisFilePath = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Extras", "VisualStudioDebugging", "UE4.natvis");
			if (NatvisFilePath.Exists())
			{
				EngineProject.AddFileToProject(NatvisFilePath, UnrealBuildTool.EngineDirectory);
			}
		}
 /// <summary>
 /// For additional Project files (ex. *PROJECTNAME*-AndroidRun.androidproj.user) that needs to be written out.  This is currently used only on Android.
 /// </summary>
 /// <param name="ProjectFile">Project file this will be related to</param>
 public virtual void WriteAdditionalProjUserFile(ProjectFile ProjectFile)
 {
 }
Example #16
0
 /// <summary>
 /// Writes the master project file (e.g. Visual Studio Solution file)
 /// </summary>
 /// <param name="UBTProject">The UnrealBuildTool project</param>
 /// <returns>True if successful</returns>
 protected abstract bool WriteMasterProjectFile( ProjectFile UBTProject );
 /// <summary>
 /// For additional Project files (ex. *PROJECTNAME*-AndroidRun.androidproj) that needs to be written out.  This is currently used only on Android.
 /// </summary>
 /// <param name="ProjectFile">Project file this will be related to</param>
 /// <returns>Project file written out, Solution folder it should be put in</returns>
 public virtual Tuple <ProjectFile, string> WriteAdditionalProjFile(ProjectFile ProjectFile)
 {
     return(null);
 }
Example #18
0
        /// <summary>
        /// Adds UnrealBuildTool to the master project
        /// </summary>
        private void AddUnrealBuildToolProject( MasterProjectFolder ProgramsFolder, IEnumerable<ProjectFile> Dependencies )
        {
            var ProjectFileName = Utils.MakePathRelativeTo( Path.Combine( Path.Combine( EngineRelativePath, "Source" ), "Programs", "UnrealBuildTool", "UnrealBuildTool.csproj" ), MasterProjectRelativePath );
            var UnrealBuildToolProject = new VCSharpProjectFile( ProjectFileName );
            UnrealBuildToolProject.ShouldBuildForAllSolutionTargets = true;

            foreach (var Dependent in Dependencies)
            {
                UnrealBuildToolProject.AddDependsOnProject( Dependent );
            }

            // Store it off as we need it when generating target projects.
            UBTProject = UnrealBuildToolProject;

            // Add the project
            AddExistingProjectFile(UnrealBuildToolProject, bNeedsAllPlatformAndConfigurations:true, bForceDevelopmentConfiguration:true);

            // Put this in a solution folder
            ProgramsFolder.ChildProjects.Add( UnrealBuildToolProject );
        }
Example #19
0
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
        {
            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.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");
            }

            // Find the projects for ShaderCompileWorker and UnrealLightmass
            ProjectFile ShaderCompileWorkerProject = null;
            ProjectFile UnrealLightmassProject     = null;

            foreach (ProjectFile Project in AllProjectFiles)
            {
                if (Project.ProjectTargets.Count == 1)
                {
                    FileReference TargetFilePath = Project.ProjectTargets[0].TargetFilePath;
                    if (TargetFilePath != null)
                    {
                        string TargetFileName = TargetFilePath.GetFileNameWithoutAnyExtensions();
                        if (TargetFileName.Equals("ShaderCompileWorker", StringComparison.InvariantCultureIgnoreCase))
                        {
                            ShaderCompileWorkerProject = Project;
                        }
                        else if (TargetFileName.Equals("UnrealLightmass", StringComparison.InvariantCultureIgnoreCase))
                        {
                            UnrealLightmassProject = Project;
                        }
                    }
                    if (ShaderCompileWorkerProject != null &&
                        UnrealLightmassProject != null)
                    {
                        break;
                    }
                }
            }

            // 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);

                    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
                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);
                        }
                        if (bEditorDependsOnShaderCompileWorker && !bUsePrecompiled && CurProject.IsGeneratedProject && ShaderCompileWorkerProject != null && CurProject.ProjectTargets.Any(x => x.TargetRules != null && x.TargetRules.Type == TargetType.Editor))
                        {
                            Dependencies.Add(ShaderCompileWorkerProject);
                        }
                        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))
                                                    {
                                                        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);

                                // 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;

                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);
        }
Example #20
0
        /// Adds engine build infrastructure files to the specified project
        protected void AddEngineBuildFiles( ProjectFile EngineProject )
        {
            var BuildDirectory = Path.Combine( EngineRelativePath, "Build" );

            var DirectoriesToSearch = new List<string>();
            DirectoriesToSearch.Add( BuildDirectory );
            var SubdirectoryNamesToExclude = new List<string>();
            {
                // Nothing to exclude, yet!
                // SubdirectoryNamesToExclude.Add( "DirectoryName" );
            }
            EngineProject.AddFilesToProject( SourceFileSearch.FindFiles(
                DirectoriesToSearch: DirectoriesToSearch,
                ExcludeNoRedistFiles: bExcludeNoRedistFiles,
                SubdirectoryNamesToExclude: SubdirectoryNamesToExclude ), EngineRelativePath );
        }
Example #21
0
        static void BuildSolutionExplorerState_VS2017(MasterProjectFolder Folder, string Suffix, VCSolutionExplorerState ExplorerState, ProjectFile DefaultProject)
        {
            foreach (ProjectFile Project in Folder.ChildProjects)
            {
                string ProjectIdentifier = String.Format("{0}{1}", Project.ProjectFilePath.GetFileNameWithoutExtension(), Suffix);
                if (Project == DefaultProject)
                {
                    ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectIdentifier, new string[] { ProjectIdentifier }));
                }
                else
                {
                    ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectIdentifier, new string[] { }));
                }
            }

            foreach (MasterProjectFolder SubFolder in Folder.SubFolders)
            {
                string SubFolderName = SubFolder.FolderName + Suffix;
                if (SubFolderName == "Automation;Programs")
                {
                    ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(SubFolderName, new string[] { }));
                }
                else
                {
                    ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(SubFolderName, new string[] { SubFolderName }));
                }
                BuildSolutionExplorerState_VS2017(SubFolder, ";" + SubFolderName, ExplorerState, DefaultProject);
            }
        }
Example #22
0
        protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
        {
            bool bSuccess = true;

            var SolutionFileName = MasterProjectName + ".sln";

            // Setup solution file content
            var VCSolutionFileContent = new StringBuilder();

            const string VersionTag = "# UnrealEngineGeneratedSolutionVersion=1.0";

            // Solution file header
            if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2013)
            {
                VCSolutionFileContent.Append(
                    ProjectFileGenerator.NewLine +
                    "Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
                    "# Visual Studio 2013" + ProjectFileGenerator.NewLine +
                    VersionTag + ProjectFileGenerator.NewLine);

                /* This is not required by VS 2013 to load the projects
                 * VCSolutionFileContent.Append(
                 *      "VisualStudioVersion = 12.0.20617.1 PREVIEW" + ProjectFileGenerator.NewLine +
                 *      "MinimumVisualStudioVersion = 10.0.40219.1" + ProjectFileGenerator.NewLine );*/
            }
            else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2012)
            {
                VCSolutionFileContent.Append(
                    ProjectFileGenerator.NewLine +
                    "Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
                    "# Visual Studio 2012" + ProjectFileGenerator.NewLine +
                    VersionTag + ProjectFileGenerator.NewLine);
            }
            else
            {
                throw new BuildException("Unexpected ProjectFileFormat");
            }


            // Solution folders, files and project entries
            {
                // This the GUID that Visual Studio uses to identify a solution folder
                var SolutionFolderEntryGUID = "{2150E333-8FDC-42A3-9474-1A3956D46DE8}";

                // Solution folders
                {
                    var AllSolutionFolders = new List <MasterProjectFolder>();
                    System.Action <List <MasterProjectFolder> /* Folders */> GatherFoldersFunction = null;
                    GatherFoldersFunction = FolderList =>
                    {
                        AllSolutionFolders.AddRange(FolderList);
                        foreach (var CurSubFolder in FolderList)
                        {
                            GatherFoldersFunction(CurSubFolder.SubFolders);
                        }
                    };
                    GatherFoldersFunction(RootFolder.SubFolders);

                    foreach (VisualStudioSolutionFolder CurFolder in AllSolutionFolders)
                    {
                        var FolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant();
                        VCSolutionFileContent.Append(
                            "Project(\"" + SolutionFolderEntryGUID + "\") = \"" + CurFolder.FolderName + "\", \"" + CurFolder.FolderName + "\", \"" + FolderGUIDString + "\"" + ProjectFileGenerator.NewLine);

                        // Add any files that are inlined right inside the solution folder
                        if (CurFolder.Files.Count > 0)
                        {
                            VCSolutionFileContent.Append(
                                "	ProjectSection(SolutionItems) = preProject"+ ProjectFileGenerator.NewLine);
                            foreach (var CurFile in CurFolder.Files)
                            {
                                // Syntax is:  <relative file path> = <relative file path>
                                VCSolutionFileContent.Append(
                                    "		"+ CurFile + " = " + CurFile + ProjectFileGenerator.NewLine);
                            }
                            VCSolutionFileContent.Append(
                                "	EndProjectSection"+ ProjectFileGenerator.NewLine);
                        }

                        VCSolutionFileContent.Append(
                            "EndProject" + ProjectFileGenerator.NewLine
                            );
                    }
                }


                // Project files
                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.
                    var ProjectNameInSolution = Path.GetFileNameWithoutExtension(CurProject.ProjectFilePath);

                    // Use the existing project's GUID that's already known to us
                    var ProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant();

                    VCSolutionFileContent.Append(
                        "Project(\"" + ProjectTypeGUID + "\") = \"" + ProjectNameInSolution + "\", \"" + CurProject.RelativeProjectFilePath + "\", \"" + ProjectGUID + "\"" + ProjectFileGenerator.NewLine);

                    // 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)
                    {
                        var 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.Append("\tProjectSection(ProjectDependencies) = postProject" + ProjectFileGenerator.NewLine);

                            // Setup any addition dependencies this project has...
                            foreach (var DependsOnProject in Dependencies)
                            {
                                var DependsOnProjectGUID = ((MSBuildProjectFile)DependsOnProject).ProjectGUID.ToString("B").ToUpperInvariant();
                                VCSolutionFileContent.Append("\t\t" + DependsOnProjectGUID + " = " + DependsOnProjectGUID + ProjectFileGenerator.NewLine);
                            }

                            VCSolutionFileContent.Append("\tEndProjectSection" + ProjectFileGenerator.NewLine);
                        }
                    }

                    VCSolutionFileContent.Append(
                        "EndProject" + ProjectFileGenerator.NewLine
                        );
                }
            }

            // Solution configuration platforms.  This is just a list of all of the platforms and configurations that
            // appear in Visual Studio's build configuration selector.
            var SolutionConfigCombinations = new List <VCSolutionConfigCombination>();

            // The "Global" section has source control, solution configurations, project configurations,
            // preferences, and project hierarchy data
            {
                VCSolutionFileContent.Append(
                    "Global" + ProjectFileGenerator.NewLine);
                {
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(SolutionConfigurationPlatforms) = preSolution"+ ProjectFileGenerator.NewLine);

                        var SolutionConfigurationsValidForProjects = new Dictionary <string, Tuple <UnrealTargetConfiguration, string> >();
                        var PlatformsValidForProjects = new HashSet <UnrealTargetPlatform>();

                        foreach (var CurConfiguration in SupportedConfigurations)
                        {
                            if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
                            {
                                foreach (var CurPlatform in SupportedPlatforms)
                                {
                                    if (UnrealBuildTool.IsValidPlatform(CurPlatform))
                                    {
                                        foreach (var 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 (var ProjectTarget in CurProject.ProjectTargets)
                                                {
                                                    if (VCProjectFile.IsValidProjectPlatformAndConfiguration(ProjectTarget, CurPlatform, CurConfiguration))
                                                    {
                                                        PlatformsValidForProjects.Add(CurPlatform);

                                                        // Default to a target configuration name of "Game", since that will collapse down to an empty string
                                                        var TargetConfigurationName = TargetRules.TargetType.Game.ToString();
                                                        if (ProjectTarget.TargetRules != null)
                                                        {
                                                            TargetConfigurationName = ProjectTarget.TargetRules.ConfigurationName;
                                                        }

                                                        var SolutionConfigName = MakeSolutionConfigurationName(CurConfiguration, TargetConfigurationName);
                                                        SolutionConfigurationsValidForProjects[SolutionConfigName] = new Tuple <UnrealTargetConfiguration, string>(CurConfiguration, TargetConfigurationName);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        foreach (var CurPlatform in PlatformsValidForProjects)
                        {
                            foreach (var SolutionConfigKeyValue in SolutionConfigurationsValidForProjects)
                            {
                                // e.g.  "Development|Win64 = Development|Win64"
                                var SolutionConfigName      = SolutionConfigKeyValue.Key;
                                var Configuration           = SolutionConfigKeyValue.Value.Item1;
                                var TargetConfigurationName = SolutionConfigKeyValue.Value.Item2;

                                var SolutionPlatformName = CurPlatform.ToString();

                                var SolutionConfigAndPlatformPair = SolutionConfigName + "|" + SolutionPlatformName;
                                SolutionConfigCombinations.Add(
                                    new VCSolutionConfigCombination
                                {
                                    VCSolutionConfigAndPlatformName = SolutionConfigAndPlatformPair,
                                    Configuration           = Configuration,
                                    Platform                = CurPlatform,
                                    TargetConfigurationName = TargetConfigurationName
                                }
                                    );
                            }
                        }

                        // 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)); }
                                )
                            );

                        var AppendedSolutionConfigAndPlatformNames = new HashSet <string>(StringComparer.InvariantCultureIgnoreCase);
                        foreach (var 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.Append(
                                    "		"+ SolutionConfigCombination.VCSolutionConfigAndPlatformName + " = " + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ProjectFileGenerator.NewLine);
                                AppendedSolutionConfigAndPlatformNames.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName);
                            }
                        }

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection"+ ProjectFileGenerator.NewLine);
                    }


                    // 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.Append(
                            "	GlobalSection(ProjectConfigurationPlatforms) = postSolution"+ ProjectFileGenerator.NewLine);

                        var CombinationsThatWereMatchedToProjects = new List <VCSolutionConfigCombination>();

                        foreach (MSBuildProjectFile CurProject in AllProjectFiles)
                        {
                            // NOTE: We don't emit solution configuration entries for "stub" projects.  Those projects are only
                            // built using UnrealBuildTool and don't require a presence in the solution project list

                            // NOTE: We also process projects that were "imported" here, hoping to match those to our solution
                            //       configurations.  In some cases this may not be successful though.  Imported projects
                            //       should always be carefully setup to match our project generator's solution configs.
                            if (!CurProject.IsStubProject)
                            {
                                if (CurProject.ProjectTargets.Count == 0)
                                {
                                    throw new BuildException("Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!");
                                }
                                var IsProgramProject = CurProject.ProjectTargets[0].TargetRules != null && CurProject.ProjectTargets[0].TargetRules.Type == TargetRules.TargetType.Program;

                                var GameOrProgramConfigsAlreadyMapped = new HashSet <string>();
                                foreach (var SolutionConfigCombination in SolutionConfigCombinations)
                                {
                                    // Handle aliasing of Program and Game target configuration names
                                    if ((IsProgramProject && GameOrProgramConfigsAlreadyMapped.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName)) ||
                                        IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Game.ToString() ||
                                        !IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Program.ToString())
                                    {
                                        var TargetConfigurationName = SolutionConfigCombination.TargetConfigurationName;
                                        if (IsProgramProject && TargetConfigurationName == TargetRules.TargetType.Game.ToString())
                                        {
                                            TargetConfigurationName = TargetRules.TargetType.Program.ToString();
                                        }

                                        // Now, we want to find a target in this project that maps to the current solution config combination.  Only up to one target should
                                        // and every solution config combination should map to at least one target in one project (otherwise we shouldn't have added it!).
                                        ProjectTarget MatchingProjectTarget = null;
                                        foreach (var ProjectTarget in CurProject.ProjectTargets)
                                        {
                                            bool IsMatchingCombination = VCProjectFile.IsValidProjectPlatformAndConfiguration(ProjectTarget, SolutionConfigCombination.Platform, SolutionConfigCombination.Configuration);
                                            if (ProjectTarget.TargetRules != null)
                                            {
                                                if (TargetConfigurationName != ProjectTarget.TargetRules.ConfigurationName)
                                                {
                                                    // Solution configuration name for this combination doesn't match this target's configuration name.  It's not buildable.
                                                    IsMatchingCombination = false;
                                                }
                                            }
                                            else
                                            {
                                                // UBT gets a pass because it is a dependency of every single configuration combination
                                                if (CurProject != UBTProject &&
                                                    !CurProject.ShouldBuildForAllSolutionTargets &&
                                                    TargetConfigurationName != TargetRules.TargetType.Game.ToString())
                                                {
                                                    // Can't build non-generated project in configurations except for the default (Game)
                                                    IsMatchingCombination = false;
                                                }
                                            }

                                            if (IsMatchingCombination)
                                            {
                                                if (MatchingProjectTarget != null)
                                                {
                                                    // Not expecting more than one target to match a single solution configuration per project!
                                                    throw new BuildException("Not expecting more than one target for project " + CurProject.ProjectFilePath + " to match solution configuration " + SolutionConfigCombination.VCSolutionConfigAndPlatformName);
                                                }

                                                MatchingProjectTarget = ProjectTarget;

                                                // NOTE: For faster perf, we could "break" here and bail out early, but that would circumvent the error checking
                                                //		 for multiple targets within a project that may map to a single solution configuration.
                                            }
                                        }

                                        var SolutionConfiguration = SolutionConfigCombination.Configuration;
                                        var SolutionPlatform      = SolutionConfigCombination.Platform;


                                        if (MatchingProjectTarget == null)
                                        {
                                            // The current configuration/platform and target configuration name doesn't map to anything our project actually supports.
                                            // We'll map it to a default config.
                                            SolutionConfiguration = UnrealTargetConfiguration.Development;

                                            // Prefer using Win64 as the default, but fall back to a platform the project file actually supports if needed.  This is for
                                            // projects that can never be compiled in Windows, such as UnrealLaunchDaemon which is an iOS-only program
                                            SolutionPlatform = UnrealTargetPlatform.Win64;
                                            if (CurProject.ProjectTargets[0].TargetRules != null)
                                            {
                                                var ProjectSupportedPlatforms = new List <UnrealTargetPlatform>();
                                                CurProject.ProjectTargets[0].TargetRules.GetSupportedPlatforms(ref ProjectSupportedPlatforms);
                                                if (!ProjectSupportedPlatforms.Contains(SolutionPlatform))
                                                {
                                                    SolutionPlatform = ProjectSupportedPlatforms[0];
                                                }
                                            }


                                            if (IsProgramProject)
                                            {
                                                TargetConfigurationName = TargetRules.TargetType.Program.ToString();
                                            }
                                            else
                                            {
                                                TargetConfigurationName = TargetRules.TargetType.Game.ToString();
                                            }
                                        }


                                        // If the project wants to always build in "Development", regardless of what the solution
                                        // configuration is set to, then we'll do that here.  This is used for projects like
                                        // UnrealBuildTool and ShaderCompileWorker
                                        if (MatchingProjectTarget != null)
                                        {
                                            if (MatchingProjectTarget.ForceDevelopmentConfiguration)
                                            {
                                                SolutionConfiguration = UnrealTargetConfiguration.Development;
                                            }
                                        }


                                        string ProjectConfigName;
                                        string ProjectPlatformName;
                                        CurProject.MakeProjectPlatformAndConfigurationNames(SolutionPlatform, SolutionConfiguration, TargetConfigurationName, out ProjectPlatformName, out ProjectConfigName);

                                        var ProjectConfigAndPlatformPair = ProjectConfigName.ToString() + "|" + ProjectPlatformName.ToString();

                                        // e.g.  "{4232C52C-680F-4850-8855-DC39419B5E9B}.Debug|iOS.ActiveCfg = iOS_Debug|Win32"
                                        var CurProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant();
                                        VCSolutionFileContent.Append(
                                            "		"+ CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".ActiveCfg = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);


                                        // Set whether this project configuration should be built when the user initiates "build solution"
                                        if (MatchingProjectTarget != null && CurProject.ShouldBuildByDefaultForSolutionTargets)
                                        {
                                            VCSolutionFileContent.Append(
                                                "		"+ CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Build.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);

                                            var ProjGen = UEPlatformProjectGenerator.GetPlatformProjectGenerator(SolutionConfigCombination.Platform, true);
                                            if (MatchingProjectTarget.ProjectDeploys ||
                                                ((ProjGen != null) && (ProjGen.GetVisualStudioDeploymentEnabled(SolutionPlatform, SolutionConfiguration) == true)))
                                            {
                                                VCSolutionFileContent.Append(
                                                    "		"+ CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Deploy.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);
                                            }
                                        }

                                        CombinationsThatWereMatchedToProjects.Add(SolutionConfigCombination);
                                    }
                                }
                            }
                        }

                        // Check for problems
                        foreach (var SolutionConfigCombination in SolutionConfigCombinations)
                        {
                            if (!CombinationsThatWereMatchedToProjects.Contains(SolutionConfigCombination))
                            {
                                throw new BuildException("Unable to find a ProjectTarget that matches the solution configuration/platform mapping: " + SolutionConfigCombination.Configuration.ToString() + ", " + SolutionConfigCombination.Platform.ToString() + ", " + SolutionConfigCombination.TargetConfigurationName);
                            }
                        }
                        VCSolutionFileContent.Append(
                            "	EndGlobalSection"+ ProjectFileGenerator.NewLine);
                    }


                    // Setup other solution properties
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(SolutionProperties) = preSolution"+ ProjectFileGenerator.NewLine);

                        // 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.Append(
                            "		HideSolutionNode = FALSE"+ ProjectFileGenerator.NewLine);

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection"+ ProjectFileGenerator.NewLine);
                    }



                    // Solution directory hierarchy
                    {
                        VCSolutionFileContent.Append(
                            "	GlobalSection(NestedProjects) = preSolution"+ ProjectFileGenerator.NewLine);

                        // 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)
                            {
                                var 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.Append(
                                        "		"+ ChildProject.ProjectGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine);
                                }

                                foreach (VisualStudioSolutionFolder SubFolder in CurFolder.SubFolders)
                                {
                                    //	e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}"
                                    LocalVCSolutionFileContent.Append(
                                        "		"+ SubFolder.FolderGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine);
                                }

                                // Recurse into subfolders
                                FolderProcessorFunction(LocalVCSolutionFileContent, CurFolder.SubFolders);
                            }
                        };
                        FolderProcessorFunction(VCSolutionFileContent, RootFolder.SubFolders);

                        VCSolutionFileContent.Append(
                            "	EndGlobalSection"+ ProjectFileGenerator.NewLine);
                    }
                }

                VCSolutionFileContent.Append(
                    "EndGlobal" + ProjectFileGenerator.NewLine);
            }


            // Save the solution file
            if (bSuccess)
            {
                var SolutionFilePath = Path.Combine(MasterProjectRelativePath, SolutionFileName);
                bSuccess = WriteFileIfChanged(SolutionFilePath, VCSolutionFileContent.ToString());
            }


            // Save a solution config file which selects the development editor configuration by default.
            if (bSuccess)
            {
                // Figure out the filename for the SUO file. VS2013 will automatically import the VS2012 options if necessary.
                string SolutionOptionsExtension = (ProjectFileFormat == VCProjectFileFormat.VisualStudio2012)? "v11.suo" : "v12.suo";

                // Check it doesn't exist before overwriting it. Since these files store the user's preferences, it'd be bad form to overwrite them.
                string SolutionOptionsFileName = Path.Combine(MasterProjectRelativePath, Path.ChangeExtension(SolutionFileName, SolutionOptionsExtension));
                if (!File.Exists(SolutionOptionsFileName))
                {
                    VCSolutionOptions Options = new VCSolutionOptions();

                    // Set the default configuration and startup project
                    VCSolutionConfigCombination DefaultConfig = SolutionConfigCombinations.Find(x => x.Configuration == UnrealTargetConfiguration.Development && x.Platform == UnrealTargetPlatform.Win64 && x.TargetConfigurationName == "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();
                    foreach (ProjectFile ProjectFile in AllProjectFiles)
                    {
                        string ProjectName = Path.GetFileNameWithoutExtension(ProjectFile.ProjectFilePath);
                        if (ProjectFile == DefaultProject)
                        {
                            ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectName, new string[] { ProjectName }));
                        }
                        else
                        {
                            ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectName, new string[] { }));
                        }
                    }
                    if (IncludeEnginePrograms)
                    {
                        ExplorerState.OpenProjects.Add(new Tuple <string, string[]>("Automation", new string[0]));
                    }
                    Options.SetExplorerState(ExplorerState);

                    // Write the file
                    if (Options.Sections.Count > 0)
                    {
                        Options.Write(SolutionOptionsFileName);
                    }
                }
            }

            return(bSuccess);
        }
Example #23
0
 static void BuildSolutionExplorerState_VS2015(List <ProjectFile> AllProjectFiles, VCSolutionExplorerState ExplorerState, ProjectFile DefaultProject, bool IncludeEnginePrograms)
 {
     foreach (ProjectFile ProjectFile in AllProjectFiles)
     {
         string ProjectName = ProjectFile.ProjectFilePath.GetFileNameWithoutExtension();
         if (ProjectFile == DefaultProject)
         {
             ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectName, new string[] { ProjectName }));
         }
         else
         {
             ExplorerState.OpenProjects.Add(new Tuple <string, string[]>(ProjectName, new string[] { }));
         }
     }
     if (IncludeEnginePrograms)
     {
         ExplorerState.OpenProjects.Add(new Tuple <string, string[]>("Automation", new string[0]));
     }
 }
Example #24
0
 /// <summary>
 /// Writes the master project file (e.g. Visual Studio Solution file)
 /// </summary>
 /// <param name="UBTProject">The UnrealBuildTool project</param>
 /// <returns>True if successful</returns>
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
 {
     return(true);
 }
		/// <summary>
		/// Creates project entries for all known targets (*.Target.cs files)
		/// </summary>
		/// <param name="AllGameFolders">All game folders</param>
		/// <param name="EngineProject">The engine project we created</param>
		/// <param name="GameProjects">Map of game folder name to all of the game projects we created</param>
		/// <param name="ProgramProjects">Map of program names to all of the program projects we created</param>
		/// <param name="TemplateGameProjects">Set of template game projects we found.  These will also be in the GameProjects map</param>
		private void AddProjectsForAllTargets( List<UProjectInfo> AllGames, out ProjectFile EngineProject, out Dictionary<DirectoryReference, ProjectFile> GameProjects, out Dictionary<string, ProjectFile> ProgramProjects, out HashSet<ProjectFile> TemplateGameProjects )
		{
			// 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 Dictionary<DirectoryReference,ProjectFile>();
			ProgramProjects = new Dictionary<string,ProjectFile>( StringComparer.InvariantCultureIgnoreCase );
			TemplateGameProjects = new HashSet<ProjectFile>();

			// Get some standard directories
			DirectoryReference EngineSourceProgramsDirectory = DirectoryReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Programs");
			DirectoryReference TemplatesDirectory = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "..", "Templates");

			// 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);
			foreach( FileReference TargetFilePath in AllTargetFiles )
			{
				string TargetName = TargetFilePath.GetFileNameWithoutAnyExtensions();		// Remove both ".cs" and ".Target"

				// Check to see if this is an Engine target.  That is, the target is located under the "Engine" folder
				bool IsEngineTarget = 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 = IncludeEngineSource;
					}
				}

				if (WantProjectFileForTarget)
				{
					RulesAssembly RulesAssembly;

					FileReference CheckProjectFile;
					if(!UProjectInfo.TryGetProjectForTarget(TargetName, out CheckProjectFile))
					{
						RulesAssembly = RulesCompiler.CreateEngineRulesAssembly();
					}
					else
					{
						RulesAssembly = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile);
					}

					// 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, new TargetInfo(BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development, ""), false);

					bool IsProgramTarget = false;

					DirectoryReference GameFolder = null;
					string ProjectFileNameBase = null;
					if (TargetRulesObject.Type == TargetRules.TargetType.Program)
					{
						IsProgramTarget = true;
						ProjectFileNameBase = TargetName;
					}
					else if (IsEngineTarget)
					{
						ProjectFileNameBase = EngineProjectFileNameBase;
					}
					else
					{
						// Figure out which game project this target belongs to
						UProjectInfo 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.Folder;
						ProjectFileNameBase = ProjectInfo.GameName;
					}

					// @todo projectfiles: We should move all of the Target.cs files out of sub-folders to clean up the project directories a bit (e.g. GameUncooked folder)

					FileReference ProjectFilePath = FileReference.Combine(IntermediateProjectFilesPath, ProjectFileNameBase + ProjectFileExtension);

					if (TargetRules.IsGameType(TargetRulesObject.Type) &&
						(TargetRules.IsEditorType(TargetRulesObject.Type) == false))
					{
						// Allow platforms to generate stub projects here...
						UEPlatformProjectGenerator.GenerateGameProjectStubs(
							InGenerator: this,
							InTargetName: TargetName,
							InTargetFilepath: TargetFilePath.FullName,
							InTargetRules: TargetRulesObject,
							InPlatforms: SupportedPlatforms,
							InConfigurations: SupportedConfigurations);
					}

					bool bProjectAlreadyExisted;
					ProjectFile ProjectFile = FindOrAddProject(ProjectFilePath, IncludeInGeneratedProjects: true, bAlreadyExisted: out bProjectAlreadyExisted);
					ProjectFile.IsForeignProject = bGeneratingGameProjectFiles && OnlyGameProject != null && TargetFilePath.IsUnderDirectory(OnlyGameProject.Directory);
					ProjectFile.IsGeneratedProject = true;
					ProjectFile.IsStubProject = false;

					// Check to see if this is a template target.  That is, the target is located under the "Templates" folder
					bool IsTemplateTarget = TargetFilePath.IsUnderDirectory(TemplatesDirectory);

					DirectoryReference BaseFolder = null;
					if (IsProgramTarget)
					{
						ProgramProjects[TargetName] = ProjectFile;
						BaseFolder = TargetFilePath.Directory;
					}
					else if (IsEngineTarget)
					{
						EngineProject = ProjectFile;
						BaseFolder = UnrealBuildTool.EngineDirectory;
						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
					{
						GameProjects[GameFolder] = ProjectFile;
						if (IsTemplateTarget)
						{
							TemplateGameProjects.Add(ProjectFile);
						}
						BaseFolder = GameFolder;

						if (!bProjectAlreadyExisted)
						{
							// Add the .uproject file for this game/template
							FileReference UProjectFilePath = FileReference.Combine(BaseFolder, ProjectFileNameBase + ".uproject");
							if (UProjectFilePath.Exists())
							{
								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.ConfigurationName.Equals(TargetRulesObject.ConfigurationName, StringComparison.InvariantCultureIgnoreCase))
						{
							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.ConfigurationName, 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 == TargetRules.TargetType.Game && ExistingProjectTarget.TargetRules.Type == TargetRules.TargetType.Program ||
							ExistingProjectTarget.TargetRules.Type == TargetRules.TargetType.Program && ExistingProjectTarget.TargetRules.Type == TargetRules.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
                        };

                    if (TargetName == "UnrealCodeAnalyzer")
                    {
                        ProjectFile.ShouldBuildByDefaultForSolutionTargets = false;
                    }

					if (TargetName == "ShaderCompileWorker")		// @todo projectfiles: Ideally, the target rules file should set this
					{
						ProjectTarget.ForceDevelopmentConfiguration = true;
					}

					ProjectFile.ProjectTargets.Add(ProjectTarget);

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


					// We special case ShaderCompileWorker.  It needs to always be compiled in Development mode.
					Log.TraceVerbose("Generating target {0} for {1}", TargetRulesObject.Type.ToString(), ProjectFilePath);
				}
			}
		}
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject, PlatformProjectGeneratorCollection PlatformProjectGenerators)
 {
     return(WriteXcodeWorkspace());
 }
		/// Adds shader source code to the specified project
		protected void AddEngineShaderSource( ProjectFile EngineProject )
		{
			// Setup a project file entry for this module's project.  Remember, some projects may host multiple modules!
			DirectoryReference ShadersDirectory = DirectoryReference.Combine( UnrealBuildTool.EngineDirectory, "Shaders" );

			List<string> SubdirectoryNamesToExclude = new List<string>();
			{
                // Don't include binary shaders in the project file.
                SubdirectoryNamesToExclude.Add( "Binaries" );
				// We never want shader intermediate files in our project file
				SubdirectoryNamesToExclude.Add( "PDBDump" );
				SubdirectoryNamesToExclude.Add( "WorkingDirectory" );
			}

			EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( ShadersDirectory, SubdirectoryNamesToExclude ), UnrealBuildTool.EngineDirectory );
		}
        /// <summary>
        /// Adds UnrealBuildTool to the master project
        /// </summary>
        private void AddUnrealBuildToolProject( MasterProjectFolder ProgramsFolder )
        {
            var ProjectFileName = Utils.MakePathRelativeTo( Path.Combine( Path.Combine( EngineRelativePath, "Source" ), "Programs", "UnrealBuildTool", "UnrealBuildTool.csproj" ), MasterProjectRelativePath );
            var UnrealBuildToolProject = new VCSharpProjectFile( ProjectFileName );

            // Store it off as we need it when generating target projects.
            UBTProject = UnrealBuildToolProject;

            // Add the project
            AddExistingProjectFile(UnrealBuildToolProject, bNeedsAllPlatformAndConfigurations:true, bForceDevelopmentConfiguration:true);

            // Put this in a solution folder
            ProgramsFolder.ChildProjects.Add( UnrealBuildToolProject );
        }
		/// Adds engine build infrastructure files to the specified project
		protected void AddEngineBuildFiles( ProjectFile EngineProject )
		{
			DirectoryReference BuildDirectory = DirectoryReference.Combine( UnrealBuildTool.EngineDirectory, "Build" );

			List<string> SubdirectoryNamesToExclude = new List<string>();
			SubdirectoryNamesToExclude.Add("Receipts");

			EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( BuildDirectory, SubdirectoryNamesToExclude ), UnrealBuildTool.EngineDirectory );
		}
Example #30
0
 protected override bool WriteMasterProjectFile( ProjectFile UBTProject )
 {
     bool bSuccess = true;
     return bSuccess;
 }
		/// Adds all engine localization text files to the specified project
		private void AddEngineLocalizationFiles( ProjectFile EngineProject )
		{
			DirectoryReference EngineLocalizationDirectory = DirectoryReference.Combine( UnrealBuildTool.EngineDirectory, "Content", "Localization" );
			if( EngineLocalizationDirectory.Exists( ) )
			{
				EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( EngineLocalizationDirectory ), UnrealBuildTool.EngineDirectory );
			}
		}
		protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
		{
			bool bSuccess = true;

			string SolutionFileName = MasterProjectName + ".sln";

			// Setup solution file content
			StringBuilder VCSolutionFileContent = new StringBuilder();

			const string VersionTag = "# UnrealEngineGeneratedSolutionVersion=1.0";

			// Solution file header
			if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2017)
			{
				VCSolutionFileContent.Append(
					ProjectFileGenerator.NewLine +
					"Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
					"# Visual Studio 15" + ProjectFileGenerator.NewLine +
					"VisualStudioVersion = 15.0.25618.0" + ProjectFileGenerator.NewLine +
					"MinimumVisualStudioVersion = 10.0.40219.1" + ProjectFileGenerator.NewLine);
			}
			else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2015)
			{
				VCSolutionFileContent.Append(
					ProjectFileGenerator.NewLine +
					"Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
					"# Visual Studio 14" + ProjectFileGenerator.NewLine +
					"VisualStudioVersion = 14.0.22310.1" + ProjectFileGenerator.NewLine +
					"MinimumVisualStudioVersion = 10.0.40219.1" + ProjectFileGenerator.NewLine);
			}
			else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2013)
			{
				VCSolutionFileContent.Append(
					ProjectFileGenerator.NewLine +
					"Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
					"# Visual Studio 2013" + ProjectFileGenerator.NewLine +
					VersionTag + ProjectFileGenerator.NewLine);
            }
            else if (ProjectFileFormat == VCProjectFileFormat.VisualStudio2012)
            {
                VCSolutionFileContent.Append(
                    ProjectFileGenerator.NewLine +
                    "Microsoft Visual Studio Solution File, Format Version 12.00" + ProjectFileGenerator.NewLine +
                    "# Visual Studio 2012" + ProjectFileGenerator.NewLine +
                    VersionTag + ProjectFileGenerator.NewLine);
            }
			else
			{
				throw new BuildException("Unexpected ProjectFileFormat");
			}

			// Find the projects for ShaderCompileWorker and UnrealLightmass
			ProjectFile ShaderCompileWorkerProject = null;
			ProjectFile UnrealLightmassProject = null;
			foreach (ProjectFile Project in AllProjectFiles)
			{
				if (Project.ProjectTargets.Count == 1)
				{
					FileReference TargetFilePath = Project.ProjectTargets[0].TargetFilePath;
					if (TargetFilePath != null)
					{
						string TargetFileName = TargetFilePath.GetFileNameWithoutAnyExtensions();
						if (TargetFileName.Equals("ShaderCompileWorker", StringComparison.InvariantCultureIgnoreCase))
						{
							ShaderCompileWorkerProject = Project;
						}
						else if (TargetFileName.Equals("UnrealLightmass", StringComparison.InvariantCultureIgnoreCase))
						{
							UnrealLightmassProject = Project;
						}
					}
					if (ShaderCompileWorkerProject != null
						&& UnrealLightmassProject != null)
					{
						break;
					}
				}
			}

			// 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);

					foreach (VisualStudioSolutionFolder CurFolder in AllSolutionFolders)
					{
						string FolderGUIDString = CurFolder.FolderGUID.ToString("B").ToUpperInvariant();
						VCSolutionFileContent.Append(
								"Project(\"" + SolutionFolderEntryGUID + "\") = \"" + CurFolder.FolderName + "\", \"" + CurFolder.FolderName + "\", \"" + FolderGUIDString + "\"" + ProjectFileGenerator.NewLine);

						// Add any files that are inlined right inside the solution folder
						if (CurFolder.Files.Count > 0)
						{
							VCSolutionFileContent.Append(
									"	ProjectSection(SolutionItems) = preProject" + ProjectFileGenerator.NewLine);
							foreach (string CurFile in CurFolder.Files)
							{
								// Syntax is:  <relative file path> = <relative file path>
								VCSolutionFileContent.Append(
									"		" + CurFile + " = " + CurFile + ProjectFileGenerator.NewLine);
							}
							VCSolutionFileContent.Append(
									"	EndProjectSection" + ProjectFileGenerator.NewLine);
						}

						VCSolutionFileContent.Append(
								"EndProject" + ProjectFileGenerator.NewLine
							);
					}
				}


				// Project files
				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.Append(
							"Project(\"" + ProjectTypeGUID + "\") = \"" + ProjectNameInSolution + "\", \"" + CurProject.ProjectFilePath.MakeRelativeTo(ProjectFileGenerator.MasterProjectPath) + "\", \"" + ProjectGUID + "\"" + ProjectFileGenerator.NewLine);

					// 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);
						}
						if (UEBuildConfiguration.bEditorDependsOnShaderCompileWorker && CurProject.IsGeneratedProject && ShaderCompileWorkerProject != null && CurProject.ProjectTargets.Any(x => x.TargetRules != null && x.TargetRules.Type == TargetRules.TargetType.Editor))
						{
							Dependencies.Add(ShaderCompileWorkerProject);
						}
						Dependencies.AddRange(CurProject.DependsOnProjects);

						if (Dependencies.Count > 0)
						{
							VCSolutionFileContent.Append("\tProjectSection(ProjectDependencies) = postProject" + ProjectFileGenerator.NewLine);

							// Setup any addition dependencies this project has...
							foreach (ProjectFile DependsOnProject in Dependencies)
							{
								string DependsOnProjectGUID = ((MSBuildProjectFile)DependsOnProject).ProjectGUID.ToString("B").ToUpperInvariant();
								VCSolutionFileContent.Append("\t\t" + DependsOnProjectGUID + " = " + DependsOnProjectGUID + ProjectFileGenerator.NewLine);
							}

							VCSolutionFileContent.Append("\tEndProjectSection" + ProjectFileGenerator.NewLine);
						}
					}

					VCSolutionFileContent.Append(
							"EndProject" + ProjectFileGenerator.NewLine
						);
				}
			}

			// 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.Append(
					"Global" + ProjectFileGenerator.NewLine);
				{
					{
						VCSolutionFileContent.Append(
							"	GlobalSection(SolutionConfigurationPlatforms) = preSolution" + ProjectFileGenerator.NewLine);

						Dictionary<string, Tuple<UnrealTargetConfiguration, string>> SolutionConfigurationsValidForProjects = new Dictionary<string, Tuple<UnrealTargetConfiguration, string>>();
						HashSet<UnrealTargetPlatform> PlatformsValidForProjects = new HashSet<UnrealTargetPlatform>();

						foreach (UnrealTargetConfiguration CurConfiguration in SupportedConfigurations)
						{
							if (UnrealBuildTool.IsValidConfiguration(CurConfiguration))
							{
								foreach (UnrealTargetPlatform CurPlatform in SupportedPlatforms)
								{
									if (UnrealBuildTool.IsValidPlatform(CurPlatform))
									{
										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))
													{
														PlatformsValidForProjects.Add(CurPlatform);

														// Default to a target configuration name of "Game", since that will collapse down to an empty string
														string TargetConfigurationName = TargetRules.TargetType.Game.ToString();
														if (ProjectTarget.TargetRules != null)
														{
															TargetConfigurationName = ProjectTarget.TargetRules.ConfigurationName;
														}

														string SolutionConfigName = MakeSolutionConfigurationName(CurConfiguration, TargetConfigurationName);
														SolutionConfigurationsValidForProjects[SolutionConfigName] = new Tuple<UnrealTargetConfiguration, string>(CurConfiguration, TargetConfigurationName);
													}
												}
											}
										}
									}
								}
							}
						}

						foreach (UnrealTargetPlatform CurPlatform in PlatformsValidForProjects)
						{
							foreach (KeyValuePair<string, Tuple<UnrealTargetConfiguration, string>> SolutionConfigKeyValue in SolutionConfigurationsValidForProjects)
							{
								// e.g.  "Development|Win64 = Development|Win64"
								string SolutionConfigName = SolutionConfigKeyValue.Key;
								UnrealTargetConfiguration Configuration = SolutionConfigKeyValue.Value.Item1;
								string TargetConfigurationName = SolutionConfigKeyValue.Value.Item2;

								string SolutionPlatformName = CurPlatform.ToString();

								string SolutionConfigAndPlatformPair = SolutionConfigName + "|" + SolutionPlatformName;
								SolutionConfigCombinations.Add(
										new VCSolutionConfigCombination
										{
											VCSolutionConfigAndPlatformName = SolutionConfigAndPlatformPair,
											Configuration = Configuration,
											Platform = CurPlatform,
											TargetConfigurationName = TargetConfigurationName
										}
									);
							}
						}

						// 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.Append(
									"		" + SolutionConfigCombination.VCSolutionConfigAndPlatformName + " = " + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ProjectFileGenerator.NewLine);
								AppendedSolutionConfigAndPlatformNames.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName);
							}
						}

						VCSolutionFileContent.Append(
							"	EndGlobalSection" + ProjectFileGenerator.NewLine);
					}


					// 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.Append(
							"	GlobalSection(ProjectConfigurationPlatforms) = postSolution" + ProjectFileGenerator.NewLine);

						List<VCSolutionConfigCombination> CombinationsThatWereMatchedToProjects = new List<VCSolutionConfigCombination>();

						foreach (MSBuildProjectFile CurProject in AllProjectFiles)
						{
							// NOTE: We don't emit solution configuration entries for "stub" projects.  Those projects are only
							// built using UnrealBuildTool and don't require a presence in the solution project list

							// NOTE: We also process projects that were "imported" here, hoping to match those to our solution
							//       configurations.  In some cases this may not be successful though.  Imported projects
							//       should always be carefully setup to match our project generator's solution configs.
							if (!CurProject.IsStubProject)
							{
								if (CurProject.ProjectTargets.Count == 0)
								{
									throw new BuildException("Expecting project '" + CurProject.ProjectFilePath + "' to have at least one ProjectTarget associated with it!");
								}
								bool IsProgramProject = CurProject.ProjectTargets[0].TargetRules != null && CurProject.ProjectTargets[0].TargetRules.Type == TargetRules.TargetType.Program;

								HashSet<string> GameOrProgramConfigsAlreadyMapped = new HashSet<string>();
								foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations)
								{
									// Handle aliasing of Program and Game target configuration names
									if ((IsProgramProject && GameOrProgramConfigsAlreadyMapped.Add(SolutionConfigCombination.VCSolutionConfigAndPlatformName)) ||
										IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Game.ToString() ||
										!IsProgramProject && SolutionConfigCombination.TargetConfigurationName != TargetRules.TargetType.Program.ToString())
									{
										string TargetConfigurationName = SolutionConfigCombination.TargetConfigurationName;
										if (IsProgramProject)
										{
											TargetConfigurationName = TargetRules.TargetType.Program.ToString();
										}

										// Now, we want to find a target in this project that maps to the current solution config combination.  Only up to one target should
										// and every solution config combination should map to at least one target in one project (otherwise we shouldn't have added it!).
										ProjectTarget MatchingProjectTarget = null;
										foreach (ProjectTarget ProjectTarget in CurProject.ProjectTargets)
										{
											bool IsMatchingCombination = VCProjectFile.IsValidProjectPlatformAndConfiguration(ProjectTarget, SolutionConfigCombination.Platform, SolutionConfigCombination.Configuration);
											if (ProjectTarget.TargetRules != null)
											{
												if (TargetConfigurationName != ProjectTarget.TargetRules.ConfigurationName)
												{
													// Solution configuration name for this combination doesn't match this target's configuration name.  It's not buildable.
													IsMatchingCombination = false;
												}
											}
											else
											{
												// UBT gets a pass because it is a dependency of every single configuration combination
												if (CurProject != UBTProject &&
													!CurProject.ShouldBuildForAllSolutionTargets &&
													TargetConfigurationName != TargetRules.TargetType.Game.ToString())
												{
													// Can't build non-generated project in configurations except for the default (Game)
													IsMatchingCombination = false;
												}
											}

											if (IsMatchingCombination)
											{
												if (MatchingProjectTarget != null)
												{
													// Not expecting more than one target to match a single solution configuration per project!
													throw new BuildException("Not expecting more than one target for project " + CurProject.ProjectFilePath + " to match solution configuration " + SolutionConfigCombination.VCSolutionConfigAndPlatformName);
												}

												MatchingProjectTarget = ProjectTarget;

												// NOTE: For faster perf, we could "break" here and bail out early, but that would circumvent the error checking
												//		 for multiple targets within a project that may map to a single solution configuration.
											}
										}

										UnrealTargetConfiguration SolutionConfiguration = SolutionConfigCombination.Configuration;
										UnrealTargetPlatform SolutionPlatform = SolutionConfigCombination.Platform;


										if (MatchingProjectTarget == null)
										{
											// The current configuration/platform and target configuration name doesn't map to anything our project actually supports.
											// We'll map it to a default config.
											SolutionConfiguration = UnrealTargetConfiguration.Development;

											// Prefer using Win64 as the default, but fall back to a platform the project file actually supports if needed.  This is for
											// projects that can never be compiled in Windows, such as UnrealLaunchDaemon which is an iOS-only program
											SolutionPlatform = UnrealTargetPlatform.Win64;
											if (CurProject.ProjectTargets[0].TargetRules != null)
											{
												List<UnrealTargetPlatform> ProjectSupportedPlatforms = new List<UnrealTargetPlatform>();
												CurProject.ProjectTargets[0].TargetRules.GetSupportedPlatforms(ref ProjectSupportedPlatforms);
												if (!ProjectSupportedPlatforms.Contains(SolutionPlatform))
												{
													SolutionPlatform = ProjectSupportedPlatforms[0];
												}
											}


											if (IsProgramProject)
											{
												TargetConfigurationName = TargetRules.TargetType.Program.ToString();
											}
											else
											{
												TargetConfigurationName = TargetRules.TargetType.Game.ToString();
											}
										}


										// If the project wants to always build in "Development", regardless of what the solution
										// configuration is set to, then we'll do that here.  This is used for projects like
										// UnrealBuildTool and ShaderCompileWorker
										if (MatchingProjectTarget != null)
										{
											if (MatchingProjectTarget.ForceDevelopmentConfiguration)
											{
												SolutionConfiguration = UnrealTargetConfiguration.Development;
											}
										}

										// Always allow SCW and UnrealLighmass to build in editor configurations
										if (MatchingProjectTarget == null && SolutionConfigCombination.TargetConfigurationName == TargetRules.TargetType.Editor.ToString() && SolutionConfigCombination.Platform == UnrealTargetPlatform.Win64)
										{
											if (CurProject == ShaderCompileWorkerProject)
											{
												MatchingProjectTarget = ShaderCompileWorkerProject.ProjectTargets[0];
											}
											else if (CurProject == UnrealLightmassProject)
											{
												MatchingProjectTarget = UnrealLightmassProject.ProjectTargets[0];
											}
										}

										string ProjectConfigName;
										string ProjectPlatformName;
										CurProject.MakeProjectPlatformAndConfigurationNames(SolutionPlatform, SolutionConfiguration, TargetConfigurationName, out ProjectPlatformName, out ProjectConfigName);

										string ProjectConfigAndPlatformPair = ProjectConfigName.ToString() + "|" + ProjectPlatformName.ToString();

										// e.g.  "{4232C52C-680F-4850-8855-DC39419B5E9B}.Debug|iOS.ActiveCfg = iOS_Debug|Win32"
										string CurProjectGUID = CurProject.ProjectGUID.ToString("B").ToUpperInvariant();
										VCSolutionFileContent.Append(
											"		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".ActiveCfg = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);


										// Set whether this project configuration should be built when the user initiates "build solution"
										if (MatchingProjectTarget != null && CurProject.ShouldBuildByDefaultForSolutionTargets)
										{
											// Some targets are "dummy targets"; they only exist to show user friendly errors in VS. Weed them out here, and don't set them to build by default.
											List<UnrealTargetPlatform> SupportedPlatforms = null;
											if (MatchingProjectTarget.TargetRules != null)
											{
												SupportedPlatforms = new List<UnrealTargetPlatform>();
												MatchingProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms);
											}
											if (SupportedPlatforms == null || SupportedPlatforms.Contains(SolutionConfigCombination.Platform))
											{
												VCSolutionFileContent.Append(
														"		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Build.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);

												UEPlatformProjectGenerator ProjGen = UEPlatformProjectGenerator.GetPlatformProjectGenerator(SolutionConfigCombination.Platform, true);
												if (MatchingProjectTarget.ProjectDeploys ||
													((ProjGen != null) && (ProjGen.GetVisualStudioDeploymentEnabled(SolutionPlatform, SolutionConfiguration) == true)))
												{
													VCSolutionFileContent.Append(
															"		" + CurProjectGUID + "." + SolutionConfigCombination.VCSolutionConfigAndPlatformName + ".Deploy.0 = " + ProjectConfigAndPlatformPair + ProjectFileGenerator.NewLine);
												}
											}
										}

										CombinationsThatWereMatchedToProjects.Add(SolutionConfigCombination);
									}
								}
							}
						}

						// Check for problems
						foreach (VCSolutionConfigCombination SolutionConfigCombination in SolutionConfigCombinations)
						{
							if (!CombinationsThatWereMatchedToProjects.Contains(SolutionConfigCombination))
							{
								throw new BuildException("Unable to find a ProjectTarget that matches the solution configuration/platform mapping: " + SolutionConfigCombination.Configuration.ToString() + ", " + SolutionConfigCombination.Platform.ToString() + ", " + SolutionConfigCombination.TargetConfigurationName);
							}
						}
						VCSolutionFileContent.Append(
							"	EndGlobalSection" + ProjectFileGenerator.NewLine);
					}


					// Setup other solution properties
					{
						VCSolutionFileContent.Append(
							"	GlobalSection(SolutionProperties) = preSolution" + ProjectFileGenerator.NewLine);

						// 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.Append(
							"		HideSolutionNode = FALSE" + ProjectFileGenerator.NewLine);

						VCSolutionFileContent.Append(
							"	EndGlobalSection" + ProjectFileGenerator.NewLine);
					}



					// Solution directory hierarchy
					{
						VCSolutionFileContent.Append(
							"	GlobalSection(NestedProjects) = preSolution" + ProjectFileGenerator.NewLine);

						// 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.Append(
											"		" + ChildProject.ProjectGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine);
									}

									foreach (VisualStudioSolutionFolder SubFolder in CurFolder.SubFolders)
									{
										//	e.g. "{BF6FB09F-A2A6-468F-BE6F-DEBE07EAD3EA} = {C43B6BB5-3EF0-4784-B896-4099753BCDA9}"
										LocalVCSolutionFileContent.Append(
											"		" + SubFolder.FolderGUID.ToString("B").ToUpperInvariant() + " = " + CurFolderGUIDString + ProjectFileGenerator.NewLine);
									}

									// Recurse into subfolders
									FolderProcessorFunction(LocalVCSolutionFileContent, CurFolder.SubFolders);
								}
							};
						FolderProcessorFunction(VCSolutionFileContent, RootFolder.SubFolders);

						VCSolutionFileContent.Append(
							"	EndGlobalSection" + ProjectFileGenerator.NewLine);
					}
				}

				VCSolutionFileContent.Append(
					"EndGlobal" + ProjectFileGenerator.NewLine);
			}


			// 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)
			{
				// 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;
					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 (!SolutionOptionsFileName.Exists())
				{
					SolutionOptionsFileName.Directory.CreateDirectory();

					VCSolutionOptions Options = new VCSolutionOptions();

					// Set the default configuration and startup project
					VCSolutionConfigCombination DefaultConfig = SolutionConfigCombinations.Find(x => x.Configuration == UnrealTargetConfiguration.Development && x.Platform == UnrealTargetPlatform.Win64 && x.TargetConfigurationName == "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();
					foreach (ProjectFile ProjectFile in AllProjectFiles)
					{
						string ProjectName = ProjectFile.ProjectFilePath.GetFileNameWithoutExtension();
						if (ProjectFile == DefaultProject)
						{
							ExplorerState.OpenProjects.Add(new Tuple<string, string[]>(ProjectName, new string[] { ProjectName }));
						}
						else
						{
							ExplorerState.OpenProjects.Add(new Tuple<string, string[]>(ProjectName, new string[] { }));
						}
					}
					if (IncludeEnginePrograms)
					{
						ExplorerState.OpenProjects.Add(new Tuple<string, string[]>("Automation", new string[0]));
					}
					Options.SetExplorerState(ExplorerState);

					// Write the file
					if (Options.Sections.Count > 0)
					{
						Options.Write(SolutionOptionsFileName.FullName);
					}
				}
			}

			return bSuccess;
		}
        /// Adds all engine template text files to the specified project
        private void AddEngineTemplateFiles( ProjectFile EngineProject )
        {
            DirectoryReference EngineTemplateDirectory = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Content", "Editor", "Templates");
            if (EngineTemplateDirectory.Exists())
            {
				EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( EngineTemplateDirectory ), UnrealBuildTool.EngineDirectory );
			}
        }
Example #34
0
 /// Adds all engine template text files to the specified project
 private void AddEngineTemplateFiles( ProjectFile EngineProject )
 {
     var EngineTemplateDirectory = Path.Combine(EngineRelativePath, "Content", "Editor", "Templates");
     if (Directory.Exists(EngineTemplateDirectory))
     {
         var DirectoriesToSearch = new List<string>();
         DirectoriesToSearch.Add( EngineTemplateDirectory );
         EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( DirectoriesToSearch, ExcludeNoRedistFiles:bExcludeNoRedistFiles), EngineRelativePath );
     }
 }
		/// Adds all engine config files to the specified project
		private void AddEngineConfigFiles( ProjectFile EngineProject )
		{
            DirectoryReference EngineConfigDirectory = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Config" );
			if( EngineConfigDirectory.Exists( ) )
			{
				EngineProject.AddFilesToProject( SourceFileSearch.FindFiles( EngineConfigDirectory ), UnrealBuildTool.EngineDirectory );
			}
		}
Example #36
0
        /// <summary>
        /// Adds detected UBT configuration files (BuildConfiguration.xml) to engine project.
        /// </summary>
        /// <param name="EngineProject">Engine project to add files to.</param>
        private void AddUBTConfigFilesToEngineProject(ProjectFile EngineProject)
        {
            EngineProject.AddAliasedFileToProject(new AliasedFile(
                    XmlConfigLoader.GetXSDPath(),
                    Path.Combine("Programs", "UnrealBuildTool")
                ));

            foreach(var BuildConfigurationPath in XmlConfigLoader.ConfigLocationHierarchy)
            {
                if(!BuildConfigurationPath.bExists)
                {
                    continue;
                }

                EngineProject.AddAliasedFileToProject(
                        new AliasedFile(
                            BuildConfigurationPath.FSLocation,
                            Path.Combine("Config", "UnrealBuildTool", BuildConfigurationPath.IDEFolderName)
                        )
                    );
            }
        }
		/// Adds all engine extras files to the specified project
		protected virtual void AddEngineExtrasFiles(ProjectFile EngineProject)
		{
		}
Example #38
0
        /// Adds UnrealHeaderTool config files to the specified project
        private void AddUnrealHeaderToolConfigFiles(ProjectFile EngineProject)
        {
            var UHTConfigDirectory = Path.Combine(EngineRelativePath, "Programs", "UnrealHeaderTool", "Config");
            if (Directory.Exists(UHTConfigDirectory))
            {
                var DirectoriesToSearch = new List<string>();
                DirectoriesToSearch.Add(UHTConfigDirectory);

                EngineProject.AddFilesToProject(SourceFileSearch.FindFiles(DirectoriesToSearch, ExcludeNoRedistFiles: bExcludeNoRedistFiles), EngineRelativePath);
            }
        }
		/// Adds UnrealHeaderTool config files to the specified project
		private void AddUnrealHeaderToolConfigFiles(ProjectFile EngineProject)
		{
			DirectoryReference UHTConfigDirectory = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Programs", "UnrealHeaderTool", "Config");
			if (UHTConfigDirectory.Exists())
			{
				EngineProject.AddFilesToProject(SourceFileSearch.FindFiles(UHTConfigDirectory), UnrealBuildTool.EngineDirectory);
			}
		}
Example #40
0
        /// <summary>
        /// Generates a Visual Studio solution file and Visual C++ project files for all known engine and game targets.
        /// Does not actually build anything.
        /// </summary>
        /// <param name="Arguments">Command-line arguments</param>
        /// <param name="bSuccess">True if everything went OK</param>
        public virtual void GenerateProjectFiles( String[] Arguments, out bool bSuccess )
        {
            bSuccess = true;

            // Parse project generator options
            bool IncludeAllPlatforms = true;
            ConfigureProjectFileGeneration( Arguments, ref IncludeAllPlatforms);

            if( bGeneratingGameProjectFiles )
            {
                Log.TraceInformation("Discovering modules, targets and source code for game...");

                MasterProjectRelativePath = UnrealBuildTool.GetUProjectPath();

                    // Set the project file name
                MasterProjectName = Path.GetFileNameWithoutExtension(UnrealBuildTool.GetUProjectFile());

                if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                {
                    if (!Directory.Exists(MasterProjectRelativePath + "/Intermediate/Source"))
                    {
                        if (BuildHostPlatform.Current.Platform == UnrealTargetPlatform.Mac)
                        {
                            MasterProjectRelativePath = Path.GetFullPath(Path.Combine(Utils.GetExecutingAssemblyDirectory(), "..", "..", "..", "Engine"));
                            GameProjectName = "UE4Game";
                        }
                        if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                        {
                            throw new BuildException("Directory '{0}' is missing 'Source' folder.", MasterProjectRelativePath);
                        }
                    }
                }
                IntermediateProjectFilesPath = Path.Combine(MasterProjectRelativePath, "Intermediate", "ProjectFiles");
            }
            else if( bGeneratingRocketProjectFiles )
            {
                Log.TraceInformation("Discovering modules, targets and source code for project...");

                // NOTE: Realistically, the distro that the Rocket user is generating projects FROM won't have NoRedist files in it.  But when
                //       testing from a developer branch, this is useful to get authentic projects. This only really matters when
                //       bIncludeEngineModulesInRocketProjects=true (defaults to false.)
                bExcludeNoRedistFiles = true;

                MasterProjectRelativePath = UnrealBuildTool.GetUProjectPath();
                IntermediateProjectFilesPath = Path.Combine( MasterProjectRelativePath, "Intermediate", "ProjectFiles" );

                // Set the project file name
                MasterProjectName = Path.GetFileNameWithoutExtension(UnrealBuildTool.GetUProjectFile());

                if (!Directory.Exists(MasterProjectRelativePath + "/Source"))
                {
                    if (!Directory.Exists(MasterProjectRelativePath + "/Intermediate/Source"))
                    {
                        throw new BuildException("Directory '{0}' is missing 'Source' folder.", MasterProjectRelativePath);
                    }
                }
            }

            // Modify the name if specific platforms were given
            if (ProjectPlatforms.Count > 0)
            {
                // Sort the platforms names so we get consistent names
                List<string> SortedPlatformNames = new List<string>();
                foreach (UnrealTargetPlatform SpecificPlatform in ProjectPlatforms)
                {
                    SortedPlatformNames.Add(SpecificPlatform.ToString());
                }
                SortedPlatformNames.Sort();

                MasterProjectName += "_";
                foreach (string SortedPlatform in SortedPlatformNames)
                {
                    MasterProjectName += SortedPlatform;
                    IntermediateProjectFilesPath += SortedPlatform;
                }
            }

            bool bCleanProjectFiles = UnrealBuildTool.CommandLineContains( "-CleanProjects" );
            if (bCleanProjectFiles)
            {
                CleanProjectFiles(MasterProjectRelativePath, MasterProjectName, IntermediateProjectFilesPath);
            }

            // Figure out which platforms we should generate project files for.
            string SupportedPlatformNames;
            SetupSupportedPlatformsAndConfigurations( IncludeAllPlatforms:IncludeAllPlatforms, SupportedPlatformNames:out SupportedPlatformNames );

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

            RootFolder = AllocateMasterProjectFolder( this, "<Root>" );

            // Build the list of games to generate projects for
            var AllGameProjects = UProjectInfo.FilterGameProjects(true, bGeneratingGameProjectFiles ? GameProjectName : null);

            var AssemblyName = "ProjectFileGenerator";
            if( bGeneratingGameProjectFiles )
            {
                AssemblyName = GameProjectName + "ProjectFileGenerator";
            }
            else if( bGeneratingRocketProjectFiles )
            {
                AssemblyName = "RocketProjectFileGenerator";
            }

            List<string> AssemblyGameFolders = new List<string>();
            foreach (UProjectInfo Project in AllGameProjects)
            {
                AssemblyGameFolders.Add(Project.Folder);
            }
            RulesCompiler.SetAssemblyNameAndGameFolders( AssemblyName, AssemblyGameFolders );

            ProjectFile EngineProject = null;
            Dictionary<string, ProjectFile> GameProjects = null;
            Dictionary<string, ProjectFile> ProgramProjects = null;
            HashSet<ProjectFile> TemplateGameProjects = null;
            {
                // Setup buildable projects for all targets
                AddProjectsForAllTargets( AllGameProjects, out EngineProject, out GameProjects, out ProgramProjects, out TemplateGameProjects );

                // Add all game projects and game config files
                AddAllGameProjects(GameProjects, SupportedPlatformNames, RootFolder);

                // Set the game to be the default project
                if(bGeneratingGameProjectFiles && GameProjects.Count > 0)
                {
                    DefaultProject = GameProjects.Values.First();
                }

                // Place projects into root level solution folders
                if( IncludeEngineSource )
                {
                    // If we're still missing an engine project because we don't have any targets for it, make one up.
                    if( EngineProject == null )
                    {
                        string ProjectFilePath = Path.Combine(IntermediateProjectFilesPath, "UE4" + ProjectFileExtension);

                        bool bAlreadyExisted;
                        EngineProject = FindOrAddProject(Utils.MakePathRelativeTo(ProjectFilePath, MasterProjectRelativePath), true, out bAlreadyExisted);

                        EngineProject.IsForeignProject = false;
                        EngineProject.IsGeneratedProject = true;
                        EngineProject.IsStubProject = true;
                    }

                    if( EngineProject != null )
                    {
                        RootFolder.AddSubFolder( "Engine" ).ChildProjects.Add( EngineProject );

                        // Engine config files
                        if( IncludeConfigFiles )
                        {
                            AddEngineConfigFiles( EngineProject );
                            if( IncludeEnginePrograms )
                            {
                                AddUnrealHeaderToolConfigFiles(EngineProject);
                                AddUBTConfigFilesToEngineProject(EngineProject);
                            }
                        }

                        // Engine localization files
                        if( IncludeLocalizationFiles )
                        {
                            AddEngineLocalizationFiles( EngineProject );
                        }

                        // Engine template files
                        if (IncludeTemplateFiles)
                        {
                            AddEngineTemplateFiles( EngineProject );
                        }

                        if( IncludeShaderSource )
                        {
                            Log.TraceVerbose( "Adding shader source code..." );

                            // Find shader source files and generate stub project
                            AddEngineShaderSource( EngineProject );
                        }

                        if( IncludeBuildSystemFiles )
                        {
                            Log.TraceVerbose( "Adding build system files..." );

                            AddEngineBuildFiles( EngineProject );
                        }

                        if( IncludeDocumentation )
                        {
                            AddEngineDocumentation( EngineProject );
                        }
                    }

                    foreach( var CurGameProject in GameProjects.Values )
                    {
                        // Templates go under a different solution folder than games
                        if( TemplateGameProjects.Contains( CurGameProject ) )
                        {
                            RootFolder.AddSubFolder( "Templates" ).ChildProjects.Add( CurGameProject );
                        }
                        else
                        {
                            RootFolder.AddSubFolder( "Games" ).ChildProjects.Add( CurGameProject );
                        }
                    }

                    foreach( var CurProgramProject in ProgramProjects.Values )
                    {
                        ProjectTarget Target = CurProgramProject.ProjectTargets.FirstOrDefault(t => !String.IsNullOrEmpty(t.TargetRules.SolutionDirectory));

                        if (Target != null)
                        {
                            RootFolder.AddSubFolder(Target.TargetRules.SolutionDirectory).ChildProjects.Add(CurProgramProject);
                        }
                        else
                        {
                            RootFolder.AddSubFolder( "Programs" ).ChildProjects.Add( CurProgramProject );
                        }
                    }

                    // Add all of the config files for generated program targets
                    AddEngineProgramConfigFiles( ProgramProjects );
                }
            }

            // Find all of the module files.  This will filter out any modules or targets that don't belong to platforms
            // we're generating project files for.
            var AllModuleFiles = DiscoverModules();

            // Setup "stub" projects for all modules
            AddProjectsForAllModules(AllGameProjects, ProgramProjects, AllModuleFiles, bGatherThirdPartySource);

            {
                if( IncludeEnginePrograms )
                {
                    MasterProjectFolder ProgramsFolder = RootFolder.AddSubFolder( "Programs" );

                    // Add EnvVarsToXML to the master project
                    var EnvVarsToXMLProjectFile = AddSimpleCSharpProject("EnvVarsToXML/EnvVarsToXML", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true);
                    ProgramsFolder.ChildProjects.Add(EnvVarsToXMLProjectFile);

                    // Add UnrealBuildTool to the master project
                    AddUnrealBuildToolProject( ProgramsFolder, new ProjectFile[] { EnvVarsToXMLProjectFile } );

                    // Add AutomationTool to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("AutomationTool", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add UnrealAutomationTool (launcher) to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("AutomationToolLauncher", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add automation.csproj files to the master project
                    AddAutomationModules(ProgramsFolder);

                    // Add DotNETUtilities to the master project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("DotNETCommon/DotNETUtilities", bShouldBuildForAllSolutionTargets: true, bForceDevelopmentConfiguration: true));

                    // Add the Git dependencies project
                    ProgramsFolder.ChildProjects.Add(AddSimpleCSharpProject("GitDependencies", bForceDevelopmentConfiguration: true, bShouldBuildByDefaultForSolutionTargets: false));

                    // Add all of the IOS C# projects
                    AddIOSProjects( ProgramsFolder );

                    // Add all of the Android C# projects
                    AddAndroidProjects( ProgramsFolder );

                    // Add all of the PS4 C# projects
                    AddPS4Projects( ProgramsFolder );

                    AddHTML5Projects( ProgramsFolder );
                }

                // Eliminate all redundant master project folders.  E.g., folders which contain only one project and that project
                // has the same name as the folder itself.  To the user, projects "feel like" folders already in the IDE, so we
                // want to collapse them down where possible.
                EliminateRedundantMasterProjectSubFolders( RootFolder, "" );

                bool bWriteFileManifest = UnrealBuildTool.CommandLineContains("-filemanifest");

                if (bWriteFileManifest == false)
                {
                    // Figure out which targets we need about IntelliSense for.  We only need to worry about targets for projects
                    // that we're actually generating in this session.
                    var IntelliSenseTargetFiles = new List<Tuple<ProjectFile, string>>();
                    {
                        // Engine targets
                        if( EngineProject != null && !bGeneratingRocketProjectFiles )
                        {
                            foreach( var ProjectTarget in EngineProject.ProjectTargets )
                            {
                                if( !String.IsNullOrEmpty( ProjectTarget.TargetFilePath ) )
                                {
                                    // Only bother with the editor target.  We want to make sure that definitions are setup to be as inclusive as possible
                                    // for good quality IntelliSense.  For example, we want WITH_EDITORONLY_DATA=1, so using the editor targets works well.
                                    if( ProjectTarget.TargetRules.Type == TargetRules.TargetType.Editor )
                                    {
                                        IntelliSenseTargetFiles.Add( Tuple.Create(EngineProject, ProjectTarget.TargetFilePath) );
                                    }
                                }
                            }
                        }

                        // Program targets
                        foreach( var ProgramProject in ProgramProjects.Values )
                        {
                            foreach( var ProjectTarget in ProgramProject.ProjectTargets )
                            {
                                if( !String.IsNullOrEmpty( ProjectTarget.TargetFilePath ) )
                                {
                                    IntelliSenseTargetFiles.Add( Tuple.Create( ProgramProject, ProjectTarget.TargetFilePath ) );
                                }
                            }
                        }

                        // Game/template targets
                        foreach( var GameProject in GameProjects.Values )
                        {
                            foreach( var ProjectTarget in GameProject.ProjectTargets )
                            {
                                if( !String.IsNullOrEmpty( ProjectTarget.TargetFilePath ) )
                                {
                                    // Only bother with the editor target.  We want to make sure that definitions are setup to be as inclusive as possible
                                    // for good quality IntelliSense.  For example, we want WITH_EDITORONLY_DATA=1, so using the editor targets works well.
                                    if( ProjectTarget.TargetRules.Type == TargetRules.TargetType.Editor )
                                    {
                                        IntelliSenseTargetFiles.Add( Tuple.Create( GameProject, ProjectTarget.TargetFilePath ) );
                                    }
                                }
                            }
                        }
                    }

                    // Generate IntelliSense data if we need to.  This involves having UBT simulate the action compilation of
                    // the targets so that we can extra the compiler defines, include paths, etc.
                    bSuccess = GenerateIntelliSenseData(Arguments, IntelliSenseTargetFiles );
                }

                // If everything went OK, we'll now save out all of the new project files
                if( bSuccess )
                {
                    if (bWriteFileManifest == false)
                    {
                        // Save new project files
                        WriteProjectFiles();

                        Log.TraceVerbose( "Project generation complete ({0} generated, {1} imported)", GeneratedProjectFiles.Count, OtherProjectFiles.Count );
                    }
                    else
                    {
                        WriteProjectFileManifest();
                    }
                }
            }
        }
		protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
		{
			return WriteXcodeWorkspace();
		}
Example #42
0
        /// Adds engine documentation to the specified project
        protected void AddEngineDocumentation( ProjectFile EngineProject )
        {
            // NOTE: The project folder added here will actually be collapsed away later if not needed
            var DocumentationProjectDirectory = Path.Combine( EngineRelativePath, "Documentation" );
            var DocumentationSourceDirectory = Path.Combine( EngineRelativePath, "Documentation", "Source" );
            DirectoryInfo DirInfo = new DirectoryInfo( DocumentationProjectDirectory );
            if( DirInfo.Exists && Directory.Exists( DocumentationSourceDirectory ) )
            {
                Log.TraceVerbose( "Adding documentation files..." );

                var DirectoriesToSearch = new List<string>();
                DirectoriesToSearch.Add( DocumentationSourceDirectory );

                var SubdirectoryNamesToExclude = new List<string>();
                {
                    // We never want any of the images or attachment files included in our generated project
                    SubdirectoryNamesToExclude.Add( "Images" );
                    SubdirectoryNamesToExclude.Add( "Attachments" );

                    // The API directory is huge, so don't include any of it
                    SubdirectoryNamesToExclude.Add("API");

                    // Omit Javascript source because it just confuses the Visual Studio IDE
                    SubdirectoryNamesToExclude.Add( "Javascript" );
                }

                var DocumentationFiles = SourceFileSearch.FindFiles(
                    DirectoriesToSearch: DirectoriesToSearch,
                    ExcludeNoRedistFiles: bExcludeNoRedistFiles,
                    SubdirectoryNamesToExclude: SubdirectoryNamesToExclude );

                // Filter out non-English documentation files if we were configured to do so
                if( !bAllDocumentationLanguages )
                {
                    var FilteredDocumentationFiles = new List<string>();
                    foreach( var DocumentationFile in DocumentationFiles )
                    {
                        bool bPassesFilter = true;
                        if( DocumentationFile.EndsWith( ".udn", StringComparison.InvariantCultureIgnoreCase ) )
                        {
                            var LanguageSuffix = Path.GetExtension( Path.GetFileNameWithoutExtension( DocumentationFile ) );
                            if( !String.IsNullOrEmpty( LanguageSuffix ) &&
                                !LanguageSuffix.Equals( ".int", StringComparison.InvariantCultureIgnoreCase ) )
                            {
                                bPassesFilter = false;
                            }
                        }

                        if( bPassesFilter )
                        {
                            FilteredDocumentationFiles.Add( DocumentationFile );
                        }
                    }
                    DocumentationFiles = FilteredDocumentationFiles;
                }

                EngineProject.AddFilesToProject( DocumentationFiles, EngineRelativePath );
            }
            else
            {
                Log.TraceVerbose("Skipping documentation project... directory not found");
            }
        }
Example #43
0
 protected override bool WriteMasterProjectFile(ProjectFile UBTProject)
 {
     return(WriteXcodeWorkspace());
 }
Example #44
0
        /// <summary>
        /// Add the given project to the DepondsOn project list.
        /// </summary>
        /// <param name="InProjectFile">The project this project is dependent on</param>
        public void AddDependsOnProject(ProjectFile InProjectFile)
        {
            // Make sure that it doesn't exist already
            var AlreadyExists = false;
            foreach (var ExistingDependentOn in DependsOnProjects)
            {
                if (ExistingDependentOn == InProjectFile)
                {
                    AlreadyExists = true;
                    break;
                }
            }

            if (AlreadyExists == false)
            {
                DependsOnProjects.Add(InProjectFile);
            }
        }
Example #45
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);
                }
            }
        }