Пример #1
0
        /// <summary>
        /// Get the project folder for the given target name
        /// </summary>
        /// <param name="InTargetName">Name of the target of interest</param>
        /// <param name="OutProjectFileName">The project filename</param>
        /// <returns>True if the target was found</returns>
        public static bool TryGetProjectForTarget(string InTargetName, out FileReference OutProjectFileName)
        {
            if (CachedTargetNameToProjectFile == null)
            {
                lock (LockObject)
                {
                    if (CachedTargetNameToProjectFile == null)
                    {
                        Dictionary <string, FileReference> TargetNameToProjectFile = new Dictionary <string, FileReference>();
                        foreach (FileReference ProjectFile in EnumerateProjectFiles())
                        {
                            foreach (DirectoryReference ExtensionDir in UnrealBuildTool.GetExtensionDirs(ProjectFile.Directory))
                            {
                                DirectoryReference SourceDirectory = DirectoryReference.Combine(ExtensionDir, "Source");
                                if (DirectoryLookupCache.DirectoryExists(SourceDirectory))
                                {
                                    FindTargetFiles(SourceDirectory, TargetNameToProjectFile, ProjectFile);
                                }

                                DirectoryReference IntermediateSourceDirectory = DirectoryReference.Combine(ExtensionDir, "Intermediate", "Source");
                                if (DirectoryLookupCache.DirectoryExists(IntermediateSourceDirectory))
                                {
                                    FindTargetFiles(IntermediateSourceDirectory, TargetNameToProjectFile, ProjectFile);
                                }
                            }
                        }
                        CachedTargetNameToProjectFile = TargetNameToProjectFile;
                    }
                }
            }
            return(CachedTargetNameToProjectFile.TryGetValue(InTargetName, out OutProjectFileName));
        }
Пример #2
0
        /// <summary>
        /// Enumerates all the plugin files available to the given project
        /// </summary>
        /// <param name="ProjectFile">Path to the project file</param>
        /// <returns>List of project files</returns>
        public static IEnumerable <FileReference> EnumeratePlugins(FileReference ProjectFile)
        {
            List <DirectoryReference> BaseDirs = new List <DirectoryReference>();

            BaseDirs.AddRange(UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory, "Plugins"));
            BaseDirs.AddRange(UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EnterpriseDirectory, "Plugins"));
            if (ProjectFile != null)
            {
                BaseDirs.AddRange(UnrealBuildTool.GetExtensionDirs(ProjectFile.Directory, "Plugins"));
                BaseDirs.AddRange(UnrealBuildTool.GetExtensionDirs(ProjectFile.Directory, "Mods"));
            }
            return(BaseDirs.SelectMany(x => EnumeratePlugins(x)).ToList());
        }
Пример #3
0
        /// <summary>
        /// Scans a project directory, adding tasks for subdirectories
        /// </summary>
        /// <param name="ProjectDirectory">The project directory to search</param>
        static void ScanProjectDirectory(DirectoryItem ProjectDirectory)
        {
            foreach (DirectoryReference ExtensionDir in UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory))
            {
                DirectoryItem BaseDirectory = DirectoryItem.GetItemByDirectoryReference(ExtensionDir);
                BaseDirectory.CacheDirectories();

                DirectoryItem BasePluginsDirectory = DirectoryItem.Combine(ProjectDirectory, "Plugins");
                Enqueue(() => ScanPluginFolder(BasePluginsDirectory));

                DirectoryItem BaseSourceDirectory = DirectoryItem.Combine(ProjectDirectory, "Source");
                Enqueue(() => ScanDirectoryTree(BaseSourceDirectory));
            }
        }
Пример #4
0
        /// <summary>
        /// Read all the plugin descriptors under the given directory
        /// </summary>
        /// <param name="RootDirectory">The directory to look in.</param>
        /// <param name="Subdirectory">A subdirectory to look in in RootDirectory and any other Platform directories under Root</param>
        /// <param name="Type">The plugin type</param>
        /// <returns>Sequence of the found PluginInfo object.</returns>
        public static IReadOnlyList <PluginInfo> ReadPluginsFromDirectory(DirectoryReference RootDirectory, string Subdirectory, PluginType Type)
        {
            // look for directories in RootDirectory and and extension directories under RootDirectory
            List <DirectoryReference> RootDirectories = UnrealBuildTool.GetExtensionDirs(RootDirectory, Subdirectory);

            Dictionary <PluginInfo, FileReference> ChildPlugins = new Dictionary <PluginInfo, FileReference>();
            List <PluginInfo> AllParentPlugins = new List <PluginInfo>();

            foreach (DirectoryReference Dir in RootDirectories)
            {
                if (!DirectoryReference.Exists(Dir))
                {
                    continue;
                }

                List <PluginInfo> Plugins;
                if (!PluginInfoCache.TryGetValue(Dir, out Plugins))
                {
                    Plugins = new List <PluginInfo>();
                    foreach (FileReference PluginFileName in EnumeratePlugins(Dir))
                    {
                        PluginInfo Plugin = new PluginInfo(PluginFileName, Type);

                        // is there a parent to merge up into?
                        if (Plugin.Descriptor.bIsPluginExtension)
                        {
                            ChildPlugins.Add(Plugin, PluginFileName);
                        }
                        else
                        {
                            Plugins.Add(Plugin);
                        }
                    }
                    PluginInfoCache.Add(Dir, Plugins);
                }

                // gather all of the plugins into one list
                AllParentPlugins.AddRange(Plugins);
            }

            // now that all parent plugins are read in, we can let the children look up the parents
            foreach (KeyValuePair <PluginInfo, FileReference> Pair in ChildPlugins)
            {
                TryMergeWithParent(Pair.Key, Pair.Value);
            }

            return(AllParentPlugins);
        }
Пример #5
0
        /// <summary>
        /// Scans the engine directory, adding tasks for subdirectories
        /// </summary>
        static void ScanEngineDirectory()
        {
            foreach (DirectoryReference ExtensionDir in UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory))
            {
                DirectoryItem BaseDirectory = DirectoryItem.GetItemByDirectoryReference(ExtensionDir);
                BaseDirectory.CacheDirectories();

                DirectoryItem BasePluginsDirectory = DirectoryItem.Combine(BaseDirectory, "Plugins");
                Enqueue(() => ScanPluginFolder(BasePluginsDirectory));

                DirectoryItem BaseSourceDirectory = DirectoryItem.Combine(BaseDirectory, "Source");
                BaseSourceDirectory.CacheDirectories();

                DirectoryItem BaseSourceRuntimeDirectory = DirectoryItem.Combine(BaseSourceDirectory, "Runtime");
                Enqueue(() => ScanDirectoryTree(BaseSourceRuntimeDirectory));

                DirectoryItem BaseSourceDeveloperDirectory = DirectoryItem.Combine(BaseSourceDirectory, "Developer");
                Enqueue(() => ScanDirectoryTree(BaseSourceDeveloperDirectory));

                DirectoryItem BaseSourceEditorDirectory = DirectoryItem.Combine(BaseSourceDirectory, "Editor");
                Enqueue(() => ScanDirectoryTree(BaseSourceEditorDirectory));
            }
        }
        /// <summary>
        /// Return all data driven infos found
        /// </summary>
        /// <returns></returns>
        public static Dictionary <string, ConfigDataDrivenPlatformInfo> GetAllPlatformInfos()
        {
            // need to init?
            if (PlatformInfos == null)
            {
                PlatformInfos = new Dictionary <string, ConfigDataDrivenPlatformInfo>();
                Dictionary <string, string> IniParents = new Dictionary <string, string>();

                // find all platform directories (skipping NFL/NoRedist)
                foreach (DirectoryReference EngineConfigDir in UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory, "Config", bIncludeRestrictedDirectories:false))
                {
                    // look through all config dirs looking for the data driven ini file
                    foreach (string FilePath in Directory.EnumerateFiles(EngineConfigDir.FullName, "DataDrivenPlatformInfo.ini", SearchOption.AllDirectories))
                    {
                        FileReference FileRef = new FileReference(FilePath);

                        // get the platform name from the path
                        string IniPlatformName;
                        if (FileRef.IsUnderDirectory(DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Config")))
                        {
                            // Foo/Engine/Config/<Platform>/DataDrivenPlatformInfo.ini
                            IniPlatformName = Path.GetFileName(Path.GetDirectoryName(FilePath));
                        }
                        else
                        {
                            // Foo/Engine/Platforms/<Platform>/Config/DataDrivenPlatformInfo.ini
                            IniPlatformName = Path.GetFileName(Path.GetDirectoryName(Path.GetDirectoryName(FilePath)));
                        }

                        // load the DataDrivenPlatformInfo from the path (with Add support in a file that doesn't use +'s in the arrays for C++ usage)
                        ConfigFile Config = new ConfigFile(FileRef, ConfigLineAction.Add);
                        ConfigDataDrivenPlatformInfo NewInfo = new ConfigDataDrivenPlatformInfo();


                        // we must have the key section
                        ConfigFileSection Section = null;
                        if (Config.TryGetSection("DataDrivenPlatformInfo", out Section))
                        {
                            ConfigHierarchySection ParsedSection = new ConfigHierarchySection(new List <ConfigFileSection>()
                            {
                                Section
                            });

                            // get string values
                            string IniParent;
                            if (ParsedSection.TryGetValue("IniParent", out IniParent))
                            {
                                IniParents[IniPlatformName] = IniParent;
                            }

                            // slightly nasty bool parsing for bool values
                            string Temp;
                            if (ParsedSection.TryGetValue("bIsConfidential", out Temp) == false || ConfigHierarchy.TryParse(Temp, out NewInfo.bIsConfidential) == false)
                            {
                                NewInfo.bIsConfidential = false;
                            }

                            // get a list of additional restricted folders
                            IReadOnlyList <string> AdditionalRestrictedFolders;
                            if (ParsedSection.TryGetValues("AdditionalRestrictedFolders", out AdditionalRestrictedFolders) && AdditionalRestrictedFolders.Count > 0)
                            {
                                NewInfo.AdditionalRestrictedFolders = AdditionalRestrictedFolders.Select(x => x.Trim()).Where(x => x.Length > 0).ToArray();
                            }

                            // create cache it
                            PlatformInfos[IniPlatformName] = NewInfo;
                        }
                    }
                }

                // now that all are read in, calculate the ini parent chain, starting with parent-most
                foreach (KeyValuePair <string, ConfigDataDrivenPlatformInfo> Pair in PlatformInfos)
                {
                    string CurrentPlatform;

                    // walk up the chain and build up the ini chain
                    List <string> Chain = new List <string>();
                    if (IniParents.TryGetValue(Pair.Key, out CurrentPlatform))
                    {
                        while (!string.IsNullOrEmpty(CurrentPlatform))
                        {
                            // insert at 0 to reverse the order
                            Chain.Insert(0, CurrentPlatform);
                            if (IniParents.TryGetValue(CurrentPlatform, out CurrentPlatform) == false)
                            {
                                break;
                            }
                        }
                    }

                    // bake it into the info
                    if (Chain.Count > 0)
                    {
                        Pair.Value.IniParentChain = Chain.ToArray();
                    }
                }
            }

            return(PlatformInfos);
        }
Пример #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="RulesFileType"></param>
        /// <param name="GameFolders"></param>
        /// <param name="ForeignPlugins"></param>
        /// <param name="AdditionalSearchPaths"></param>
        /// <param name="bIncludeEngine"></param>
        /// <param name="bIncludeEnterprise"></param>
        /// <param name="bIncludeTempTargets">Whether to include targets generated by UAT to accomodate content-only projects that need to be compiled to include plugins</param>
        /// <returns></returns>
        public static List <FileReference> FindAllRulesSourceFiles(RulesFileType RulesFileType, List <DirectoryReference> GameFolders, List <FileReference> ForeignPlugins, List <DirectoryReference> AdditionalSearchPaths, bool bIncludeEngine = true, bool bIncludeEnterprise = true, bool bIncludeTempTargets = true)
        {
            List <DirectoryReference> Folders = new List <DirectoryReference>();

            // Add all engine source (including third party source)
            if (bIncludeEngine)
            {
                Folders.AddRange(UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory, "Source"));
            }
            if (bIncludeEnterprise)
            {
                Folders.Add(UnrealBuildTool.EnterpriseSourceDirectory);
            }

            // @todo plugin: Disallow modules from including plugin modules as dependency modules? (except when the module is part of that plugin)

            // Get all the root folders for plugins
            List <DirectoryReference> RootFolders = new List <DirectoryReference>();

            if (bIncludeEngine)
            {
                RootFolders.AddRange(UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory));
            }
            if (bIncludeEnterprise)
            {
                RootFolders.Add(UnrealBuildTool.EnterpriseDirectory);
            }
            if (GameFolders != null)
            {
                RootFolders.AddRange(GameFolders.SelectMany(x => UnrealBuildTool.GetExtensionDirs(x)));
            }

            // Find all the plugin source directories
            foreach (DirectoryReference RootFolder in RootFolders)
            {
                DirectoryReference PluginsFolder = DirectoryReference.Combine(RootFolder, "Plugins");
                foreach (FileReference PluginFile in Plugins.EnumeratePlugins(PluginsFolder))
                {
                    Folders.Add(DirectoryReference.Combine(PluginFile.Directory, "Source"));
                }
            }

            // Add all the extra plugin folders
            if (ForeignPlugins != null)
            {
                foreach (FileReference ForeignPlugin in ForeignPlugins)
                {
                    Folders.Add(DirectoryReference.Combine(ForeignPlugin.Directory, "Source"));
                }
            }

            // Add in the game folders to search
            if (GameFolders != null)
            {
                foreach (DirectoryReference GameFolder in GameFolders)
                {
                    Folders.AddRange(UnrealBuildTool.GetExtensionDirs(GameFolder, "Source"));

                    if (bIncludeTempTargets)
                    {
                        DirectoryReference GameIntermediateSourceFolder = DirectoryReference.Combine(GameFolder, "Intermediate", "Source");
                        Folders.Add(GameIntermediateSourceFolder);
                    }
                }
            }

            // Process the additional search path, if sent in
            if (AdditionalSearchPaths != null)
            {
                foreach (DirectoryReference AdditionalSearchPath in AdditionalSearchPaths)
                {
                    if (AdditionalSearchPath != null)
                    {
                        if (DirectoryReference.Exists(AdditionalSearchPath))
                        {
                            Folders.Add(AdditionalSearchPath);
                        }
                        else
                        {
                            throw new BuildException("Couldn't find AdditionalSearchPath for rules source files '{0}'", AdditionalSearchPath);
                        }
                    }
                }
            }

            // Iterate over all the folders to check
            List <FileReference>    SourceFiles       = new List <FileReference>();
            HashSet <FileReference> UniqueSourceFiles = new HashSet <FileReference>();

            foreach (DirectoryReference Folder in Folders)
            {
                IReadOnlyList <FileReference> SourceFilesForFolder = FindAllRulesFiles(Folder, RulesFileType);
                foreach (FileReference SourceFile in SourceFilesForFolder)
                {
                    if (UniqueSourceFiles.Add(SourceFile))
                    {
                        SourceFiles.Add(SourceFile);
                    }
                }
            }
            return(SourceFiles);
        }
Пример #8
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 = UnrealBuildTool.GetExtensionDirs(ProjectFileName.Directory);
                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);
        }
Пример #9
0
        /// <summary>
        /// Creates the engine rules assembly
        /// </summary>
        /// <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 CreateEngineRulesAssembly(bool bUsePrecompiled, bool bSkipCompile)
        {
            if (EngineRulesAssembly == null)
            {
                List <PluginInfo> IncludedPlugins = new List <PluginInfo>();

                // search for all engine plugins
                IncludedPlugins.AddRange(Plugins.ReadEnginePlugins(UnrealBuildTool.EngineDirectory));

                RulesScope EngineScope = new RulesScope("Engine", null);

                EngineRulesAssembly = CreateEngineOrEnterpriseRulesAssembly(EngineScope, UnrealBuildTool.GetExtensionDirs(UnrealBuildTool.EngineDirectory), ProjectFileGenerator.EngineProjectFileNameBase, IncludedPlugins, UnrealBuildTool.IsEngineInstalled() || bUsePrecompiled, bSkipCompile, null);
            }
            return(EngineRulesAssembly);
        }