public UEBuildClient(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Client", InTargetCsFilename) { if (ShouldCompileMonolithic()) { if (!UnrealBuildTool.IsDesktopPlatform(Platform)) { // We are compiling for a console... // We want the output to go into the <GAME>\Binaries folder if (!InRulesObject.bOutputToEngineBinaries) { OutputPaths = OutputPaths.Select(Path => new FileReference(Path.FullName.Replace("Engine\\Binaries", InDesc.TargetName + "\\Binaries"))).ToList(); } } } }
private static void ConditionallyCompileAndLoadRulesAssembly() { if( String.IsNullOrEmpty( AssemblyName ) ) { throw new BuildException( "Module or target rules data was requested, but not rules assembly name was set yet!" ); } // Did we already have a RulesAssembly and cached data about rules files and modules? If so, then we'll // check to see if we need to flush everything and start over. This can happen if UBT wants to built // different targets in a single invocation, or when generating project files before or after building // a target LoadedAssemblyData LoadedAssembly; if (LoadedAssemblyMap.TryGetValue(AssemblyName, out LoadedAssembly)) { RulesAssembly ExistingAssembly = LoadedAssembly.ExistingAssembly; List<string> ExistingGameFolders = LoadedAssembly.ExistingGameFolders; // Make sure the game folder list wasn't changed since we last compiled this assembly if( ExistingGameFolders != AllGameFolders ) // Quick-check pointers first to avoid iterating { var AnyGameFoldersDifferent = false; if( ExistingGameFolders.Count != AllGameFolders.Count ) { AnyGameFoldersDifferent = true; } else { foreach( var NewGameFolder in AllGameFolders ) { if( !ExistingGameFolders.Contains( NewGameFolder ) ) { AnyGameFoldersDifferent = true; break; } } foreach( var OldGameFolder in ExistingGameFolders ) { if( !AllGameFolders.Contains( OldGameFolder ) ) { AnyGameFoldersDifferent = true; break; } } } if( AnyGameFoldersDifferent ) { throw new BuildException( "SetAssemblyNameAndGameFolders() was called with an assembly name that had already been compiled, but with DIFFERENT game folders. This is not allowed." ); } } return; } var AdditionalSearchPaths = new List<string>(); if (UnrealBuildTool.HasUProjectFile()) { // Add the game project's source folder var ProjectSourceDirectory = Path.Combine( UnrealBuildTool.GetUProjectPath(), "Source" ); if( Directory.Exists( ProjectSourceDirectory ) ) { AdditionalSearchPaths.Add( ProjectSourceDirectory ); } // Add the games project's intermediate source folder var ProjectIntermediateSourceDirectory = Path.Combine(UnrealBuildTool.GetUProjectPath(), "Intermediate", "Source"); if (Directory.Exists(ProjectIntermediateSourceDirectory)) { AdditionalSearchPaths.Add(ProjectIntermediateSourceDirectory); } } var ModuleFileNames = FindAllRulesSourceFiles(RulesFileType.Module, AdditionalSearchPaths); var AssemblySourceFiles = new List<string>(); AssemblySourceFiles.AddRange( ModuleFileNames ); if( AssemblySourceFiles.Count == 0 ) { throw new BuildException("No module rules source files were found in any of the module base directories!"); } var TargetFileNames = FindAllRulesSourceFiles(RulesFileType.Target, AdditionalSearchPaths); AssemblySourceFiles.AddRange( TargetFileNames ); // Create a path to the assembly that we'll either load or compile string BaseIntermediatePath = UnrealBuildTool.HasUProjectFile() ? Path.Combine(UnrealBuildTool.GetUProjectPath(), BuildConfiguration.BaseIntermediateFolder) : BuildConfiguration.BaseIntermediatePath; string OutputAssemblyPath = Path.GetFullPath(Path.Combine(BaseIntermediatePath, "BuildRules", AssemblyName + ".dll")); RulesAssembly Rules = new RulesAssembly(DynamicCompilation.CompileAndLoadAssembly( OutputAssemblyPath, AssemblySourceFiles )); // Setup the module map foreach( var CurModuleFileName in ModuleFileNames ) { var CleanFileName = Utils.CleanDirectorySeparators( CurModuleFileName ); var ModuleName = Path.GetFileNameWithoutExtension( Path.GetFileNameWithoutExtension( CleanFileName ) ); // Strip both extensions if( !Rules.ModuleNameToModuleFileMap.ContainsKey( ModuleName ) ) { Rules.ModuleNameToModuleFileMap.Add( ModuleName, CurModuleFileName ); } } // Setup the target map foreach( var CurTargetFileName in TargetFileNames ) { var CleanFileName = Utils.CleanDirectorySeparators( CurTargetFileName ); var TargetName = Path.GetFileNameWithoutExtension( Path.GetFileNameWithoutExtension( CleanFileName ) ); // Strip both extensions if( !Rules.TargetNameToTargetFileMap.ContainsKey( TargetName ) ) { Rules.TargetNameToTargetFileMap.Add( TargetName, CurTargetFileName ); } } // Remember that we loaded this assembly var RulesAssemblyName = Path.GetFileNameWithoutExtension( Rules.Rules.Location ); LoadedAssemblyMap[RulesAssemblyName] = new LoadedAssemblyData(Rules, AllGameFolders); }
public LoadedAssemblyData(RulesAssembly InAssembly, List<string> InGameFolders) { ExistingAssembly = InAssembly; ExistingGameFolders = InGameFolders; }
/// <summary> /// Constructor. Compiles a rules assembly from the given source files. /// </summary> /// <param name="Plugins">All the plugins included in this assembly</param> /// <param name="ModuleFiles">List of module files to compile</param> /// <param name="TargetFiles">List of target files to compile</param> /// <param name="ModuleFileToPluginInfo">Mapping of module file to the plugin that contains it</param> /// <param name="AssemblyFileName">The output path for the compiled assembly</param> /// <param name="Parent">The parent rules assembly</param> public RulesAssembly(IReadOnlyList<PluginInfo> Plugins, List<FileReference> ModuleFiles, List<FileReference> TargetFiles, Dictionary<FileReference, PluginInfo> ModuleFileToPluginInfo, FileReference AssemblyFileName, RulesAssembly Parent) { this.Plugins = Plugins; this.ModuleFileToPluginInfo = ModuleFileToPluginInfo; this.Parent = Parent; // Find all the source files List<FileReference> AssemblySourceFiles = new List<FileReference>(); AssemblySourceFiles.AddRange(ModuleFiles); AssemblySourceFiles.AddRange(TargetFiles); // Compile the assembly if (AssemblySourceFiles.Count > 0) { CompiledAssembly = DynamicCompilation.CompileAndLoadAssembly(AssemblyFileName, AssemblySourceFiles); } // Setup the module map foreach (FileReference ModuleFile in ModuleFiles) { string ModuleName = ModuleFile.GetFileNameWithoutAnyExtensions(); if (!ModuleNameToModuleFile.ContainsKey(ModuleName)) { ModuleNameToModuleFile.Add(ModuleName, ModuleFile); } } // Setup the target map foreach (FileReference TargetFile in TargetFiles) { string TargetName = TargetFile.GetFileNameWithoutAnyExtensions(); if (!TargetNameToTargetFile.ContainsKey(TargetName)) { TargetNameToTargetFile.Add(TargetName, TargetFile); } } }
public UEBuildEditor(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Editor", InTargetCsFilename) { }
/// <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="ForeignPlugins">List of foreign plugin folders to include in the assembly. May be null.</param> public static RulesAssembly CreateProjectRulesAssembly(FileReference ProjectFileName) { // Check if there's an existing assembly for this project RulesAssembly ProjectRulesAssembly; if (!LoadedAssemblyMap.TryGetValue(ProjectFileName, out ProjectRulesAssembly)) { // Create the engine rules assembly RulesAssembly Parent = CreateEngineRulesAssembly(); // Find all the rules under the project source directory DirectoryReference ProjectDirectory = ProjectFileName.Directory; DirectoryReference ProjectSourceDirectory = DirectoryReference.Combine(ProjectDirectory, "Source"); List<FileReference> ModuleFiles = new List<FileReference>(FindAllRulesFiles(ProjectSourceDirectory, RulesFileType.Module)); List<FileReference> TargetFiles = new List<FileReference>(FindAllRulesFiles(ProjectSourceDirectory, RulesFileType.Target)); // Find all the project plugins List<PluginInfo> ProjectPlugins = new List<PluginInfo>(Plugins.ReadProjectPlugins(ProjectFileName.Directory)); ProjectDescriptor Project = ProjectDescriptor.FromFile(ProjectFileName.FullName); // Add the project's additional plugin directories plugins too ProjectPlugins.AddRange(Plugins.ReadAdditionalPlugins(Project.AdditionalPluginDirectories)); Dictionary<FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary<FileReference, PluginInfo>(); FindModuleRulesForPlugins(ProjectPlugins, ModuleFiles, ModuleFileToPluginInfo); // Add the games project's intermediate source folder DirectoryReference ProjectIntermediateSourceDirectory = DirectoryReference.Combine(ProjectDirectory, "Intermediate", "Source"); if (ProjectIntermediateSourceDirectory.Exists()) { TargetFiles.AddRange(FindAllRulesFiles(ProjectIntermediateSourceDirectory, RulesFileType.Target)); } // Compile the assembly FileReference AssemblyFileName = FileReference.Combine(ProjectDirectory, BuildConfiguration.BaseIntermediateFolder, "BuildRules", ProjectFileName.GetFileNameWithoutExtension() + "ModuleRules.dll"); ProjectRulesAssembly = new RulesAssembly(ProjectPlugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, Parent); LoadedAssemblyMap.Add(ProjectFileName, ProjectRulesAssembly); } return ProjectRulesAssembly; }
/// <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="ForeignPlugins">List of foreign plugin folders to include in the assembly. May be null.</param> public static RulesAssembly CreatePluginRulesAssembly(FileReference PluginFileName, RulesAssembly Parent) { // Check if there's an existing assembly for this project RulesAssembly PluginRulesAssembly; if (!LoadedAssemblyMap.TryGetValue(PluginFileName, out PluginRulesAssembly)) { // Find all the rules source files List<FileReference> ModuleFiles = new List<FileReference>(); 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, PluginLoadedFrom.GameProject)); } // Find all the modules Dictionary<FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary<FileReference, PluginInfo>(); FindModuleRulesForPlugins(ForeignPlugins, ModuleFiles, ModuleFileToPluginInfo); // Compile the assembly FileReference AssemblyFileName = FileReference.Combine(PluginFileName.Directory, BuildConfiguration.BaseIntermediateFolder, "BuildRules", Path.GetFileNameWithoutExtension(PluginFileName.FullName) + "ModuleRules.dll"); PluginRulesAssembly = new RulesAssembly(ForeignPlugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, Parent); LoadedAssemblyMap.Add(PluginFileName, PluginRulesAssembly); } return PluginRulesAssembly; }
/// <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, PluginFileName.Directory, ForeignPlugins, ModuleFiles, TargetFiles, AssemblyFileName, bContainsEngineModules, DefaultBuildSettings: null, bReadOnly: false, bSkipCompile: bSkipCompile, Parent: Parent); LoadedAssemblyMap.Add(PluginFileName, PluginRulesAssembly); } return(PluginRulesAssembly); }
/// <summary> /// Creates the engine rules assembly /// </summary> /// <param name="ForeignPlugins">List of plugins to include in this assembly</param> /// <returns>New rules assembly</returns> public static RulesAssembly CreateEngineRulesAssembly() { if (EngineRulesAssembly == null) { // Find all the rules files List<FileReference> ModuleFiles = new List<FileReference>(FindAllRulesFiles(UnrealBuildTool.EngineSourceDirectory, RulesFileType.Module)); List<FileReference> TargetFiles = new List<FileReference>(FindAllRulesFiles(UnrealBuildTool.EngineSourceDirectory, RulesFileType.Target)); // Add all the plugin modules too IReadOnlyList<PluginInfo> EnginePlugins = Plugins.ReadEnginePlugins(UnrealBuildTool.EngineDirectory); Dictionary<FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary<FileReference, PluginInfo>(); FindModuleRulesForPlugins(EnginePlugins, ModuleFiles, ModuleFileToPluginInfo); // Create a path to the assembly that we'll either load or compile FileReference AssemblyFileName = FileReference.Combine(UnrealBuildTool.EngineDirectory, BuildConfiguration.BaseIntermediateFolder, "BuildRules", "UE4Rules.dll"); EngineRulesAssembly = new RulesAssembly(EnginePlugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, null); } return EngineRulesAssembly; }
/// <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); } // Create the assembly FileReference EngineAssemblyFileName = FileReference.Combine(RootDirectories[0], "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension); RulesAssembly EngineAssembly = new RulesAssembly(Scope, RootDirectories[0], 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(RootDirectories[0], "Intermediate", "Build", "BuildRules", AssemblyPrefix + "ProgramRules" + FrameworkAssemblyExtension); RulesAssembly ProgramAssembly = new RulesAssembly(ProgramsScope, RootDirectories[0], new List <PluginInfo>().AsReadOnly(), ProgramModuleFiles, ProgramTargetFiles, ProgramAssemblyFileName, bContainsEngineModules: false, DefaultBuildSettings: BuildSettingsVersion.Latest, bReadOnly: bReadOnly, bSkipCompile: bSkipCompile, Parent: EngineAssembly); // Return the combined assembly return(ProgramAssembly); }
/// <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 rules/plugins under the project source directories foreach (DirectoryReference ProjectDirectory in UnrealBuildTool.GetAllProjectDirectories(ProjectFileName)) { 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 (string AdditionalPluginDirectory in Project.AdditionalPluginDirectories) { ProjectPlugins.AddRange(Plugins.ReadAdditionalPlugins(MainProjectDirectory, 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, MainProjectDirectory, ProjectPlugins, ModuleFiles, TargetFiles, AssemblyFileName, bContainsEngineModules: false, DefaultBuildSettings: null, bReadOnly: UnrealBuildTool.IsProjectInstalled(), bSkipCompile: bSkipCompile, Parent: Parent); } LoadedAssemblyMap.Add(ProjectFileName, ProjectRulesAssembly); } return(ProjectRulesAssembly); }
/// <summary> /// Creates a rules assembly with the given parameters. /// </summary> /// <param name="PluginFileName">The plugin file to create rules for</param> /// <param name="Parent">The parent rules assembly</param> /// <returns>The new rules assembly</returns> public static RulesAssembly CreatePluginRulesAssembly(FileReference PluginFileName, RulesAssembly Parent) { // Check if there's an existing assembly for this project RulesAssembly PluginRulesAssembly; if (!LoadedAssemblyMap.TryGetValue(PluginFileName, out PluginRulesAssembly)) { // Find all the rules source files List <FileReference> ModuleFiles = new List <FileReference>(); 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, PluginLoadedFrom.GameProject)); } // Find all the modules Dictionary <FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary <FileReference, PluginInfo>(); FindModuleRulesForPlugins(ForeignPlugins, ModuleFiles, ModuleFileToPluginInfo); // Compile the assembly FileReference AssemblyFileName = FileReference.Combine(PluginFileName.Directory, "Intermediate", "Build", "BuildRules", Path.GetFileNameWithoutExtension(PluginFileName.FullName) + "ModuleRules.dll"); PluginRulesAssembly = new RulesAssembly(ForeignPlugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, Parent); LoadedAssemblyMap.Add(PluginFileName, PluginRulesAssembly); } return(PluginRulesAssembly); }
/// <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="bInstalled">Whether the assembly should be marked as installed</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 bInstalled, 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>(); 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>(); FindModuleRulesForPlugins(Plugins, EngineModuleFiles, ModuleFileToPluginInfo); // Create the assembly FileReference EngineAssemblyFileName = FileReference.Combine(RootDirectory, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension); RulesAssembly EngineAssembly = new RulesAssembly(Plugins, EngineModuleFiles, new List <FileReference>(), ModuleFileToPluginInfo, EngineAssemblyFileName, bContainsEngineModules: true, bUseBackwardsCompatibleDefaults: false, bInstalled: bInstalled, Parent: Parent); // Find all the rules files List <FileReference> ProgramModuleFiles = new List <FileReference>(FindAllRulesFiles(ProgramsDirectory, RulesFileType.Module)); List <FileReference> 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(new List <PluginInfo>().AsReadOnly(), ProgramModuleFiles, ProgramTargetFiles, new Dictionary <FileReference, PluginInfo>(), ProgramAssemblyFileName, bContainsEngineModules: false, bUseBackwardsCompatibleDefaults: false, bInstalled: bInstalled, Parent: EngineAssembly); // Return the combined assembly return(ProgramAssembly); }
/// <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="Parent">The parent rules assembly</param> /// <returns>New rules assembly</returns> private static RulesAssembly CreateRulesAssembly(DirectoryReference RootDirectory, string AssemblyPrefix, IReadOnlyList <PluginInfo> Plugins, RulesAssembly Parent) { DirectoryReference SourceDirectory = DirectoryReference.Combine(RootDirectory, "Source"); // Find all the rules files List <FileReference> ModuleFiles = new List <FileReference>(FindAllRulesFiles(SourceDirectory, RulesFileType.Module)); List <FileReference> TargetFiles = new List <FileReference>(FindAllRulesFiles(SourceDirectory, RulesFileType.Target)); // Add all the plugin modules too Dictionary <FileReference, PluginInfo> ModuleFileToPluginInfo = new Dictionary <FileReference, PluginInfo>(); FindModuleRulesForPlugins(Plugins, ModuleFiles, ModuleFileToPluginInfo); // Create a path to the assembly that we'll either load or compile FileReference AssemblyFileName = FileReference.Combine(RootDirectory, "Intermediate", "Build", "BuildRules", AssemblyPrefix + "Rules" + FrameworkAssemblyExtension); return(new RulesAssembly(Plugins, ModuleFiles, TargetFiles, ModuleFileToPluginInfo, AssemblyFileName, Parent)); }
public UEBuildServer(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Server", InTargetCsFilename) { }
/// <summary> /// Main entry point /// </summary> /// <param name="Arguments">Command-line arguments</param> /// <returns>One of the values of ECompilationResult</returns> public override int Execute(CommandLineArguments Arguments) { Arguments.ApplyTo(this); // Create the build configuration object, and read the settings BuildConfiguration BuildConfiguration = new BuildConfiguration(); XmlConfig.ApplyTo(BuildConfiguration); Arguments.ApplyTo(BuildConfiguration); // Parse all the targets being built List <TargetDescriptor> TargetDescriptors = TargetDescriptor.ParseCommandLine(Arguments, BuildConfiguration.bUsePrecompiled, bSkipRulesCompile); if (TargetDescriptors.Count == 0) { throw new BuildException("No targets specified to clean"); } // Also add implicit descriptors for cleaning UnrealBuildTool if (!BuildConfiguration.bDoNotBuildUHT) { const string UnrealHeaderToolTarget = "UnrealHeaderTool"; // Get a list of project files to clean UHT for List <FileReference> ProjectFiles = new List <FileReference>(); foreach (TargetDescriptor TargetDesc in TargetDescriptors) { if (TargetDesc.Name != UnrealHeaderToolTarget && !RemoteMac.HandlesTargetPlatform(TargetDesc.Platform)) { if (ProjectFiles.Count == 0) { ProjectFiles.Add(null); } if (TargetDesc.ProjectFile != null && !ProjectFiles.Contains(TargetDesc.ProjectFile)) { ProjectFiles.Add(TargetDesc.ProjectFile); } } } // Add descriptors for cleaning UHT with all these projects if (ProjectFiles.Count > 0) { UnrealTargetConfiguration Configuration = BuildConfiguration.bForceDebugUnrealHeaderTool ? UnrealTargetConfiguration.Debug : UnrealTargetConfiguration.Development; string Architecture = UEBuildPlatform.GetBuildPlatform(BuildHostPlatform.Current.Platform).GetDefaultArchitecture(null); foreach (FileReference ProjectFile in ProjectFiles) { TargetDescriptors.Add(new TargetDescriptor(ProjectFile, UnrealHeaderToolTarget, BuildHostPlatform.Current.Platform, Configuration, Architecture, null)); } } } // Output the list of targets that we're cleaning Log.TraceInformation("Cleaning {0} binaries...", StringUtils.FormatList(TargetDescriptors.Select(x => x.Name).Distinct())); // Loop through all the targets, and clean them all HashSet <FileReference> FilesToDelete = new HashSet <FileReference>(); HashSet <DirectoryReference> DirectoriesToDelete = new HashSet <DirectoryReference>(); for (int Idx = 0; Idx < TargetDescriptors.Count; ++Idx) { TargetDescriptor TargetDescriptor = TargetDescriptors[Idx]; // Create the rules assembly RulesAssembly RulesAssembly = RulesCompiler.CreateTargetRulesAssembly(TargetDescriptor.ProjectFile, TargetDescriptor.Name, bSkipRulesCompile, BuildConfiguration.bUsePrecompiled, TargetDescriptor.ForeignPlugin); // Create the rules object ReadOnlyTargetRules Target = new ReadOnlyTargetRules(RulesAssembly.CreateTargetRules(TargetDescriptor.Name, TargetDescriptor.Platform, TargetDescriptor.Configuration, TargetDescriptor.Architecture, TargetDescriptor.ProjectFile, TargetDescriptor.AdditionalArguments)); if (!bSkipPreBuildTargets && Target.PreBuildTargets.Count > 0) { foreach (TargetInfo PreBuildTarget in Target.PreBuildTargets) { TargetDescriptor NewTarget = TargetDescriptor.FromTargetInfo(PreBuildTarget); if (!TargetDescriptors.Contains(NewTarget)) { TargetDescriptors.Add(NewTarget); } } } // Find the base folders that can contain binaries List <DirectoryReference> BaseDirs = new List <DirectoryReference>(); BaseDirs.Add(UnrealBuildTool.EngineDirectory); BaseDirs.Add(UnrealBuildTool.EnterpriseDirectory); foreach (FileReference Plugin in Plugins.EnumeratePlugins(Target.ProjectFile)) { BaseDirs.Add(Plugin.Directory); } if (Target.ProjectFile != null) { BaseDirs.Add(Target.ProjectFile.Directory); } // If we're running a precompiled build, remove anything under the engine folder BaseDirs.RemoveAll(x => RulesAssembly.IsReadOnly(x)); // Get all the names which can prefix build products List <string> NamePrefixes = new List <string>(); if (Target.Type != TargetType.Program) { NamePrefixes.Add(UEBuildTarget.GetAppNameForTargetType(Target.Type)); } NamePrefixes.Add(Target.Name); // Get the suffixes for this configuration List <string> NameSuffixes = new List <string>(); if (Target.Configuration == Target.UndecoratedConfiguration) { NameSuffixes.Add(""); } NameSuffixes.Add(String.Format("-{0}-{1}", Target.Platform.ToString(), Target.Configuration.ToString())); if (!String.IsNullOrEmpty(Target.Architecture)) { NameSuffixes.AddRange(NameSuffixes.ToArray().Select(x => x + Target.Architecture)); } // Add all the makefiles and caches to be deleted FilesToDelete.Add(TargetMakefile.GetLocation(Target.ProjectFile, Target.Name, Target.Platform, Target.Configuration)); FilesToDelete.UnionWith(SourceFileMetadataCache.GetFilesToClean(Target.ProjectFile)); // Add all the intermediate folders to be deleted foreach (DirectoryReference BaseDir in BaseDirs) { foreach (string NamePrefix in NamePrefixes) { DirectoryReference GeneratedCodeDir = DirectoryReference.Combine(BaseDir, "Intermediate", "Build", Target.Platform.ToString(), NamePrefix, "Inc"); if (DirectoryReference.Exists(GeneratedCodeDir)) { DirectoriesToDelete.Add(GeneratedCodeDir); } DirectoryReference IntermediateDir = DirectoryReference.Combine(BaseDir, "Intermediate", "Build", Target.Platform.ToString(), NamePrefix, Target.Configuration.ToString()); if (DirectoryReference.Exists(IntermediateDir)) { DirectoriesToDelete.Add(IntermediateDir); } } } // List of additional files and directories to clean, specified by the target platform List <FileReference> AdditionalFilesToDelete = new List <FileReference>(); List <DirectoryReference> AdditionalDirectoriesToDelete = new List <DirectoryReference>(); // Add all the build products from this target string[] NamePrefixesArray = NamePrefixes.Distinct().ToArray(); string[] NameSuffixesArray = NameSuffixes.Distinct().ToArray(); foreach (DirectoryReference BaseDir in BaseDirs) { DirectoryReference BinariesDir = DirectoryReference.Combine(BaseDir, "Binaries", Target.Platform.ToString()); if (DirectoryReference.Exists(BinariesDir)) { UEBuildPlatform.GetBuildPlatform(Target.Platform).FindBuildProductsToClean(BinariesDir, NamePrefixesArray, NameSuffixesArray, AdditionalFilesToDelete, AdditionalDirectoriesToDelete); } } // Get all the additional intermediate folders created by this platform UEBuildPlatform.GetBuildPlatform(Target.Platform).FindAdditionalBuildProductsToClean(Target, AdditionalFilesToDelete, AdditionalDirectoriesToDelete); // Add the platform's files and directories to the main list FilesToDelete.UnionWith(AdditionalFilesToDelete); DirectoriesToDelete.UnionWith(AdditionalDirectoriesToDelete); } // Delete all the directories, then all the files. By sorting the list of directories before we delete them, we avoid spamming the log if a parent directory is deleted first. foreach (DirectoryReference DirectoryToDelete in DirectoriesToDelete.OrderBy(x => x.FullName)) { if (DirectoryReference.Exists(DirectoryToDelete)) { Log.TraceVerbose(" Deleting {0}{1}...", DirectoryToDelete, Path.DirectorySeparatorChar); try { FileUtils.ForceDeleteDirectory(DirectoryToDelete); } catch (Exception Ex) { throw new BuildException(Ex, "Unable to delete {0} ({1})", DirectoryToDelete, Ex.Message.TrimEnd()); } } } foreach (FileReference FileToDelete in FilesToDelete.OrderBy(x => x.FullName)) { if (FileReference.Exists(FileToDelete)) { Log.TraceVerbose(" Deleting " + FileToDelete); try { FileUtils.ForceDeleteFile(FileToDelete); } catch (Exception Ex) { throw new BuildException(Ex, "Unable to delete {0} ({1})", FileToDelete, Ex.Message.TrimEnd()); } } } // Also clean all the remote targets for (int Idx = 0; Idx < TargetDescriptors.Count; Idx++) { TargetDescriptor TargetDescriptor = TargetDescriptors[Idx]; if (RemoteMac.HandlesTargetPlatform(TargetDescriptor.Platform)) { RemoteMac RemoteMac = new RemoteMac(TargetDescriptor.ProjectFile); RemoteMac.Clean(TargetDescriptor); } } return(0); }