示例#1
0
        /// <summary>
        /// Creates a rules assembly with the given parameters.
        /// </summary>
        /// <param name="PluginFileName">The plugin file to create rules for</param>
        /// <param name="bSkipCompile">Whether to skip compilation for this assembly</param>
        /// <param name="Parent">The parent rules assembly</param>
        /// <param name="bContainsEngineModules">Whether the plugin contains engine modules. Used to initialize the default value for ModuleRules.bTreatAsEngineModule.</param>
        /// <returns>The new rules assembly</returns>
        public static RulesAssembly CreatePluginRulesAssembly(FileReference PluginFileName, bool bSkipCompile, RulesAssembly Parent, bool bContainsEngineModules)
        {
            // Check if there's an existing assembly for this project
            RulesAssembly PluginRulesAssembly;

            if (!LoadedAssemblyMap.TryGetValue(PluginFileName, out PluginRulesAssembly))
            {
                // Find all the rules source files
                Dictionary <FileReference, ModuleRulesContext> ModuleFiles = new Dictionary <FileReference, ModuleRulesContext>();
                List <FileReference> TargetFiles = new List <FileReference>();

                // Create a list of plugins for this assembly. If it already exists in the parent assembly, just create an empty assembly.
                List <PluginInfo> ForeignPlugins = new List <PluginInfo>();
                if (Parent == null || !Parent.EnumeratePlugins().Any(x => x.File == PluginFileName))
                {
                    ForeignPlugins.Add(new PluginInfo(PluginFileName, PluginType.External));
                }

                // Create a new scope for the plugin. It should not reference anything else.
                RulesScope Scope = new RulesScope("Plugin", Parent.Scope);

                // Find all the modules
                ModuleRulesContext PluginModuleContext = new ModuleRulesContext(Scope, PluginFileName.Directory);
                PluginModuleContext.bClassifyAsGameModuleForUHT = !bContainsEngineModules;
                FindModuleRulesForPlugins(ForeignPlugins, PluginModuleContext, ModuleFiles);

                // Compile the assembly
                FileReference AssemblyFileName = FileReference.Combine(PluginFileName.Directory, "Intermediate", "Build", "BuildRules", Path.GetFileNameWithoutExtension(PluginFileName.FullName) + "ModuleRules" + FrameworkAssemblyExtension);
                PluginRulesAssembly = new RulesAssembly(Scope, new List <DirectoryReference> {
                    PluginFileName.Directory
                }, ForeignPlugins, ModuleFiles, TargetFiles, AssemblyFileName, bContainsEngineModules, DefaultBuildSettings: null, bReadOnly: false, bSkipCompile: bSkipCompile, Parent: Parent);
                LoadedAssemblyMap.Add(PluginFileName, PluginRulesAssembly);
            }
            return(PluginRulesAssembly);
        }
示例#2
0
        /// <summary>
        /// Find all the module rules files under a given directory
        /// </summary>
        /// <param name="BaseDirectory">The directory to search under</param>
        /// <param name="ModuleContext">The module context for each found rules instance</param>
        /// <param name="ModuleFileToContext">Map of module files to their context</param>
        private static void AddModuleRulesWithContext(DirectoryReference BaseDirectory, ModuleRulesContext ModuleContext, Dictionary <FileReference, ModuleRulesContext> ModuleFileToContext)
        {
            IReadOnlyList <FileReference> RulesFiles = FindAllRulesFiles(BaseDirectory, RulesFileType.Module);

            foreach (FileReference RulesFile in RulesFiles)
            {
                ModuleFileToContext[RulesFile] = ModuleContext;
            }
        }
 /// <summary>
 /// Copy constructor
 /// </summary>
 /// <param name="Other">The context to copy from</param>
 public ModuleRulesContext(ModuleRulesContext Other)
 {
     this.Scope = Other.Scope;
     this.DefaultOutputBaseDir = Other.DefaultOutputBaseDir;
     this.Plugin                      = Other.Plugin;
     this.bCanHotReload               = Other.bCanHotReload;
     this.bCanBuildDebugGame          = Other.bCanBuildDebugGame;
     this.bCanUseForSharedPCH         = Other.bCanUseForSharedPCH;
     this.bClassifyAsGameModuleForUHT = Other.bClassifyAsGameModuleForUHT;
     this.DefaultUHTModuleType        = Other.DefaultUHTModuleType;
 }
示例#4
0
        /// <summary>
        /// Find all the module rules files under a given directory
        /// </summary>
        /// <param name="BaseDirectory">The directory to search under</param>
        /// <param name="SubDirectoryName">Name of the subdirectory to look under</param>
        /// <param name="BaseModuleContext">The module context for each found rules instance</param>
        /// <param name="DefaultUHTModuleType">The UHT module type</param>
        /// <param name="ModuleFileToContext">Map of module files to their context</param>
        private static void AddEngineModuleRulesWithContext(DirectoryReference BaseDirectory, string SubDirectoryName, ModuleRulesContext BaseModuleContext, UHTModuleType?DefaultUHTModuleType, Dictionary <FileReference, ModuleRulesContext> ModuleFileToContext)
        {
            DirectoryReference Directory = DirectoryReference.Combine(BaseDirectory, SubDirectoryName);

            if (DirectoryLookupCache.DirectoryExists(Directory))
            {
                ModuleRulesContext ModuleContext = new ModuleRulesContext(BaseModuleContext)
                {
                    DefaultUHTModuleType = DefaultUHTModuleType
                };
                AddModuleRulesWithContext(Directory, ModuleContext, ModuleFileToContext);
            }
        }
示例#5
0
        /// <summary>
        /// Finds all the module rules for plugins under the given directory.
        /// </summary>
        /// <param name="Plugins">The directory to search</param>
        /// <param name="DefaultContext">The default context for any files that are enumerated</param>
        /// <param name="ModuleFileToContext">Dictionary which is filled with mappings from the module file to its corresponding context</param>
        private static void FindModuleRulesForPlugins(IReadOnlyList <PluginInfo> Plugins, ModuleRulesContext DefaultContext, Dictionary <FileReference, ModuleRulesContext> ModuleFileToContext)
        {
            PrefetchRulesFiles(Plugins.Select(x => DirectoryReference.Combine(x.Directory, "Source")));

            foreach (PluginInfo Plugin in Plugins)
            {
                IReadOnlyList <FileReference> PluginModuleFiles = FindAllRulesFiles(DirectoryReference.Combine(Plugin.Directory, "Source"), RulesFileType.Module);
                foreach (FileReference ModuleFile in PluginModuleFiles)
                {
                    ModuleRulesContext PluginContext = new ModuleRulesContext(DefaultContext);
                    PluginContext.DefaultOutputBaseDir = Plugin.Directory;
                    PluginContext.Plugin            = Plugin;
                    ModuleFileToContext[ModuleFile] = PluginContext;
                }
            }
        }
示例#6
0
        /// <summary>
        /// Creates a rules assembly with the given parameters.
        /// </summary>
        /// <param name="ProjectFileName">The project file to create rules for. Null for the engine.</param>
        /// <param name="bUsePrecompiled">Whether to use a precompiled engine</param>
        /// <param name="bSkipCompile">Whether to skip compilation for this assembly</param>
        /// <returns>New rules assembly</returns>
        public static RulesAssembly CreateProjectRulesAssembly(FileReference ProjectFileName, bool bUsePrecompiled, bool bSkipCompile)
        {
            // Check if there's an existing assembly for this project
            RulesAssembly ProjectRulesAssembly;

            if (!LoadedAssemblyMap.TryGetValue(ProjectFileName, out ProjectRulesAssembly))
            {
                ProjectDescriptor Project = ProjectDescriptor.FromFile(ProjectFileName);

                // Create the parent assembly
                RulesAssembly Parent;
                if (Project.IsEnterpriseProject)
                {
                    Parent = CreateEnterpriseRulesAssembly(bUsePrecompiled, bSkipCompile);
                }
                else
                {
                    Parent = CreateEngineRulesAssembly(bUsePrecompiled, bSkipCompile);
                }

                DirectoryReference MainProjectDirectory = ProjectFileName.Directory;
                //DirectoryReference MainProjectSourceDirectory = DirectoryReference.Combine(MainProjectDirectory, "Source");

                // Create a scope for things in this assembly
                RulesScope Scope = new RulesScope("Project", Parent.Scope);

                // Create a new context for modules created by this assembly
                ModuleRulesContext DefaultModuleContext = new ModuleRulesContext(Scope, MainProjectDirectory);
                DefaultModuleContext.bCanBuildDebugGame          = true;
                DefaultModuleContext.bCanHotReload               = true;
                DefaultModuleContext.bClassifyAsGameModuleForUHT = true;
                DefaultModuleContext.bCanUseForSharedPCH         = false;

                // gather modules from project and platforms
                Dictionary <FileReference, ModuleRulesContext> ModuleFiles = new Dictionary <FileReference, ModuleRulesContext>();
                List <FileReference> TargetFiles = new List <FileReference>();

                // Find all the project directories
                List <DirectoryReference> ProjectDirectories = new List <DirectoryReference>(UnrealBuildTool.GetAllProjectDirectories(ProjectFileName));
                if (Project.AdditionalRootDirectories != null)
                {
                    ProjectDirectories.AddRange(Project.AdditionalRootDirectories);
                }

                // Find all the rules/plugins under the project source directories
                foreach (DirectoryReference ProjectDirectory in ProjectDirectories)
                {
                    DirectoryReference ProjectSourceDirectory = DirectoryReference.Combine(ProjectDirectory, "Source");

                    AddModuleRulesWithContext(ProjectSourceDirectory, DefaultModuleContext, ModuleFiles);
                    TargetFiles.AddRange(FindAllRulesFiles(ProjectSourceDirectory, RulesFileType.Target));
                }

                // Find all the project plugins
                List <PluginInfo> ProjectPlugins = new List <PluginInfo>();
                ProjectPlugins.AddRange(Plugins.ReadProjectPlugins(MainProjectDirectory));

                // Add the project's additional plugin directories plugins too
                if (Project.AdditionalPluginDirectories != null)
                {
                    foreach (DirectoryReference AdditionalPluginDirectory in Project.AdditionalPluginDirectories)
                    {
                        ProjectPlugins.AddRange(Plugins.ReadAdditionalPlugins(AdditionalPluginDirectory));
                    }
                }

                // Find all the plugin module rules
                FindModuleRulesForPlugins(ProjectPlugins, DefaultModuleContext, ModuleFiles);

                // Add the games project's intermediate source folder
                DirectoryReference ProjectIntermediateSourceDirectory = DirectoryReference.Combine(MainProjectDirectory, "Intermediate", "Source");
                if (DirectoryReference.Exists(ProjectIntermediateSourceDirectory))
                {
                    AddModuleRulesWithContext(ProjectIntermediateSourceDirectory, DefaultModuleContext, ModuleFiles);
                    TargetFiles.AddRange(FindAllRulesFiles(ProjectIntermediateSourceDirectory, RulesFileType.Target));
                }

                // Compile the assembly. If there are no module or target files, just use the parent assembly.
                FileReference AssemblyFileName = FileReference.Combine(MainProjectDirectory, "Intermediate", "Build", "BuildRules", ProjectFileName.GetFileNameWithoutExtension() + "ModuleRules" + FrameworkAssemblyExtension);
                if (ModuleFiles.Count == 0 && TargetFiles.Count == 0)
                {
                    ProjectRulesAssembly = Parent;
                }
                else
                {
                    ProjectRulesAssembly = new RulesAssembly(Scope, new List <DirectoryReference> {
                        MainProjectDirectory
                    }, ProjectPlugins, ModuleFiles, TargetFiles, AssemblyFileName, bContainsEngineModules: false, DefaultBuildSettings: null, bReadOnly: UnrealBuildTool.IsProjectInstalled(), bSkipCompile: bSkipCompile, Parent: Parent);
                }
                LoadedAssemblyMap.Add(ProjectFileName, ProjectRulesAssembly);
            }
            return(ProjectRulesAssembly);
        }
示例#7
0
        /// <summary>
        /// Creates a rules assembly
        /// </summary>
        /// <param name="Scope">Scope for items created from this assembly</param>
        /// <param name="RootDirectories">The root directories to create rules for</param>
        /// <param name="AssemblyPrefix">A prefix for the assembly file name</param>
        /// <param name="Plugins">List of plugins to include in this assembly</param>
        /// <param name="bReadOnly">Whether the assembly should be marked as installed</param>
        /// <param name="bSkipCompile">Whether to skip compilation for this assembly</param>
        /// <param name="Parent">The parent rules assembly</param>
        /// <returns>New rules assembly</returns>
        private static RulesAssembly CreateEngineOrEnterpriseRulesAssembly(RulesScope Scope, List <DirectoryReference> RootDirectories, string AssemblyPrefix, IReadOnlyList <PluginInfo> Plugins, bool bReadOnly, bool bSkipCompile, RulesAssembly Parent)
        {
            // Scope hierarchy
            RulesScope PluginsScope  = new RulesScope(Scope.Name + " Plugins", Scope);
            RulesScope ProgramsScope = new RulesScope(Scope.Name + " Programs", PluginsScope);

            // Find the shared modules, excluding the programs directory. These are used to create an assembly with the bContainsEngineModules flag set to true.
            Dictionary <FileReference, ModuleRulesContext> ModuleFileToContext = new Dictionary <FileReference, ModuleRulesContext>();
            ModuleRulesContext DefaultModuleContext = new ModuleRulesContext(Scope, RootDirectories[0]);

            foreach (DirectoryReference RootDirectory in RootDirectories)
            {
                using (Timeline.ScopeEvent("Finding engine modules"))
                {
                    DirectoryReference SourceDirectory = DirectoryReference.Combine(RootDirectory, "Source");

                    AddEngineModuleRulesWithContext(SourceDirectory, "Runtime", DefaultModuleContext, UHTModuleType.EngineRuntime, ModuleFileToContext);
                    AddEngineModuleRulesWithContext(SourceDirectory, "Developer", DefaultModuleContext, UHTModuleType.EngineDeveloper, ModuleFileToContext);
                    AddEngineModuleRulesWithContext(SourceDirectory, "Editor", DefaultModuleContext, UHTModuleType.EngineEditor, ModuleFileToContext);
                    AddEngineModuleRulesWithContext(SourceDirectory, "ThirdParty", DefaultModuleContext, UHTModuleType.EngineThirdParty, ModuleFileToContext);
                }
            }

            // Add all the plugin modules too (don't need to loop over RootDirectories since the plugins come in already found
            using (Timeline.ScopeEvent("Finding plugin modules"))
            {
                ModuleRulesContext PluginsModuleContext = new ModuleRulesContext(PluginsScope, RootDirectories[0]);
                FindModuleRulesForPlugins(Plugins, PluginsModuleContext, ModuleFileToContext);
            }

            // Get the path to store any generated assemblies
            DirectoryReference AssemblyDir = RootDirectories[0];

            if (UnrealBuildTool.IsFileInstalled(FileReference.Combine(AssemblyDir, AssemblyPrefix)))
            {
                DirectoryReference UserDir = Utils.GetUserSettingDirectory();
                if (UserDir != null)
                {
                    ReadOnlyBuildVersion Version = ReadOnlyBuildVersion.Current;
                    AssemblyDir = DirectoryReference.Combine(UserDir, "UnrealEngine", String.Format("{0}.{1}", Version.MajorVersion, Version.MinorVersion));
                }
            }

            // Create the assembly
            FileReference EngineAssemblyFileName = FileReference.Combine(AssemblyDir, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension);
            RulesAssembly EngineAssembly         = new RulesAssembly(Scope, RootDirectories, Plugins, ModuleFileToContext, new List <FileReference>(), EngineAssemblyFileName, bContainsEngineModules: true, DefaultBuildSettings: BuildSettingsVersion.Latest, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: Parent);

            List <FileReference> ProgramTargetFiles = new List <FileReference>();
            Dictionary <FileReference, ModuleRulesContext> ProgramModuleFiles = new Dictionary <FileReference, ModuleRulesContext>();

            foreach (DirectoryReference RootDirectory in RootDirectories)
            {
                DirectoryReference SourceDirectory   = DirectoryReference.Combine(RootDirectory, "Source");
                DirectoryReference ProgramsDirectory = DirectoryReference.Combine(SourceDirectory, "Programs");

                // Also create a scope for them, and update the UHT module type
                ModuleRulesContext ProgramsModuleContext = new ModuleRulesContext(ProgramsScope, RootDirectory);
                ProgramsModuleContext.DefaultUHTModuleType = UHTModuleType.Program;

                using (Timeline.ScopeEvent("Finding program modules"))
                {
                    // Find all the rules files
                    AddModuleRulesWithContext(ProgramsDirectory, ProgramsModuleContext, ProgramModuleFiles);
                }

                using (Timeline.ScopeEvent("Finding program targets"))
                {
                    ProgramTargetFiles.AddRange(FindAllRulesFiles(SourceDirectory, RulesFileType.Target));
                }
            }

            // Create a path to the assembly that we'll either load or compile
            FileReference ProgramAssemblyFileName = FileReference.Combine(AssemblyDir, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "ProgramRules" + FrameworkAssemblyExtension);
            RulesAssembly ProgramAssembly         = new RulesAssembly(ProgramsScope, RootDirectories, new List <PluginInfo>().AsReadOnly(), ProgramModuleFiles, ProgramTargetFiles, ProgramAssemblyFileName, bContainsEngineModules: false, DefaultBuildSettings: BuildSettingsVersion.Latest, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: EngineAssembly);

            // Return the combined assembly
            return(ProgramAssembly);
        }