// Copyright Epic Games, Inc. All Rights Reserved. using System; using System.Collections.Generic; using System.Linq; using EpicGames.Core; using Microsoft.Extensions.Logging; namespace UnrealBuildTool { /// /// Stores information about a plugin that is being built for a target /// class UEBuildPlugin { /// /// Information about the plugin /// public PluginInfo Info; /// /// Modules that this plugin belongs to /// public List Modules = new List(); /// /// Recursive /// public HashSet? Dependencies; /// /// Whether the descriptor for this plugin is needed at runtime; because it has modules or content which is used, or because it references another module that does. /// public bool bDescriptorNeededAtRuntime; /// /// Whether this descriptor is referenced non-optionally by something else; a project file or other plugin. This is recursively applied to the plugin's references. /// public bool bDescriptorReferencedExplicitly; /// /// Chain of references to this plugin /// public string ReferenceChain; /// /// Constructor /// /// The static plugin information /// Chain of references to this plugin public UEBuildPlugin(PluginInfo Info, string ReferenceChain) { this.Info = Info; this.ReferenceChain = ReferenceChain; } /// /// Accessor for the name of this plugin /// public string Name => Info.Name; /// /// Accessor for the file for this plugin /// public FileReference File => Info.File; /// /// Accessor for the child files for this plugin /// public List ChildFiles => Info.ChildFiles; /// /// Accessor for the type of the plugin /// public PluginType Type => Info.Type; /// /// Accessor for this plugin's root directory /// public DirectoryReference Directory => Info.Directory; /// /// Accessor for this plugin's descriptor /// public PluginDescriptor Descriptor => Info.Descriptor; /// /// Returns the name of this plugin for debugging /// /// Name of the plugin public override string ToString() { return Info.Name; } /// /// Public entry point to validate a module /// /// /// /// true if there are any fatal errors public bool ValidatePlugin(ILogger logger, ReadOnlyTargetRules rules) { bool anyErrors = false; if (Dependencies != null) { foreach (UEBuildPlugin dependencyPlugin in Dependencies) { if (dependencyPlugin.Descriptor.bIsSealed) { logger.LogError("Plugin '{PluginName}' cannot depend on plugin '{DependencyPluginName}' because it is sealed.", Name, dependencyPlugin.Name); anyErrors = true; } else if (Descriptor.DisallowedPlugins != null && Descriptor.DisallowedPlugins.Contains(dependencyPlugin.Name)) { logger.LogError("Plugin '{PluginName}' cannot depend on plugin '{DependencyPluginName}' because it is disallowed.", Name, dependencyPlugin.Name); anyErrors = true; } else if (!String.IsNullOrEmpty(dependencyPlugin.Descriptor.DeprecatedEngineVersion)) { logger.LogWarning("Plugin '{PluginName}' depends on plugin '{DependencyPluginName}' which was deprecated in {EngineVersion} and will soon be removed. Please update your dependencies.", Name, dependencyPlugin.Name, dependencyPlugin.Descriptor.DeprecatedEngineVersion); } } } if (!String.IsNullOrEmpty(Descriptor.DeprecatedEngineVersion)) { logger.LogWarning("Project '{ProjectName}' depends on plugin '{PluginName}' which was deprecated in {EngineVersion} and will soon be removed. Please update your dependencies.", rules.Name, Name, Descriptor.DeprecatedEngineVersion); } // Check that any plugins with the NoCode specifier do not contain modules. if (Descriptor.bNoCode && Modules.Any()) { logger.LogError("Plugin '{PluginName}' cannot contain any code or modules. See the plugin descriptor property `NoCode`", Name); anyErrors = true; } return anyErrors; } } }