Ejemplo n.º 1
0
 /// <summary>
 /// Scans an arbitrary directory tree
 /// </summary>
 /// <param name="Directory">Root of the directory tree</param>
 static void ScanDirectoryTree(DirectoryItem Directory)
 {
     foreach (DirectoryItem SubDirectory in Directory.EnumerateDirectories())
     {
         Enqueue(() => ScanDirectoryTree(SubDirectory));
     }
     Directory.CacheFiles();
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Scans a plugin parent directory, adding tasks for subdirectories
 /// </summary>
 /// <param name="Directory">The directory which may contain plugin directories</param>
 static void ScanPluginFolder(DirectoryItem Directory)
 {
     foreach (DirectoryItem SubDirectory in Directory.EnumerateDirectories())
     {
         if (SubDirectory.EnumerateFiles().Any(x => x.HasExtension(".uplugin")))
         {
             Enqueue(() => ScanDirectoryTree(DirectoryItem.Combine(SubDirectory, "Source")));
         }
         else
         {
             Enqueue(() => ScanPluginFolder(SubDirectory));
         }
     }
 }
Ejemplo n.º 3
0
        /// <summary>
        /// Finds all the source files under a directory that contain reflection markup
        /// </summary>
        /// <param name="Directory">The directory to search</param>
        /// <param name="MetadataCache">Cache of source file metadata</param>
        /// <param name="ExcludedFolderNames">Set of folder names to ignore when recursing the directory tree</param>
        /// <param name="FilesWithMarkup">Receives the set of files which contain reflection markup</param>
        /// <param name="Queue">Queue to add sub-tasks to</param>
        static void FindFilesWithMarkup(DirectoryItem Directory, SourceFileMetadataCache MetadataCache, ReadOnlyHashSet <string> ExcludedFolderNames, ConcurrentBag <FileItem> FilesWithMarkup, ThreadPoolWorkQueue Queue)
        {
            // Search through all the subfolders
            foreach (DirectoryItem SubDirectory in Directory.EnumerateDirectories())
            {
                if (!ExcludedFolderNames.Contains(SubDirectory.Name))
                {
                    Queue.Enqueue(() => FindFilesWithMarkup(SubDirectory, MetadataCache, ExcludedFolderNames, FilesWithMarkup, Queue));
                }
            }

            // Check for all the headers in this folder
            foreach (FileItem File in Directory.EnumerateFiles())
            {
                if (File.HasExtension(".h") && MetadataCache.ContainsReflectionMarkup(File))
                {
                    FilesWithMarkup.Add(File);
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Search through a directory tree for any rules files
        /// </summary>
        /// <param name="Directory">The root directory to search from</param>
        /// <param name="Cache">Receives all the discovered rules files</param>
        /// <param name="Queue">Queue for adding additional tasks to</param>
        private static void FindAllRulesFilesRecursively(DirectoryItem Directory, RulesFileCache Cache, ThreadPoolWorkQueue Queue)
        {
            // Scan all the files in this directory
            bool bSearchSubFolders = true;

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

            // If we didn't find anything to stop the search, search all the subdirectories too
            if (bSearchSubFolders)
            {
                foreach (DirectoryItem SubDirectory in Directory.EnumerateDirectories())
                {
                    Queue.Enqueue(() => FindAllRulesFilesRecursively(SubDirectory, Cache, Queue));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Determines if a directory, or any subdirectory of it, contains new source files
        /// </summary>
        /// <param name="Directory">Directory to search through</param>
        /// <param name="ExcludedFolderNames">Set of directory names to exclude</param>
        /// <returns>True if the directory contains any source files</returns>
        static bool ContainsSourceFiles(DirectoryItem Directory, ReadOnlyHashSet <string> ExcludedFolderNames)
        {
            // Check this directory isn't ignored
            if (!ExcludedFolderNames.Contains(Directory.Name))
            {
                // Check for any source files in this actual directory
                FileItem[] SourceFiles = UEBuildModuleCPP.GetSourceFiles(Directory);
                if (SourceFiles.Length > 0)
                {
                    return(true);
                }

                // Check for any source files in a subdirectory
                foreach (DirectoryItem SubDirectory in Directory.EnumerateDirectories())
                {
                    if (ContainsSourceFiles(SubDirectory, ExcludedFolderNames))
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Find paths to all the plugins under a given parent directory (recursively)
        /// </summary>
        /// <param name="ParentDirectory">Parent directory to look in. Plugins will be found in any *subfolders* of this directory.</param>
        /// <param name="FileNames">List of filenames. Will have all the discovered .uplugin files appended to it.</param>
        /// <param name="Queue">Queue for tasks to be executed</param>
        static void EnumeratePluginsInternal(DirectoryItem ParentDirectory, List <FileReference> FileNames, ThreadPoolWorkQueue Queue)
        {
            foreach (DirectoryItem ChildDirectory in ParentDirectory.EnumerateDirectories())
            {
                bool bSearchSubDirectories = true;
                foreach (FileItem PluginFile in ChildDirectory.EnumerateFiles())
                {
                    if (PluginFile.HasExtension(".uplugin"))
                    {
                        lock (FileNames)
                        {
                            FileNames.Add(PluginFile.Location);
                        }
                        bSearchSubDirectories = false;
                    }
                }

                if (bSearchSubDirectories)
                {
                    Queue.Enqueue(() => EnumeratePluginsInternal(ChildDirectory, FileNames, Queue));
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Checks if the makefile is valid for the current set of source files. This is done separately to the Load() method to allow pre-build steps to modify source files.
        /// </summary>
        /// <param name="Makefile">The makefile that has been loaded</param>
        /// <param name="ProjectFile">Path to the project file</param>
        /// <param name="Platform">The platform being built</param>
        /// <param name="WorkingSet">The current working set of source files</param>
        /// <param name="ReasonNotLoaded">If the makefile is not valid, is set to a message describing why</param>
        /// <returns>True if the makefile is valid, false otherwise</returns>
        public static bool IsValidForSourceFiles(TargetMakefile Makefile, FileReference ProjectFile, UnrealTargetPlatform Platform, ISourceFileWorkingSet WorkingSet, out string ReasonNotLoaded)
        {
            using (Timeline.ScopeEvent("TargetMakefile.IsValidForSourceFiles()"))
            {
                // Get the list of excluded folder names for this platform
                ReadOnlyHashSet <string> ExcludedFolderNames = UEBuildPlatform.GetBuildPlatform(Platform).GetExcludedFolderNames();

                // Check if any source files have been added or removed
                foreach (KeyValuePair <DirectoryItem, FileItem[]> Pair in Makefile.DirectoryToSourceFiles)
                {
                    DirectoryItem InputDirectory = Pair.Key;
                    if (!InputDirectory.Exists || InputDirectory.LastWriteTimeUtc > Makefile.CreateTimeUtc)
                    {
                        FileItem[] SourceFiles = UEBuildModuleCPP.GetSourceFiles(InputDirectory);
                        if (SourceFiles.Length < Pair.Value.Length)
                        {
                            ReasonNotLoaded = "source file removed";
                            return(false);
                        }
                        else if (SourceFiles.Length > Pair.Value.Length)
                        {
                            ReasonNotLoaded = "source file added";
                            return(false);
                        }
                        else if (SourceFiles.Intersect(Pair.Value).Count() != SourceFiles.Length)
                        {
                            ReasonNotLoaded = "source file modified";
                            return(false);
                        }

                        foreach (DirectoryItem Directory in InputDirectory.EnumerateDirectories())
                        {
                            if (!Makefile.DirectoryToSourceFiles.ContainsKey(Directory) && ContainsSourceFiles(Directory, ExcludedFolderNames))
                            {
                                ReasonNotLoaded = "directory added";
                                return(false);
                            }
                        }
                    }
                }

                // Check if any external dependencies have changed. These comparisons are done against the makefile creation time.
                foreach (FileItem ExternalDependency in Makefile.ExternalDependencies)
                {
                    if (!ExternalDependency.Exists)
                    {
                        Log.TraceLog("{0} has been deleted since makefile was built.", ExternalDependency.Location);
                        ReasonNotLoaded = string.Format("{0} deleted", ExternalDependency.Location.GetFileName());
                        return(false);
                    }
                    if (ExternalDependency.LastWriteTimeUtc > Makefile.CreateTimeUtc)
                    {
                        Log.TraceLog("{0} has been modified since makefile was built.", ExternalDependency.Location);
                        ReasonNotLoaded = string.Format("{0} modified", ExternalDependency.Location.GetFileName());
                        return(false);
                    }
                }

                // Check if any internal dependencies has changed. These comparisons are done against the makefile modified time.
                foreach (FileItem InternalDependency in Makefile.InternalDependencies)
                {
                    if (!InternalDependency.Exists)
                    {
                        Log.TraceLog("{0} has been deleted since makefile was written.", InternalDependency.Location);
                        ReasonNotLoaded = string.Format("{0} deleted", InternalDependency.Location.GetFileName());
                        return(false);
                    }
                    if (InternalDependency.LastWriteTimeUtc > Makefile.ModifiedTimeUtc)
                    {
                        Log.TraceLog("{0} has been modified since makefile was written.", InternalDependency.Location);
                        ReasonNotLoaded = string.Format("{0} modified", InternalDependency.Location.GetFileName());
                        return(false);
                    }
                }

                // Check that no new plugins have been added
                foreach (FileReference PluginFile in Plugins.EnumeratePlugins(ProjectFile))
                {
                    FileItem PluginFileItem = FileItem.GetItemByFileReference(PluginFile);
                    if (!Makefile.PluginFiles.Contains(PluginFileItem))
                    {
                        Log.TraceLog("{0} has been added", PluginFile.GetFileName());
                        ReasonNotLoaded = string.Format("{0} has been added", PluginFile.GetFileName());
                        return(false);
                    }
                }

                // Load the metadata cache
                SourceFileMetadataCache MetadataCache = SourceFileMetadataCache.CreateHierarchy(ProjectFile);

                // Find the set of files that contain reflection markup
                ConcurrentBag <FileItem> NewFilesWithMarkupBag = new ConcurrentBag <FileItem>();
                using (ThreadPoolWorkQueue Queue = new ThreadPoolWorkQueue())
                {
                    foreach (DirectoryItem SourceDirectory in Makefile.SourceDirectories)
                    {
                        Queue.Enqueue(() => FindFilesWithMarkup(SourceDirectory, MetadataCache, ExcludedFolderNames, NewFilesWithMarkupBag, Queue));
                    }
                }

                // Check whether the list has changed
                List <FileItem> PrevFilesWithMarkup = Makefile.UObjectModuleHeaders.Where(x => !x.bUsePrecompiled).SelectMany(x => x.HeaderFiles).ToList();
                List <FileItem> NextFilesWithMarkup = NewFilesWithMarkupBag.ToList();
                if (NextFilesWithMarkup.Count != PrevFilesWithMarkup.Count || NextFilesWithMarkup.Intersect(PrevFilesWithMarkup).Count() != PrevFilesWithMarkup.Count)
                {
                    ReasonNotLoaded = "UHT files changed";
                    return(false);
                }

                // If adaptive unity build is enabled, do a check to see if there are any source files that became part of the
                // working set since the Makefile was created (or, source files were removed from the working set.)  If anything
                // changed, then we'll force a new Makefile to be created so that we have fresh unity build blobs.  We always
                // want to make sure that source files in the working set are excluded from those unity blobs (for fastest possible
                // iteration times.)

                // Check if any source files in the working set no longer belong in it
                foreach (FileItem SourceFile in Makefile.WorkingSet)
                {
                    if (!WorkingSet.Contains(SourceFile) && SourceFile.LastWriteTimeUtc > Makefile.CreateTimeUtc)
                    {
                        Log.TraceLog("{0} was part of source working set and now is not; invalidating makefile", SourceFile.AbsolutePath);
                        ReasonNotLoaded = string.Format("working set of source files changed");
                        return(false);
                    }
                }

                // Check if any source files that are eligible for being in the working set have been modified
                foreach (FileItem SourceFile in Makefile.CandidatesForWorkingSet)
                {
                    if (WorkingSet.Contains(SourceFile) && SourceFile.LastWriteTimeUtc > Makefile.CreateTimeUtc)
                    {
                        Log.TraceLog("{0} was part of source working set and now is not", SourceFile.AbsolutePath);
                        ReasonNotLoaded = string.Format("working set of source files changed");
                        return(false);
                    }
                }
            }

            ReasonNotLoaded = null;
            return(true);
        }