// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.IO; using System.Diagnostics; using System.Linq; using Tools.DotNETCommon; namespace UnrealBuildTool { /// /// The type of host that can load a module /// public enum ModuleHostType { /// /// /// Default, /// /// Any target using the UE4 runtime /// Runtime, /// /// Any target except for commandlet /// RuntimeNoCommandlet, /// /// Any target or program /// RuntimeAndProgram, /// /// Loaded only in cooked builds /// CookedOnly, /// /// Loaded only when the engine has support for developer tools enabled /// Developer, /// /// Loaded only by the editor /// Editor, /// /// Loaded only by the editor, except when running commandlets /// EditorNoCommandlet, /// /// Loaded only by programs /// Program, /// /// Loaded only by servers /// ServerOnly, /// /// Loaded only by clients /// ClientOnly, } /// /// Indicates when the engine should attempt to load this module /// public enum ModuleLoadingPhase { /// /// Loaded at the default loading point during startup (during engine init, after game modules are loaded.) /// Default, /// /// Right after the default phase /// PostDefault, /// /// Right before the default phase /// PreDefault, /// /// Loaded as soon as plugins can possibly be loaded (need GConfig) /// EarliestPossible, /// /// Loaded before the engine is fully initialized, immediately after the config system has been initialized. Necessary only for very low-level hooks /// PostConfigInit, /// /// After PostConfigInit and before coreUobject initialized. used for early boot loading screens before the uobjects are initialized /// PreEarlyLoadingScreen, /// /// Loaded before the engine is fully initialized for modules that need to hook into the loading screen before it triggers /// PreLoadingScreen, /// /// After the engine has been initialized /// PostEngineInit, /// /// Do not automatically load this module /// None, } /// /// Class containing information about a code module /// [DebuggerDisplay("Name={Name}")] public class ModuleDescriptor { /// /// Name of this module /// public readonly string Name; /// /// Usage type of module /// public ModuleHostType Type; /// /// When should the module be loaded during the startup sequence? This is sort of an advanced setting. /// public ModuleLoadingPhase LoadingPhase = ModuleLoadingPhase.Default; /// /// List of allowed platforms /// public UnrealTargetPlatform[] WhitelistPlatforms; /// /// List of disallowed platforms /// public UnrealTargetPlatform[] BlacklistPlatforms; /// /// List of allowed targets /// public TargetType[] WhitelistTargets; /// /// List of disallowed targets /// public TargetType[] BlacklistTargets; /// /// List of allowed target configurations /// public UnrealTargetConfiguration[] WhitelistTargetConfigurations; /// /// List of disallowed target configurations /// public UnrealTargetConfiguration[] BlacklistTargetConfigurations; /// /// List of allowed programs /// public string[] WhitelistPrograms; /// /// List of disallowed programs /// public string[] BlacklistPrograms; /// /// List of additional dependencies for building this module. /// public string[] AdditionalDependencies; /// /// Constructor /// /// Name of the module /// Type of target that can host this module public ModuleDescriptor(string InName, ModuleHostType InType) { Name = InName; Type = InType; } /// /// Constructs a ModuleDescriptor from a Json object /// /// /// The new module descriptor public static ModuleDescriptor FromJsonObject(JsonObject InObject) { ModuleDescriptor Module = new ModuleDescriptor(InObject.GetStringField("Name"), InObject.GetEnumField("Type")); ModuleLoadingPhase LoadingPhase; if (InObject.TryGetEnumField("LoadingPhase", out LoadingPhase)) { Module.LoadingPhase = LoadingPhase; } UnrealTargetPlatform[] WhitelistPlatforms; if (InObject.TryGetEnumArrayField("WhitelistPlatforms", out WhitelistPlatforms)) { Module.WhitelistPlatforms = WhitelistPlatforms; } UnrealTargetPlatform[] BlacklistPlatforms; if (InObject.TryGetEnumArrayField("BlacklistPlatforms", out BlacklistPlatforms)) { Module.BlacklistPlatforms = BlacklistPlatforms; } TargetType[] WhitelistTargets; if (InObject.TryGetEnumArrayField("WhitelistTargets", out WhitelistTargets)) { Module.WhitelistTargets = WhitelistTargets; } TargetType[] BlacklistTargets; if (InObject.TryGetEnumArrayField("BlacklistTargets", out BlacklistTargets)) { Module.BlacklistTargets = BlacklistTargets; } UnrealTargetConfiguration[] WhitelistTargetConfigurations; if (InObject.TryGetEnumArrayField("WhitelistTargetConfigurations", out WhitelistTargetConfigurations)) { Module.WhitelistTargetConfigurations = WhitelistTargetConfigurations; } UnrealTargetConfiguration[] BlacklistTargetConfigurations; if (InObject.TryGetEnumArrayField("BlacklistTargetConfigurations", out BlacklistTargetConfigurations)) { Module.BlacklistTargetConfigurations = BlacklistTargetConfigurations; } string[] WhitelistPrograms; if (InObject.TryGetStringArrayField("WhitelistPrograms", out WhitelistPrograms)) { Module.WhitelistPrograms = WhitelistPrograms; } string[] BlacklistPrograms; if (InObject.TryGetStringArrayField("BlacklistPrograms", out BlacklistPrograms)) { Module.BlacklistPrograms = BlacklistPrograms; } string[] AdditionalDependencies; if (InObject.TryGetStringArrayField("AdditionalDependencies", out AdditionalDependencies)) { Module.AdditionalDependencies = AdditionalDependencies; } return Module; } /// /// Write this module to a JsonWriter /// /// Writer to output to void Write(JsonWriter Writer) { Writer.WriteObjectStart(); Writer.WriteValue("Name", Name); Writer.WriteValue("Type", Type.ToString()); Writer.WriteValue("LoadingPhase", LoadingPhase.ToString()); if (WhitelistPlatforms != null && WhitelistPlatforms.Length > 0) { Writer.WriteArrayStart("WhitelistPlatforms"); foreach (UnrealTargetPlatform WhitelistPlatform in WhitelistPlatforms) { Writer.WriteValue(WhitelistPlatform.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistPlatforms != null && BlacklistPlatforms.Length > 0) { Writer.WriteArrayStart("BlacklistPlatforms"); foreach (UnrealTargetPlatform BlacklistPlatform in BlacklistPlatforms) { Writer.WriteValue(BlacklistPlatform.ToString()); } Writer.WriteArrayEnd(); } if (WhitelistTargets != null && WhitelistTargets.Length > 0) { Writer.WriteArrayStart("WhitelistTargets"); foreach (TargetType WhitelistTarget in WhitelistTargets) { Writer.WriteValue(WhitelistTarget.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistTargets != null && BlacklistTargets.Length > 0) { Writer.WriteArrayStart("BlacklistTargets"); foreach (TargetType BlacklistTarget in BlacklistTargets) { Writer.WriteValue(BlacklistTarget.ToString()); } Writer.WriteArrayEnd(); } if (WhitelistTargetConfigurations != null && WhitelistTargetConfigurations.Length > 0) { Writer.WriteArrayStart("WhitelistTargetConfigurations"); foreach (UnrealTargetConfiguration WhitelistTargetConfiguration in WhitelistTargetConfigurations) { Writer.WriteValue(WhitelistTargetConfiguration.ToString()); } Writer.WriteArrayEnd(); } if (BlacklistTargetConfigurations != null && BlacklistTargetConfigurations.Length > 0) { Writer.WriteArrayStart("BlacklistTargetConfigurations"); foreach (UnrealTargetConfiguration BlacklistTargetConfiguration in BlacklistTargetConfigurations) { Writer.WriteValue(BlacklistTargetConfiguration.ToString()); } Writer.WriteArrayEnd(); } if(WhitelistPrograms != null && WhitelistPrograms.Length > 0) { Writer.WriteStringArrayField("WhitelistPrograms", WhitelistPrograms); } if(BlacklistPrograms != null && BlacklistPrograms.Length > 0) { Writer.WriteStringArrayField("BlacklistPrograms", BlacklistPrograms); } if (AdditionalDependencies != null && AdditionalDependencies.Length > 0) { Writer.WriteArrayStart("AdditionalDependencies"); foreach (string AdditionalDependency in AdditionalDependencies) { Writer.WriteValue(AdditionalDependency); } Writer.WriteArrayEnd(); } Writer.WriteObjectEnd(); } /// /// Write an array of module descriptors /// /// The Json writer to output to /// Name of the array /// Array of modules public static void WriteArray(JsonWriter Writer, string Name, ModuleDescriptor[] Modules) { if (Modules != null && Modules.Length > 0) { Writer.WriteArrayStart(Name); foreach (ModuleDescriptor Module in Modules) { Module.Write(Writer); } Writer.WriteArrayEnd(); } } /// /// Determines whether the given plugin module is part of the current build. /// /// The platform being compiled for /// The target configuration being compiled for /// Name of the target being built /// The type of the target being compiled /// Whether the configuration includes developer tools (typically UEBuildConfiguration.bBuildDeveloperTools for UBT callers) /// Whether the configuration includes the editor (typically UEBuildConfiguration.bBuildEditor for UBT callers) /// Whether the configuration requires cooked content (typically UEBuildConfiguration.bBuildRequiresCookedData for UBT callers) public bool IsCompiledInConfiguration(UnrealTargetPlatform Platform, UnrealTargetConfiguration TargetConfiguration, string TargetName, TargetType TargetType, bool bBuildDeveloperTools, bool bBuildEditor, bool bBuildRequiresCookedData) { // Check the platform is whitelisted if (WhitelistPlatforms != null && WhitelistPlatforms.Length > 0 && !WhitelistPlatforms.Contains(Platform)) { return false; } // Check the platform is not blacklisted if (BlacklistPlatforms != null && BlacklistPlatforms.Contains(Platform)) { return false; } // Check the target is whitelisted if (WhitelistTargets != null && WhitelistTargets.Length > 0 && !WhitelistTargets.Contains(TargetType)) { return false; } // Check the target is not blacklisted if (BlacklistTargets != null && BlacklistTargets.Contains(TargetType)) { return false; } // Check the target configuration is whitelisted if (WhitelistTargetConfigurations != null && WhitelistTargetConfigurations.Length > 0 && !WhitelistTargetConfigurations.Contains(TargetConfiguration)) { return false; } // Check the target configuration is not blacklisted if (BlacklistTargetConfigurations != null && BlacklistTargetConfigurations.Contains(TargetConfiguration)) { return false; } // Special checks just for programs if(TargetType == TargetType.Program) { // Check the program name is whitelisted. Note that this behavior is slightly different to other whitelist/blacklist checks; we will whitelist a module of any type if it's explicitly allowed for this program. if(WhitelistPrograms != null && WhitelistPrograms.Length > 0) { return WhitelistPrograms.Contains(TargetName); } // Check the program name is not blacklisted if(BlacklistPrograms != null && BlacklistPrograms.Contains(TargetName)) { return false; } } // Check the module is compatible with this target. switch (Type) { case ModuleHostType.Runtime: case ModuleHostType.RuntimeNoCommandlet: return TargetType != TargetType.Program; case ModuleHostType.CookedOnly: return bBuildRequiresCookedData; case ModuleHostType.RuntimeAndProgram: return true; case ModuleHostType.Developer: return bBuildDeveloperTools; case ModuleHostType.Editor: case ModuleHostType.EditorNoCommandlet: return TargetType == TargetType.Editor || bBuildEditor; case ModuleHostType.Program: return TargetType == TargetType.Program; case ModuleHostType.ServerOnly: return TargetType != TargetType.Program && TargetType != TargetType.Client; case ModuleHostType.ClientOnly: return TargetType != TargetType.Program && TargetType != TargetType.Server; } return false; } } }