Beispiel #1
0
        /// <summary>
        /// Prefetch multiple directories in parallel
        /// </summary>
        /// <param name="Directories">The directories to cache</param>
        private static void PrefetchRulesFiles(IEnumerable <DirectoryReference> Directories)
        {
            ThreadPoolWorkQueue Queue = null;

            try
            {
                foreach (DirectoryReference Directory in Directories)
                {
                    if (!RootFolderToRulesFileCache.ContainsKey(Directory))
                    {
                        RulesFileCache Cache = new RulesFileCache();
                        RootFolderToRulesFileCache[Directory] = Cache;

                        if (Queue == null)
                        {
                            Queue = new ThreadPoolWorkQueue();
                        }

                        DirectoryItem DirectoryItem = DirectoryItem.GetItemByDirectoryReference(Directory);
                        Queue.Enqueue(() => FindAllRulesFilesRecursively(DirectoryItem, Cache, Queue));
                    }
                }
            }
            finally
            {
                if (Queue != null)
                {
                    Queue.Dispose();
                    Queue = null;
                }
            }
        }
Beispiel #2
0
        private static IReadOnlyList <FileReference> FindAllRulesFiles(DirectoryReference Directory, RulesFileType Type)
        {
            // Check to see if we've already cached source files for this folder
            RulesFileCache Cache;

            if (!RootFolderToRulesFileCache.TryGetValue(Directory, out Cache))
            {
                Cache = new RulesFileCache();
                FindAllRulesFilesRecursively(Directory, Cache);
                RootFolderToRulesFileCache[Directory] = Cache;
            }

            // Get the list of files of the type we're looking for
            if (Type == RulesCompiler.RulesFileType.Module)
            {
                return(Cache.ModuleRules);
            }
            else if (Type == RulesCompiler.RulesFileType.Target)
            {
                return(Cache.TargetRules);
            }
            else if (Type == RulesCompiler.RulesFileType.AutomationModule)
            {
                return(Cache.AutomationModules);
            }
            else
            {
                throw new BuildException("Unhandled rules type: {0}", Type);
            }
        }
Beispiel #3
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);
				}
			}
		}
Beispiel #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));
                }
            }
        }
Beispiel #5
0
        /// <summary>
        /// Finds all the rules of the given type under a given directory
        /// </summary>
        /// <param name="Directory">Directory to search</param>
        /// <param name="Type">Type of rules to return</param>
        /// <returns>List of rules files of the given type</returns>
        private static IReadOnlyList <FileReference> FindAllRulesFiles(DirectoryReference Directory, RulesFileType Type)
        {
            // Check to see if we've already cached source files for this folder
            RulesFileCache Cache;

            if (!RootFolderToRulesFileCache.TryGetValue(Directory, out Cache))
            {
                Cache = new RulesFileCache();
                using (ThreadPoolWorkQueue Queue = new ThreadPoolWorkQueue())
                {
                    DirectoryItem BaseDirectory = DirectoryItem.GetItemByDirectoryReference(Directory);
                    Queue.Enqueue(() => FindAllRulesFilesRecursively(BaseDirectory, Cache, Queue));
                }
                Cache.ModuleRules.Sort((A, B) => A.FullName.CompareTo(B.FullName));
                Cache.TargetRules.Sort((A, B) => A.FullName.CompareTo(B.FullName));
                Cache.AutomationModules.Sort((A, B) => A.FullName.CompareTo(B.FullName));
                RootFolderToRulesFileCache[Directory] = Cache;
            }

            // Get the list of files of the type we're looking for
            if (Type == RulesCompiler.RulesFileType.Module)
            {
                return(Cache.ModuleRules);
            }
            else if (Type == RulesCompiler.RulesFileType.Target)
            {
                return(Cache.TargetRules);
            }
            else if (Type == RulesCompiler.RulesFileType.AutomationModule)
            {
                return(Cache.AutomationModules);
            }
            else
            {
                throw new BuildException("Unhandled rules type: {0}", Type);
            }
        }
Beispiel #6
0
		public static List<string> FindAllRulesSourceFiles( RulesFileType RulesFileType, List<string> AdditionalSearchPaths )
		{
			List<string> Folders = new List<string>();

			// Add all engine source (including third party source)
			Folders.Add( Path.Combine( ProjectFileGenerator.EngineRelativePath, "Source" ) );

			// @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<string> RootFolders = new List<string>();
			RootFolders.Add(ProjectFileGenerator.EngineRelativePath);
			RootFolders.AddRange(AllGameFolders);

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

			// Add all the extra plugin folders
			if( ForeignPlugins != null )
			{
				foreach(string ForeignPlugin in ForeignPlugins)
				{
					string PluginDirectory = Path.GetDirectoryName(Path.GetFullPath(ForeignPlugin));
					Folders.Add(Path.Combine(PluginDirectory, "Source"));
				}
			}

			// Add in the game folders to search
			if( AllGameFolders != null )
			{
				foreach( var GameFolder in AllGameFolders )
				{
					var GameSourceFolder = Path.GetFullPath(Path.Combine( GameFolder, "Source" ));
					Folders.Add( GameSourceFolder );
					var GameIntermediateSourceFolder = Path.GetFullPath(Path.Combine(GameFolder, "Intermediate", "Source"));
					Folders.Add(GameIntermediateSourceFolder);
				}
			}

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

			var SourceFiles = new List<string>();

			// Iterate over all the folders to check
			foreach( string Folder in Folders )
			{
				// Check to see if we've already cached source files for this folder
				RulesFileCache FolderRulesFileCache;
				if (!RootFolderToRulesFileCache.TryGetValue(Folder, out FolderRulesFileCache))
				{
					FolderRulesFileCache = new RulesFileCache();
					FindAllRulesFilesRecursively(new DirectoryInfo(Folder), FolderRulesFileCache);
					RootFolderToRulesFileCache[Folder] = FolderRulesFileCache;

					if (BuildConfiguration.bPrintDebugInfo)
					{
						foreach (var CurType in Enum.GetValues(typeof(RulesFileType)))
						{
							var RulesFiles = FolderRulesFileCache.RulesFilePaths[(int)CurType];
							if (RulesFiles != null)
							{
								Log.TraceVerbose("Found {0} rules files for folder {1} of type {2}", RulesFiles.Count, Folder, CurType.ToString());
							}
						}
					}
				}

				var RulesFilePathsForType = FolderRulesFileCache.RulesFilePaths[(int)RulesFileType];
				if (RulesFilePathsForType != null)
				{
					foreach (string RulesFilePath in RulesFilePathsForType)
					{
						if (!SourceFiles.Contains(RulesFilePath))
						{
							SourceFiles.Add(RulesFilePath);
						}
					}
				}
			}

			return SourceFiles;
		}
Beispiel #7
0
		private static void FindAllRulesFilesRecursively( DirectoryInfo DirInfo, RulesFileCache RulesFileCache )
		{
			if( DirInfo.Exists )
			{
				var RulesFileTypeEnum = typeof(RulesFileType);
				bool bFoundModuleRulesFile = false;
				var RulesFileTypes = typeof( RulesFileType ).GetEnumValues();
				foreach( RulesFileType CurRulesType in RulesFileTypes )
				{
					// Get the suffix and extension associated with this RulesFileType enum value.
					var MemberInfo = RulesFileTypeEnum.GetMember(CurRulesType.ToString());
					var Attributes = MemberInfo[0].GetCustomAttributes(typeof(RulesTypePropertiesAttribute), false);
					var EnumProperties = (RulesTypePropertiesAttribute)Attributes[0];
					
					var SearchRuleSuffix = "." + EnumProperties.Suffix + EnumProperties.Extension; // match files with the right suffix and extension.
					var FilesInDirectory = DirInfo.GetFiles("*" + EnumProperties.Extension);
					foreach (var RuleFile in FilesInDirectory)
					{
						// test if filename has the appropriate suffix.
						// this handles filenames such as Foo.build.cs, Foo.Build.cs, foo.bUiLd.cs to fix bug 266743 on platforms where case-sensitivity matters
						if (RuleFile.Name.EndsWith(SearchRuleSuffix, StringComparison.InvariantCultureIgnoreCase))
						{
							// Skip Uncooked targets, as those are no longer valid.  This is just for easier backwards compatibility with existing projects.
							// @todo: Eventually we can eliminate this conditional and just allow it to be an error when these are compiled
							if( CurRulesType != RulesFileType.Target || !RuleFile.Name.EndsWith( "Uncooked" + SearchRuleSuffix, StringComparison.InvariantCultureIgnoreCase ) )
							{
								if (RulesFileCache.RulesFilePaths[(int)CurRulesType] == null)
								{
									RulesFileCache.RulesFilePaths[(int)CurRulesType] = new List<string>();
								}

								// Convert file info to the full file path for this file and update our cache
								RulesFileCache.RulesFilePaths[(int)CurRulesType].Add(RuleFile.FullName);

								// NOTE: Multiple rules files in the same folder are supported.  We'll continue iterating along.
								if( CurRulesType == RulesFileType.Module )
								{
									bFoundModuleRulesFile = true;
								}
							}
							else
							{
								Log.TraceVerbose("Skipped deprecated Target rules file with Uncooked extension: " + RuleFile.Name );
							}
						}
					}
				}

				// Only recurse if we didn't find a module rules file.  In the interest of performance and organizational sensibility
				// we don't want to support folders with Build.cs files containing other folders with Build.cs files.  Performance-
				// wise, this is really important to avoid scanning every folder in the Source/ThirdParty directory, for example.
				if( !bFoundModuleRulesFile )
				{
					// Add all the files recursively
					foreach( DirectoryInfo SubDirInfo in DirInfo.GetDirectories() )
					{
						if( SubDirInfo.Name.Equals( "Intermediate", StringComparison.InvariantCultureIgnoreCase ) )
						{
							Console.WriteLine( "WARNING: UnrealBuildTool found an Intermediate folder while looking for rules '{0}'.  It should only ever be searching under 'Source' folders -- an Intermediate folder is unexpected and will greatly decrease iteration times!", SubDirInfo.FullName );
						}
						FindAllRulesFilesRecursively(SubDirInfo, RulesFileCache);
					}
				}
			}
		}
		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);
				}
			}
		}
		private static IReadOnlyList<FileReference> FindAllRulesFiles(DirectoryReference Directory, RulesFileType Type)
		{
			// Check to see if we've already cached source files for this folder
			RulesFileCache Cache;
			if (!RootFolderToRulesFileCache.TryGetValue(Directory, out Cache))
			{
				Cache = new RulesFileCache();
				FindAllRulesFilesRecursively(Directory, Cache);
					RootFolderToRulesFileCache[Directory] = Cache;
				}

			// Get the list of files of the type we're looking for
			if (Type == RulesCompiler.RulesFileType.Module)
			{
				return Cache.ModuleRules;
			}
			else if (Type == RulesCompiler.RulesFileType.Target)
			{
				return Cache.TargetRules;
			}
			else if (Type == RulesCompiler.RulesFileType.AutomationModule)
			{
				return Cache.AutomationModules;
			}
			else
			{
				throw new BuildException("Unhandled rules type: {0}", Type);
			}
		}