示例#1
0
 /// <summary>
 /// Creates the enterprise rules assembly
 /// </summary>
 /// <param name="bUsePrecompiled">Whether to use a precompiled enterprise and engine folder</param>
 /// <param name="bSkipCompile">Whether to skip compilation for this assembly</param>
 /// <returns>New rules assembly. Returns null if the enterprise directory is unavailable.</returns>
 public static RulesAssembly CreateEnterpriseRulesAssembly(bool bUsePrecompiled, bool bSkipCompile)
 {
     if (EnterpriseRulesAssembly == null && DirectoryReference.Exists(UnrealBuildTool.EnterpriseDirectory))
     {
         IReadOnlyList <PluginInfo> IncludedPlugins = Plugins.ReadEnterprisePlugins(UnrealBuildTool.EnterpriseDirectory);
         EnterpriseRulesAssembly = CreateEngineOrEnterpriseRulesAssembly(UnrealBuildTool.EnterpriseDirectory, ProjectFileGenerator.EnterpriseProjectFileNameBase, IncludedPlugins, UnrealBuildTool.IsEnterpriseInstalled() || bUsePrecompiled, bSkipCompile, CreateEngineRulesAssembly(bUsePrecompiled, bSkipCompile));
     }
     return(EnterpriseRulesAssembly);
 }
        /// <summary>
        /// Creates an instance of a module rules descriptor object for the specified module name
        /// </summary>
        /// <param name="ModuleName">Name of the module</param>
        /// <param name="Target">Information about the target associated with this module</param>
        /// <param name="ReferenceChain">Chain of references leading to this module</param>
        /// <param name="ModuleFileName">The original source file name for the Module.cs file for this module</param>
        /// <returns>Compiled module rule info</returns>
        public ModuleRules CreateModuleRules(string ModuleName, ReadOnlyTargetRules Target, string ReferenceChain, out FileReference ModuleFileName)
        {
            // Currently, we expect the user's rules object type name to be the same as the module name
            string ModuleTypeName = ModuleName;

            // Make sure the module file is known to us
            if (!ModuleNameToModuleFile.TryGetValue(ModuleName, out ModuleFileName))
            {
                if (Parent == null)
                {
                    throw new BuildException("Could not find definition for module '{0}' (referenced via {1})", ModuleName, ReferenceChain);
                }
                else
                {
                    return(Parent.CreateModuleRules(ModuleName, Target, ReferenceChain, out ModuleFileName));
                }
            }

            // The build module must define a type named 'Rules' that derives from our 'ModuleRules' type.
            Type RulesObjectType = GetModuleRulesTypeInternal(ModuleName);

            if (RulesObjectType == null)
            {
                throw new BuildException("Expecting to find a type to be declared in a module rules named '{0}' in {1}.  This type must derive from the 'ModuleRules' type defined by Unreal Build Tool.", ModuleTypeName, CompiledAssembly.FullName);
            }

            // Create an instance of the module's rules object
            try
            {
                // Create an uninitialized ModuleRules object and set some defaults.
                ModuleRules RulesObject = (ModuleRules)FormatterServices.GetUninitializedObject(RulesObjectType);
                RulesObject.bTreatAsEngineModule            = bContainsEngineModules;
                RulesObject.bUseBackwardsCompatibleDefaults = bUseBackwardsCompatibleDefaults && Target.bUseBackwardsCompatibleDefaults;
                RulesObject.bPrecompile     = RulesObject.bTreatAsEngineModule && Target.bPrecompile;
                RulesObject.bUsePrecompiled = (RulesObject.bTreatAsEngineModule && Target.bUsePrecompiled) || bInstalled;

                if (ModuleFileName.IsUnderDirectory(UnrealBuildTool.EnterpriseDirectory) && !UnrealBuildTool.IsEnterpriseInstalled())
                {
                    RulesObject.bUsePrecompiled = false;
                }

                // Call the constructor
                ConstructorInfo Constructor = RulesObjectType.GetConstructor(new Type[] { typeof(ReadOnlyTargetRules) });
                if (Constructor == null)
                {
                    throw new BuildException("No valid constructor found for {0}.", ModuleName);
                }
                Constructor.Invoke(RulesObject, new object[] { Target });

                // Update the precompiled flags
                if (RulesObject.bPrecompile && !RulesObject.CanPrecompile(ModuleFileName))
                {
                    RulesObject.bPrecompile = false;
                }
                return(RulesObject);
            }
            catch (Exception Ex)
            {
                Exception MessageEx = (Ex is TargetInvocationException && Ex.InnerException != null)? Ex.InnerException : Ex;
                throw new BuildException(Ex, "Unable to instantiate module '{0}': {1}\n(referenced via {2})", ModuleName, MessageEx.ToString(), ReferenceChain);
            }
        }
示例#3
0
        /// <summary>
        /// Creates the enterprise rules assembly
        /// </summary>
        /// <param name="bUsePrecompiled">Whether to use a precompiled enterprise and engine folder</param>
        /// <param name="bSkipCompile">Whether to skip compilation for this assembly</param>
        /// <returns>New rules assembly. Returns null if the enterprise directory is unavailable.</returns>
        public static RulesAssembly CreateEnterpriseRulesAssembly(bool bUsePrecompiled, bool bSkipCompile)
        {
            if (EnterpriseRulesAssembly == null)
            {
                RulesAssembly EngineAssembly = CreateEngineRulesAssembly(bUsePrecompiled, bSkipCompile);
                if (DirectoryReference.Exists(UnrealBuildTool.EnterpriseDirectory))
                {
                    RulesScope EnterpriseScope = new RulesScope("Enterprise", EngineAssembly.Scope);

                    //List<DirectoryReference> EnterpriseDirectories = new List<DirectoryReference>() { UnrealBuildTool.EnterpriseDirectory };

                    IReadOnlyList <PluginInfo> IncludedPlugins = Plugins.ReadEnterprisePlugins(UnrealBuildTool.EnterpriseDirectory);
                    EnterpriseRulesAssembly = CreateEngineOrEnterpriseRulesAssembly(EnterpriseScope, new List <DirectoryReference>()
                    {
                        UnrealBuildTool.EnterpriseDirectory
                    },
                                                                                    ProjectFileGenerator.EnterpriseProjectFileNameBase, IncludedPlugins, UnrealBuildTool.IsEnterpriseInstalled() || bUsePrecompiled, bSkipCompile, EngineAssembly);
                }
                else
                {
                    // If we're asked for the enterprise rules assembly but the enterprise directory is missing, fallback on the engine rules assembly
                    Log.TraceWarning("Trying to build an enterprise target but the enterprise directory is missing. Falling back on engine components only.");
                    return(EngineAssembly);
                }
            }

            return(EnterpriseRulesAssembly);
        }
示例#4
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);
                }
            }
        }