コード例 #1
0
ファイル: VCProject.cs プロジェクト: Tigrouzen/UnrealEngine-4
        /// <summary>
        /// Checks to see if the specified solution platform and configuration is able to map to this project
        /// </summary>
        /// <param name="ProjectTarget">The target that we're checking for a valid platform/config combination</param>
        /// <param name="Platform">Platform</param>
        /// <param name="Configuration">Configuration</param>
        /// <returns>True if this is a valid combination for this project, otherwise false</returns>
        public static bool IsValidProjectPlatformAndConfiguration(ProjectTarget ProjectTarget, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration)
        {
            var PlatformProjectGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
            if (PlatformProjectGenerator == null)
            {
                return false;
            }

            UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform, true);
            if (BuildPlatform == null)
            {
                return false;
            }

            if (BuildPlatform.HasRequiredSDKsInstalled() == false)
            {
                return false;
            }

            var SupportedConfigurations = new List<UnrealTargetConfiguration>();
            var SupportedPlatforms = new List<UnrealTargetPlatform>();
            if (!ProjectFileGenerator.bCreateDummyConfigsForUnsupportedPlatforms || ProjectFileGenerator.bGeneratingRocketProjectFiles)
            {
                if( ProjectTarget.TargetRules != null )
                {
                    ProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms);
                }
            }
            else
            {
                UnrealBuildTool.GetAllPlatforms(ref SupportedPlatforms);
            }
            bool bIncludeTestAndShippingConfigs = ProjectFileGenerator.bIncludeTestAndShippingConfigs || ProjectFileGenerator.bGeneratingRocketProjectFiles;
            if( ProjectTarget.TargetRules != null )
            {
                // Rocket projects always get shipping configs
                ProjectTarget.TargetRules.GetSupportedConfigurations(ref SupportedConfigurations, bIncludeTestAndShippingConfigs:bIncludeTestAndShippingConfigs);
            }

            // Add all of the extra platforms/configurations for this target
            {
                foreach( var ExtraPlatform in ProjectTarget.ExtraSupportedPlatforms )
                {
                    if( !SupportedPlatforms.Contains( ExtraPlatform ) )
                    {
                        SupportedPlatforms.Add( ExtraPlatform );
                    }
                }
                foreach( var ExtraConfig in ProjectTarget.ExtraSupportedConfigurations )
                {
                    if( bIncludeTestAndShippingConfigs || ( ExtraConfig != UnrealTargetConfiguration.Shipping && ExtraConfig != UnrealTargetConfiguration.Test ) )
                    {
                        if( !SupportedConfigurations.Contains( ExtraConfig ) )
                        {
                            SupportedConfigurations.Add( ExtraConfig );
                        }
                    }
                }
            }

            // Only build for supported platforms
            if (SupportedPlatforms.Contains(Platform) == false)
            {
                return false;
            }

            // Only build for supported configurations
            if (SupportedConfigurations.Contains(Configuration) == false)
            {
                return false;
            }

            // For Rocket projects, we currently only allow 64-bit versions of Debug and Development binaries to be compiled
            // and only 32-bit versions of Shipping binaries to be compiled.  This has to do with our choice of which build
            // configurations we want to ship with that product.  So to simplify things, we're merging Win32 and Win64
            // configurations together in the IDE under "Windows".  In order for this to work properly, we need to make
            // sure that Rocket projects only report the respective Windows platform that is valid for each configuration
            if( UnrealBuildTool.RunningRocket() && ProjectTarget.TargetRules != null )
            {
                if( Platform == UnrealTargetPlatform.Win32 || Platform == UnrealTargetPlatform.Win64 )
                {
                    // In Rocket, shipping game targets are always 32-bit
                    if( Configuration == UnrealTargetConfiguration.Shipping && ProjectTarget.TargetRules.Type == TargetRules.TargetType.RocketGame )
                    {
                        if( Platform != UnrealTargetPlatform.Win32 )
                        {
                            return false;
                        }
                    }
                    else
                    {
                        // Everything else is expecting to be 64-bit
                        if( Platform != UnrealTargetPlatform.Win64 )
                        {
                            return false;
                        }
                    }
                }
            }

            return true;
        }
コード例 #2
0
ファイル: ProjectFileGenerator.cs プロジェクト: mymei/UE4
        /// <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);
                    }
                }
            }
        }
コード例 #3
0
ファイル: ProjectFileGenerator.cs プロジェクト: mymei/UE4
        /// <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 );
        }
コード例 #4
0
ファイル: VCProject.cs プロジェクト: ErwinT6/T6Engine
		/// <summary>
		/// Checks to see if the specified solution platform and configuration is able to map to this project
		/// </summary>
		/// <param name="ProjectTarget">The target that we're checking for a valid platform/config combination</param>
		/// <param name="Platform">Platform</param>
		/// <param name="Configuration">Configuration</param>
		/// <returns>True if this is a valid combination for this project, otherwise false</returns>
		public static bool IsValidProjectPlatformAndConfiguration(ProjectTarget ProjectTarget, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration)
		{
			var PlatformProjectGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true);
			if (PlatformProjectGenerator == null)
			{
				return false;
			}

			var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform, true);
			if (BuildPlatform == null)
			{
				return false;
			}

			if (BuildPlatform.HasRequiredSDKsInstalled() != SDKStatus.Valid)
			{
				return false;
			}


			var SupportedConfigurations = new List<UnrealTargetConfiguration>();
			var SupportedPlatforms = new List<UnrealTargetPlatform>();
			if (!ProjectFileGenerator.bCreateDummyConfigsForUnsupportedPlatforms)
			{
				if( ProjectTarget.TargetRules != null )
				{
					ProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms);
				}
			}
			else
			{
				UnrealBuildTool.GetAllPlatforms(ref SupportedPlatforms);
			}
			bool bIncludeTestAndShippingConfigs = ProjectFileGenerator.bIncludeTestAndShippingConfigs || ProjectFileGenerator.bGeneratingRocketProjectFiles;
			if( ProjectTarget.TargetRules != null )
			{
				// Rocket projects always get shipping configs
				ProjectTarget.TargetRules.GetSupportedConfigurations(ref SupportedConfigurations, bIncludeTestAndShippingConfigs:bIncludeTestAndShippingConfigs);
			}

			// Add all of the extra platforms/configurations for this target
			{
				foreach( var ExtraPlatform in ProjectTarget.ExtraSupportedPlatforms )
				{
					if( !SupportedPlatforms.Contains( ExtraPlatform ) )
					{
						SupportedPlatforms.Add( ExtraPlatform );
					}
				}
				foreach( var ExtraConfig in ProjectTarget.ExtraSupportedConfigurations )
				{
					if( bIncludeTestAndShippingConfigs || ( ExtraConfig != UnrealTargetConfiguration.Shipping && ExtraConfig != UnrealTargetConfiguration.Test ) )
					{
						if( !SupportedConfigurations.Contains( ExtraConfig ) )
						{
							SupportedConfigurations.Add( ExtraConfig );
						}
					}
				}
			}

			// Only build for supported platforms
			if (SupportedPlatforms.Contains(Platform) == false)
			{
				return false;
			}

			// Only build for supported configurations
			if (SupportedConfigurations.Contains(Configuration) == false)
			{
				return false;
			}

			return true;
		}
コード例 #5
0
ファイル: VCProject.cs プロジェクト: ErwinT6/T6Engine
			public ProjectConfigAndTargetCombination(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, string InProjectPlatformName, string InProjectConfigurationName, ProjectTarget InProjectTarget)
			{
				Platform = InPlatform;
				Configuration = InConfiguration;
				ProjectPlatformName = InProjectPlatformName;
				ProjectConfigurationName = InProjectConfigurationName;
				ProjectTarget = InProjectTarget;
			}
コード例 #6
0
			public XcodeBuildConfig(string InDisplayName, string InBuildTarget, FileReference InMacExecutablePath, FileReference InIOSExecutablePath, FileReference InTVOSExecutablePath,
				ProjectTarget InProjectTarget, UnrealTargetConfiguration InBuildConfig)
			{
				DisplayName = InDisplayName;
				MacExecutablePath = InMacExecutablePath;
				IOSExecutablePath = InIOSExecutablePath;
				TVOSExecutablePath = InTVOSExecutablePath;
				BuildTarget = InBuildTarget;
				ProjectTarget = InProjectTarget;
				BuildConfig = InBuildConfig;
			}
コード例 #7
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.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");
            }


            // 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. VS will automatically import the options from earlier versions if necessary.
                string SolutionOptionsExtension = "vUnknown.suo";
                switch (ProjectFileFormat)
                {
                case VCProjectFileFormat.VisualStudio2012:
                    SolutionOptionsExtension = "v11.suo";
                    break;

                case VCProjectFileFormat.VisualStudio2013:
                    SolutionOptionsExtension = "v12.suo";
                    break;

                case VCProjectFileFormat.VisualStudio2015:
                    SolutionOptionsExtension = "v14.suo";
                    break;
                }

                // 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);
        }
コード例 #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<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);
				}
			}
		}
コード例 #9
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);
                }
            }
        }
コード例 #10
0
        private FileReference GetExecutableFilename(ProjectFile Project, ProjectTarget Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration)
        {
            TargetRules   TargetRulesObject = Target.TargetRules;
            FileReference TargetFilePath    = Target.TargetFilePath;
            string        TargetName        = TargetFilePath == null?Project.ProjectFilePath.GetFileNameWithoutExtension() : TargetFilePath.GetFileNameWithoutAnyExtensions();

            string UBTPlatformName      = Platform.ToString();
            string UBTConfigurationName = Configuration.ToString();

            string ProjectName = Project.ProjectFilePath.GetFileNameWithoutExtension();

            // Setup output path
            UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform);

            // Figure out if this is a monolithic build
            bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform);

            if (TargetRulesObject != null)
            {
                bShouldCompileMonolithic |= (Target.CreateRulesDelegate(Platform, Configuration).GetLegacyLinkType(Platform, Configuration) == TargetLinkType.Monolithic);
            }

            TargetType TargetRulesType = Target.TargetRules == null ? TargetType.Program : Target.TargetRules.Type;

            // Get the output directory
            DirectoryReference RootDirectory = UnrealBuildTool.EngineDirectory;

            if (TargetRulesType != TargetType.Program && (bShouldCompileMonolithic || TargetRulesObject.BuildEnvironment == TargetBuildEnvironment.Unique) && !TargetRulesObject.bOutputToEngineBinaries)
            {
                if (OnlyGameProject != null && TargetFilePath.IsUnderDirectory(OnlyGameProject.Directory))
                {
                    RootDirectory = OnlyGameProject.Directory;
                }
                else
                {
                    FileReference ProjectFileName;
                    if (UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFileName))
                    {
                        RootDirectory = ProjectFileName.Directory;
                    }
                }
            }

            if (TargetRulesType == TargetType.Program && (TargetRulesObject == null || !TargetRulesObject.bOutputToEngineBinaries))
            {
                FileReference ProjectFileName;
                if (UProjectInfo.TryGetProjectForTarget(TargetName, out ProjectFileName))
                {
                    RootDirectory = ProjectFileName.Directory;
                }
            }

            // Get the output directory
            DirectoryReference OutputDirectory = DirectoryReference.Combine(RootDirectory, "Binaries", UBTPlatformName);

            // Get the executable name (minus any platform or config suffixes)
            string BaseExeName = TargetName;

            if (!bShouldCompileMonolithic && TargetRulesType != TargetType.Program)
            {
                // Figure out what the compiled binary will be called so that we can point the IDE to the correct file
                string TargetConfigurationName = TargetRulesType.ToString();
                if (TargetConfigurationName != TargetType.Game.ToString() && TargetConfigurationName != TargetType.Program.ToString())
                {
                    BaseExeName = "UE4" + TargetConfigurationName;
                }
            }

            // Make the output file path
            string ExecutableFilename = FileReference.Combine(OutputDirectory, BaseExeName).ToString();

            if ((Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic))
            {
                ExecutableFilename += "-" + UBTPlatformName + "-" + UBTConfigurationName;
            }
            ExecutableFilename += TargetRulesObject.Architecture;
            ExecutableFilename += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable);

            return(FileReference.MakeFromNormalizedFullPath(ExecutableFilename));
        }