Ejemplo n.º 1
0
        /// <summary>
        /// Invalidate the cache for the givcen directory
        /// </summary>
        /// <param name="DirectoryPath">Directory to invalidate</param>
        public static void InvalidateRulesFileCache(string DirectoryPath)
        {
            DirectoryReference Directory = new DirectoryReference(DirectoryPath);

            RootFolderToRulesFileCache.Remove(Directory);
            DirectoryLookupCache.InvalidateCachedDirectory(Directory);
        }
Ejemplo n.º 2
0
        private static void FindAllRulesFilesRecursively(DirectoryReference Directory, RulesFileCache Cache)
        {
            // Scan all the files in this directory
            bool bSearchSubFolders = true;

            foreach (FileReference File in DirectoryLookupCache.EnumerateFiles(Directory))
            {
                if (File.HasExtension(".build.cs"))
                {
                    Cache.ModuleRules.Add(File);
                    bSearchSubFolders = false;
                }
                else if (File.HasExtension(".target.cs"))
                {
                    Cache.TargetRules.Add(File);
                }
                else if (File.HasExtension(".automation.csproj"))
                {
                    Cache.AutomationModules.Add(File);
                    bSearchSubFolders = false;
                }
            }

            // If we didn't find anything to stop the search, search all the subdirectories too
            if (bSearchSubFolders)
            {
                foreach (DirectoryReference SubDirectory in DirectoryLookupCache.EnumerateDirectories(Directory))
                {
                    FindAllRulesFilesRecursively(SubDirectory, Cache);
                }
            }
        }
Ejemplo n.º 3
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())
                        {
                            DirectoryReference SourceDirectory = DirectoryReference.Combine(ProjectFile.Directory, "Source");
                            if (DirectoryLookupCache.DirectoryExists(SourceDirectory))
                            {
                                FindTargetFiles(SourceDirectory, TargetNameToProjectFile, ProjectFile);
                            }

                            DirectoryReference IntermediateSourceDirectory = DirectoryReference.Combine(ProjectFile.Directory, "Intermediate", "Source");
                            if (DirectoryLookupCache.DirectoryExists(IntermediateSourceDirectory))
                            {
                                FindTargetFiles(IntermediateSourceDirectory, TargetNameToProjectFile, ProjectFile);
                            }
                        }
                        CachedTargetNameToProjectFile = TargetNameToProjectFile;
                    }
                }
            }
            return(CachedTargetNameToProjectFile.TryGetValue(InTargetName, out OutProjectFileName));
        }
Ejemplo n.º 4
0
 /// <summary>
 /// Returns a list of all the projects
 /// </summary>
 /// <returns>List of projects</returns>
 public static IEnumerable <FileReference> EnumerateProjectFiles()
 {
     if (CachedProjectFiles == null)
     {
         lock (LockObject)
         {
             if (CachedProjectFiles == null)
             {
                 HashSet <FileReference> ProjectFiles = new HashSet <FileReference>();
                 foreach (DirectoryReference BaseDirectory in EnumerateBaseDirectories())
                 {
                     if (DirectoryLookupCache.DirectoryExists(BaseDirectory))
                     {
                         foreach (DirectoryReference SubDirectory in DirectoryLookupCache.EnumerateDirectories(BaseDirectory))
                         {
                             foreach (FileReference File in DirectoryLookupCache.EnumerateFiles(SubDirectory))
                             {
                                 if (File.HasExtension(".uproject"))
                                 {
                                     ProjectFiles.Add(File);
                                 }
                             }
                         }
                     }
                 }
                 CachedProjectFiles = ProjectFiles;
             }
         }
     }
     return(CachedProjectFiles);
 }
Ejemplo n.º 5
0
        /// <summary>
        /// Creates a rules assembly
        /// </summary>
        /// <param name="RootDirectory">The root directory 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(DirectoryReference RootDirectory, string AssemblyPrefix, IReadOnlyList <PluginInfo> Plugins, bool bReadOnly, bool bSkipCompile, RulesAssembly Parent)
        {
            DirectoryReference SourceDirectory   = DirectoryReference.Combine(RootDirectory, "Source");
            DirectoryReference ProgramsDirectory = DirectoryReference.Combine(SourceDirectory, "Programs");

            // Find the shared modules, excluding the programs directory. These are used to create an assembly with the bContainsEngineModules flag set to true.
            List <FileReference> EngineModuleFiles = new List <FileReference>();

            using (Timeline.ScopeEvent("Finding engine modules"))
            {
                foreach (DirectoryReference SubDirectory in DirectoryLookupCache.EnumerateDirectories(SourceDirectory))
                {
                    if (SubDirectory != ProgramsDirectory)
                    {
                        EngineModuleFiles.AddRange(FindAllRulesFiles(SubDirectory, RulesFileType.Module));
                    }
                }
            }

            // Add all the plugin modules too
            Dictionary <FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary <FileReference, PluginInfo>();

            using (Timeline.ScopeEvent("Finding plugin modules"))
            {
                FindModuleRulesForPlugins(Plugins, EngineModuleFiles, ModuleFileToPluginInfo);
            }

            // Create the assembly
            FileReference EngineAssemblyFileName = FileReference.Combine(RootDirectory, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension);
            RulesAssembly EngineAssembly         = new RulesAssembly(RootDirectory, Plugins, EngineModuleFiles, new List <FileReference>(), ModuleFileToPluginInfo, EngineAssemblyFileName, bContainsEngineModules: true, bUseBackwardsCompatibleDefaults: false, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: Parent);

            // Find all the rules files
            List <FileReference> ProgramModuleFiles;

            using (Timeline.ScopeEvent("Finding program modules"))
            {
                ProgramModuleFiles = new List <FileReference>(FindAllRulesFiles(ProgramsDirectory, RulesFileType.Module));
            }
            List <FileReference> ProgramTargetFiles;

            using (Timeline.ScopeEvent("Finding program targets"))
            {
                ProgramTargetFiles = new List <FileReference>(FindAllRulesFiles(SourceDirectory, RulesFileType.Target));
            }

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

            // Return the combined assembly
            return(ProgramAssembly);
        }
Ejemplo n.º 6
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);
            }
        }
        /// <summary>
        /// Converts an optional string list parameter to a well-defined hash set.
        /// </summary>
        protected HashSet <DirectoryReference> CreateDirectoryHashSet(IEnumerable <string> InEnumerableStrings)
        {
            HashSet <DirectoryReference> Directories = new HashSet <DirectoryReference>();

            if (InEnumerableStrings != null)
            {
                foreach (string InputString in InEnumerableStrings)
                {
                    DirectoryReference Dir = new DirectoryReference(ExpandPathVariables(InputString, null, null));
                    if (DirectoryLookupCache.DirectoryExists(Dir))
                    {
                        Directories.Add(Dir);
                    }
                    else
                    {
                        Log.WriteLineOnce(LogEventType.Warning, LogFormatOptions.NoSeverityPrefix, "{0}: warning: Referenced directory '{1}' does not exist.", RulesFile, Dir);
                    }
                }
            }
            return(Directories);
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Retrieve the list of base directories for native projects
 /// </summary>
 public static IEnumerable <DirectoryReference> EnumerateBaseDirectories()
 {
     if (CachedBaseDirectories == null)
     {
         lock (LockObject)
         {
             if (CachedBaseDirectories == null)
             {
                 HashSet <DirectoryReference> BaseDirs = new HashSet <DirectoryReference>();
                 foreach (FileReference RootFile in DirectoryLookupCache.EnumerateFiles(UnrealBuildTool.RootDirectory))
                 {
                     if (RootFile.HasExtension(".uprojectdirs"))
                     {
                         foreach (string Line in File.ReadAllLines(RootFile.FullName))
                         {
                             string TrimLine = Line.Trim();
                             if (!TrimLine.StartsWith(";"))
                             {
                                 DirectoryReference BaseProjectDir = DirectoryReference.Combine(UnrealBuildTool.RootDirectory, TrimLine);
                                 if (BaseProjectDir.IsUnderDirectory(UnrealBuildTool.RootDirectory))
                                 {
                                     BaseDirs.Add(BaseProjectDir);
                                 }
                                 else
                                 {
                                     Log.TraceWarning("Project search path '{0}' referenced by '{1}' is not under '{2}', ignoring.", TrimLine, RootFile, UnrealBuildTool.RootDirectory);
                                 }
                             }
                         }
                     }
                 }
                 CachedBaseDirectories = BaseDirs;
             }
         }
     }
     return(CachedBaseDirectories);
 }
Ejemplo n.º 9
0
        /// <summary>
        /// Finds all target files under a given folder, and add them to the target name to project file map
        /// </summary>
        /// <param name="Directory">Directory to search</param>
        /// <param name="TargetNameToProjectFile">Map from target name to project file</param>
        /// <param name="ProjectFile">The project file for this directory</param>
        private static void FindTargetFiles(DirectoryReference Directory, Dictionary <string, FileReference> TargetNameToProjectFile, FileReference ProjectFile)
        {
            // Search for all target files within this directory
            bool bSearchSubFolders = true;

            foreach (FileReference File in DirectoryLookupCache.EnumerateFiles(Directory))
            {
                if (File.HasExtension(".target.cs"))
                {
                    string TargetName = Path.GetFileNameWithoutExtension(File.GetFileNameWithoutExtension());
                    TargetNameToProjectFile[TargetName] = ProjectFile;
                    bSearchSubFolders = false;
                }
            }

            // If we didn't find anything, recurse through the subfolders
            if (bSearchSubFolders)
            {
                foreach (DirectoryReference SubDirectory in DirectoryLookupCache.EnumerateDirectories(Directory))
                {
                    FindTargetFiles(SubDirectory, TargetNameToProjectFile, ProjectFile);
                }
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Finds the header file that is referred to by a partial include filename.
        /// </summary>
        /// <param name="RelativeIncludePath">path relative to the project</param>
        /// <param name="bSkipExternalHeader">true to skip processing of headers in external path</param>
        /// <param name="SourceFilesDirectory">- The folder containing the source files we're generating a PCH for</param>
        public static FileItem FindIncludedFile(string RelativeIncludePath, bool bSkipExternalHeader, List <string> IncludePathsToSearch, Dictionary <string, FileItem> IncludeFileSearchDictionary)
        {
            FileItem Result = null;

            if (IncludePathsToSearch == null)
            {
                throw new BuildException("Was not expecting IncludePathsToSearch to be empty for file '{0}'!", RelativeIncludePath);
            }

            ++TotalFindIncludedFileCalls;

            // Only search for the include file if the result hasn't been cached.
            string InvariantPath = RelativeIncludePath.ToLowerInvariant();

            if (!IncludeFileSearchDictionary.TryGetValue(InvariantPath, out Result))
            {
                int SearchAttempts = 0;
                if (Path.IsPathRooted(RelativeIncludePath))
                {
                    FileReference Reference = new FileReference(RelativeIncludePath);
                    if (DirectoryLookupCache.FileExists(Reference))
                    {
                        Result = FileItem.GetItemByFileReference(Reference);
                    }
                    ++SearchAttempts;
                }
                else
                {
                    // Find the first include path that the included file exists in.
                    foreach (string IncludePath in IncludePathsToSearch)
                    {
                        ++SearchAttempts;
                        string RelativeFilePath = "";
                        try
                        {
                            RelativeFilePath = Path.Combine(IncludePath, RelativeIncludePath);
                        }
                        catch (ArgumentException Exception)
                        {
                            throw new BuildException(Exception, "Failed to combine null or invalid include paths.");
                        }
                        FileReference FullFilePath = null;
                        try
                        {
                            FullFilePath = new FileReference(RelativeFilePath);
                        }
                        catch (Exception)
                        {
                        }
                        if (FullFilePath != null && DirectoryLookupCache.FileExists(FullFilePath))
                        {
                            Result = FileItem.GetItemByFileReference(FullFilePath);
                            break;
                        }
                    }
                }

                IncludePathSearchAttempts += SearchAttempts;

                if (BuildConfiguration.bPrintPerformanceInfo)
                {
                    // More than two search attempts indicates:
                    //		- Include path was not relative to the directory that the including file was in
                    //		- Include path was not relative to the project's base
                    if (SearchAttempts > 2)
                    {
                        Trace.TraceInformation("   Cache miss: " + RelativeIncludePath + " found after " + SearchAttempts.ToString() + " attempts: " + (Result != null ? Result.AbsolutePath : "NOT FOUND!"));
                    }
                }

                // Cache the result of the include path search.
                IncludeFileSearchDictionary.Add(InvariantPath, Result);
            }

            // @todo ubtmake: The old UBT tried to skip 'external' (STABLE) headers here.  But it didn't work.  We might want to do this though!  Skip system headers and source/thirdparty headers!

            if (Result != null)
            {
                Log.TraceVerbose("Resolved included file \"{0}\" to: {1}", RelativeIncludePath, Result.AbsolutePath);
            }
            else
            {
                Log.TraceVerbose("Couldn't resolve included file \"{0}\"", RelativeIncludePath);
            }

            return(Result);
        }