/// <summary> /// Initialize the attribute with a list of platforms /// </summary> /// <param name="Platforms">Variable-length array of platform arguments</param> public SupportedPlatformsAttribute(params string[] Platforms) { try { this.Platforms = Array.ConvertAll(Platforms, x => UnrealTargetPlatform.Parse(x)); } catch (BuildException Ex) { Tools.DotNETCommon.ExceptionUtils.AddContext(Ex, "while parsing a SupportedPlatforms attribute"); throw; } }
/// <summary> /// Construct a TargetInfo from an archive on disk /// </summary> /// <param name="Reader">Archive to read from</param> public TargetInfo(BinaryArchiveReader Reader) { this.Name = Reader.ReadString(); this.Platform = UnrealTargetPlatform.Parse(Reader.ReadString()); string ConfigurationStr = Reader.ReadString(); this.Architecture = Reader.ReadString(); this.ProjectFile = Reader.ReadFileReference(); string[] ArgumentStrs = Reader.ReadArray(() => Reader.ReadString()); if (!UnrealTargetConfiguration.TryParse(ConfigurationStr, out Configuration)) { throw new BuildException(string.Format("The configration name {0} is not a valid configration name. Valid names are ({1})", Name, string.Join(",", Enum.GetValues(typeof(UnrealTargetConfiguration)).Cast <UnrealTargetConfiguration>().Select(x => x.ToString())))); } Arguments = new CommandLineArguments(ArgumentStrs); }
/// <summary> /// Read a receipt from disk. /// </summary> /// <param name="Location">Filename to read from</param> /// <param name="EngineDir">Engine directory for expanded variables</param> public static TargetReceipt Read(FileReference Location, DirectoryReference EngineDir) { JsonObject RawObject = JsonObject.Read(Location); // Read the initial fields string TargetName = RawObject.GetStringField("TargetName"); TargetType TargetType = RawObject.GetEnumField <TargetType>("TargetType"); UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(RawObject.GetStringField("Platform")); UnrealTargetConfiguration Configuration = RawObject.GetEnumField <UnrealTargetConfiguration>("Configuration"); // Try to read the build version BuildVersion Version; if (!BuildVersion.TryParse(RawObject.GetObjectField("Version"), out Version)) { throw new JsonParseException("Invalid 'Version' field"); } // Read the project path FileReference ProjectFile; string RelativeProjectFile; if (RawObject.TryGetStringField("Project", out RelativeProjectFile)) { ProjectFile = FileReference.Combine(Location.Directory, RelativeProjectFile); } else { ProjectFile = null; } // Create the receipt TargetReceipt Receipt = new TargetReceipt(ProjectFile, TargetName, TargetType, Platform, Configuration, Version); // Get the project directory DirectoryReference ProjectDir = Receipt.ProjectDir; // Read the launch executable string Launch; if (RawObject.TryGetStringField("Launch", out Launch)) { Receipt.Launch = ExpandPathVariables(Launch, EngineDir, ProjectDir); } // Read the build products JsonObject[] BuildProductObjects; if (RawObject.TryGetObjectArrayField("BuildProducts", out BuildProductObjects)) { foreach (JsonObject BuildProductObject in BuildProductObjects) { string Path; BuildProductType Type; if (BuildProductObject.TryGetStringField("Path", out Path) && BuildProductObject.TryGetEnumField("Type", out Type)) { FileReference File = ExpandPathVariables(Path, EngineDir, ProjectDir); string Module; BuildProductObject.TryGetStringField("Module", out Module); Receipt.AddBuildProduct(File, Type); } } } // Read the runtime dependencies JsonObject[] RuntimeDependencyObjects; if (RawObject.TryGetObjectArrayField("RuntimeDependencies", out RuntimeDependencyObjects)) { foreach (JsonObject RuntimeDependencyObject in RuntimeDependencyObjects) { string Path; if (RuntimeDependencyObject.TryGetStringField("Path", out Path)) { FileReference File = ExpandPathVariables(Path, EngineDir, ProjectDir); StagedFileType Type; if (!RuntimeDependencyObject.TryGetEnumField("Type", out Type)) { // Previous format included an optional IgnoreIfMissing flag, which was only used for debug files. We can explicitly reference them as DebugNonUFS files now. bool bIgnoreIfMissing; if (RuntimeDependencyObject.TryGetBoolField("IgnoreIfMissing", out bIgnoreIfMissing)) { bIgnoreIfMissing = false; } Type = bIgnoreIfMissing? StagedFileType.DebugNonUFS : StagedFileType.NonUFS; } Receipt.RuntimeDependencies.Add(File, Type); } } } // Read the additional properties JsonObject[] AdditionalPropertyObjects; if (RawObject.TryGetObjectArrayField("AdditionalProperties", out AdditionalPropertyObjects)) { foreach (JsonObject AdditionalPropertyObject in AdditionalPropertyObjects) { string Name; if (AdditionalPropertyObject.TryGetStringField("Name", out Name)) { string Value; if (AdditionalPropertyObject.TryGetStringField("Value", out Value)) { Receipt.AdditionalProperties.Add(new ReceiptProperty(Name, Value)); } } } } return(Receipt); }
/// <summary> /// Reads a plugin descriptor from a json object /// </summary> /// <param name="RawObject">The object to read from</param> /// <returns>New plugin descriptor</returns> public PluginDescriptor(JsonObject RawObject) { // Read the version if (!RawObject.TryGetIntegerField("FileVersion", out FileVersion)) { if (!RawObject.TryGetIntegerField("PluginFileVersion", out FileVersion)) { throw new BuildException("Plugin descriptor does not contain a valid FileVersion entry"); } } // Check it's not newer than the latest version we can parse if (FileVersion > (int)PluginDescriptorVersion.Latest) { throw new BuildException("Plugin descriptor appears to be in a newer version ({0}) of the file format that we can load (max version: {1}).", FileVersion, (int)PluginDescriptorVersion.Latest); } // Read the other fields RawObject.TryGetIntegerField("Version", out Version); RawObject.TryGetStringField("VersionName", out VersionName); RawObject.TryGetStringField("FriendlyName", out FriendlyName); RawObject.TryGetStringField("Description", out Description); if (!RawObject.TryGetStringField("Category", out Category)) { // Category used to be called CategoryPath in .uplugin files RawObject.TryGetStringField("CategoryPath", out Category); } // Due to a difference in command line parsing between Windows and Mac, we shipped a few Mac samples containing // a category name with escaped quotes. Remove them here to make sure we can list them in the right category. if (Category != null && Category.Length >= 2 && Category.StartsWith("\"") && Category.EndsWith("\"")) { Category = Category.Substring(1, Category.Length - 2); } RawObject.TryGetStringField("CreatedBy", out CreatedBy); RawObject.TryGetStringField("CreatedByURL", out CreatedByURL); RawObject.TryGetStringField("DocsURL", out DocsURL); RawObject.TryGetStringField("MarketplaceURL", out MarketplaceURL); RawObject.TryGetStringField("SupportURL", out SupportURL); RawObject.TryGetStringField("EngineVersion", out EngineVersion); RawObject.TryGetStringArrayField("SupportedPrograms", out SupportedPrograms); RawObject.TryGetBoolField("bIsPluginExtension", out bIsPluginExtension); try { string[] SupportedTargetPlatformNames; if (RawObject.TryGetStringArrayField("SupportedTargetPlatforms", out SupportedTargetPlatformNames)) { SupportedTargetPlatforms = Array.ConvertAll(SupportedTargetPlatformNames, x => UnrealTargetPlatform.Parse(x)); } } catch (BuildException Ex) { ExceptionUtils.AddContext(Ex, "while parsing SupportedTargetPlatforms in plugin with FriendlyName '{0}'", FriendlyName); throw; } JsonObject[] ModulesArray; if (RawObject.TryGetObjectArrayField("Modules", out ModulesArray)) { Modules = Array.ConvertAll(ModulesArray, x => ModuleDescriptor.FromJsonObject(x)); } JsonObject[] LocalizationTargetsArray; if (RawObject.TryGetObjectArrayField("LocalizationTargets", out LocalizationTargetsArray)) { LocalizationTargets = Array.ConvertAll(LocalizationTargetsArray, x => LocalizationTargetDescriptor.FromJsonObject(x)); } bool bEnabledByDefaultValue; if (RawObject.TryGetBoolField("EnabledByDefault", out bEnabledByDefaultValue)) { bEnabledByDefault = bEnabledByDefaultValue; } RawObject.TryGetBoolField("CanContainContent", out bCanContainContent); RawObject.TryGetBoolField("IsBetaVersion", out bIsBetaVersion); RawObject.TryGetBoolField("IsExperimentalVersion", out bIsExperimentalVersion); RawObject.TryGetBoolField("Installed", out bInstalled); bool bCanBeUsedWithUnrealHeaderTool; if (RawObject.TryGetBoolField("CanBeUsedWithUnrealHeaderTool", out bCanBeUsedWithUnrealHeaderTool) && bCanBeUsedWithUnrealHeaderTool) { Array.Resize(ref SupportedPrograms, (SupportedPrograms == null)? 1 : SupportedPrograms.Length + 1); SupportedPrograms[SupportedPrograms.Length - 1] = "UnrealHeaderTool"; } RawObject.TryGetBoolField("RequiresBuildPlatform", out bRequiresBuildPlatform); CustomBuildSteps.TryRead(RawObject, "PreBuildSteps", out PreBuildSteps); CustomBuildSteps.TryRead(RawObject, "PostBuildSteps", out PostBuildSteps); JsonObject[] PluginsArray; if (RawObject.TryGetObjectArrayField("Plugins", out PluginsArray)) { Plugins = Array.ConvertAll(PluginsArray, x => PluginReferenceDescriptor.FromJsonObject(x)); } }
/// <summary> /// Parse a list of target descriptors from the command line /// </summary> /// <param name="Arguments">Command-line arguments</param> /// <param name="bUsePrecompiled">Whether to use a precompiled engine distribution</param> /// <param name="bSkipRulesCompile">Whether to skip compiling rules assemblies</param> /// <param name="TargetDescriptors">List of target descriptors</param> public static void ParseSingleCommandLine(CommandLineArguments Arguments, bool bUsePrecompiled, bool bSkipRulesCompile, List <TargetDescriptor> TargetDescriptors) { List <UnrealTargetPlatform> Platforms = new List <UnrealTargetPlatform>(); List <UnrealTargetConfiguration> Configurations = new List <UnrealTargetConfiguration>(); List <string> TargetNames = new List <string>(); FileReference ProjectFile = Arguments.GetFileReferenceOrDefault("-Project=", null); // Settings for creating/using static libraries for the engine for (int ArgumentIndex = 0; ArgumentIndex < Arguments.Count; ArgumentIndex++) { string Argument = Arguments[ArgumentIndex]; if (Argument.Length > 0 && Argument[0] != '-') { // Mark this argument as used. We'll interpret it as one thing or another. Arguments.MarkAsUsed(ArgumentIndex); // Check if it's a project file argument if (Argument.EndsWith(".uproject", StringComparison.OrdinalIgnoreCase)) { FileReference NewProjectFile = new FileReference(Argument); if (ProjectFile != null && ProjectFile != NewProjectFile) { throw new BuildException("Multiple project files specified on command line (first {0}, then {1})", ProjectFile, NewProjectFile); } ProjectFile = new FileReference(Argument); continue; } // Split it into separate arguments string[] InlineArguments = Argument.Split('+'); // Try to parse them as platforms UnrealTargetPlatform ParsedPlatform; if (UnrealTargetPlatform.TryParse(InlineArguments[0], out ParsedPlatform)) { Platforms.Add(ParsedPlatform); for (int InlineArgumentIdx = 1; InlineArgumentIdx < InlineArguments.Length; InlineArgumentIdx++) { Platforms.Add(UnrealTargetPlatform.Parse(InlineArguments[InlineArgumentIdx])); } continue; } // Try to parse them as configurations UnrealTargetConfiguration ParsedConfiguration; if (Enum.TryParse(InlineArguments[0], true, out ParsedConfiguration)) { Configurations.Add(ParsedConfiguration); for (int InlineArgumentIdx = 1; InlineArgumentIdx < InlineArguments.Length; InlineArgumentIdx++) { string InlineArgument = InlineArguments[InlineArgumentIdx]; if (!Enum.TryParse(InlineArgument, true, out ParsedConfiguration)) { throw new BuildException("Invalid configuration '{0}'", InlineArgument); } Configurations.Add(ParsedConfiguration); } continue; } // Otherwise assume they are target names TargetNames.AddRange(InlineArguments); } } if (Platforms.Count == 0) { throw new BuildException("No platforms specified for target"); } if (Configurations.Count == 0) { throw new BuildException("No configurations specified for target"); } // Make sure the project file exists, and make sure we're using the correct case. if (ProjectFile != null) { FileInfo ProjectFileInfo = FileUtils.FindCorrectCase(ProjectFile.ToFileInfo()); if (!ProjectFileInfo.Exists) { throw new BuildException("Unable to find project '{0}'.", ProjectFile); } ProjectFile = new FileReference(ProjectFileInfo); } // Expand all the platforms, architectures and configurations foreach (UnrealTargetPlatform Platform in Platforms) { // Make sure the platform is valid if (!InstalledPlatformInfo.IsValid(null, Platform, null, EProjectType.Code, InstalledPlatformState.Downloaded)) { if (!InstalledPlatformInfo.IsValid(null, Platform, null, EProjectType.Code, InstalledPlatformState.Supported)) { throw new BuildException("The {0} platform is not supported from this engine distribution.", Platform); } else { throw new BuildException("Missing files required to build {0} targets. Enable {0} as an optional download component in the Epic Games Launcher.", Platform); } } // Parse the architecture parameter, or get the default for the platform List <string> Architectures = new List <string>(Arguments.GetValues("-Architecture=", '+')); if (Architectures.Count == 0) { Architectures.Add(UEBuildPlatform.GetBuildPlatform(Platform).GetDefaultArchitecture(ProjectFile)); } foreach (string Architecture in Architectures) { foreach (UnrealTargetConfiguration Configuration in Configurations) { // Create all the target descriptors for targets specified by type foreach (string TargetTypeString in Arguments.GetValues("-TargetType=")) { TargetType TargetType; if (!Enum.TryParse(TargetTypeString, out TargetType)) { throw new BuildException("Invalid target type '{0}'", TargetTypeString); } if (ProjectFile == null) { throw new BuildException("-TargetType=... requires a project file to be specified"); } else { TargetNames.Add(RulesCompiler.CreateProjectRulesAssembly(ProjectFile, bUsePrecompiled, bSkipRulesCompile).GetTargetNameByType(TargetType, Platform, Configuration, Architecture, ProjectFile)); } } // Make sure we could parse something if (TargetNames.Count == 0) { throw new BuildException("No target name was specified on the command-line."); } // Create all the target descriptors foreach (string TargetName in TargetNames) { // If a project file was not specified see if we can find one if (ProjectFile == null && NativeProjects.TryGetProjectForTarget(TargetName, out ProjectFile)) { Log.TraceVerbose("Found project file for {0} - {1}", TargetName, ProjectFile); } // Create the target descriptor TargetDescriptors.Add(new TargetDescriptor(ProjectFile, TargetName, Platform, Configuration, Architecture, Arguments)); } } } } }
private static void ParsePlatformConfiguration(string PlatformConfiguration) { // Trim whitespace at the beginning. PlatformConfiguration = PlatformConfiguration.Trim(); // Remove brackets. PlatformConfiguration = PlatformConfiguration.TrimStart('('); PlatformConfiguration = PlatformConfiguration.TrimEnd(')'); bool bCanCreateEntry = true; string ConfigurationName; UnrealTargetConfiguration Configuration = UnrealTargetConfiguration.Unknown; if (ParseSubValue(PlatformConfiguration, "Configuration=", out ConfigurationName)) { Enum.TryParse(ConfigurationName, out Configuration); } if (Configuration == UnrealTargetConfiguration.Unknown) { Log.TraceWarning("Unable to read configuration from {0}", PlatformConfiguration); bCanCreateEntry = false; } string PlatformName; if (ParseSubValue(PlatformConfiguration, "PlatformName=", out PlatformName)) { if (!UnrealTargetPlatform.IsValidName(PlatformName)) { Log.TraceWarning("Unable to read platform from {0}", PlatformConfiguration); bCanCreateEntry = false; } } string PlatformTypeName; TargetType PlatformType = TargetType.Game; if (ParseSubValue(PlatformConfiguration, "PlatformType=", out PlatformTypeName)) { if (!Enum.TryParse(PlatformTypeName, out PlatformType)) { Log.TraceWarning("Unable to read Platform Type from {0}, defaulting to Game", PlatformConfiguration); PlatformType = TargetType.Game; } } if (PlatformType == TargetType.Program) { Log.TraceWarning("Program is not a valid PlatformType for an Installed Platform, defaulting to Game"); PlatformType = TargetType.Game; } string Architecture; ParseSubValue(PlatformConfiguration, "Architecture=", out Architecture); string RequiredFile; if (ParseSubValue(PlatformConfiguration, "RequiredFile=", out RequiredFile)) { RequiredFile = FileReference.Combine(UnrealBuildTool.RootDirectory, RequiredFile).ToString(); } string ProjectTypeName; EProjectType ProjectType = EProjectType.Any; if (ParseSubValue(PlatformConfiguration, "ProjectType=", out ProjectTypeName)) { Enum.TryParse(ProjectTypeName, out ProjectType); } if (ProjectType == EProjectType.Unknown) { Log.TraceWarning("Unable to read project type from {0}", PlatformConfiguration); bCanCreateEntry = false; } string CanBeDisplayedString; bool bCanBeDisplayed = false; if (ParseSubValue(PlatformConfiguration, "bCanBeDisplayed=", out CanBeDisplayedString)) { bCanBeDisplayed = Convert.ToBoolean(CanBeDisplayedString); } if (bCanCreateEntry) { InstalledPlatformConfigurations.Add(new InstalledPlatformConfiguration(Configuration, UnrealTargetPlatform.Parse(PlatformName), PlatformType, Architecture, RequiredFile, ProjectType, bCanBeDisplayed)); } }
/// <summary> /// Construct a PluginReferenceDescriptor from a Json object /// </summary> /// <param name="RawObject">The Json object containing a plugin reference descriptor</param> /// <returns>New PluginReferenceDescriptor object</returns> public static PluginReferenceDescriptor FromJsonObject(JsonObject RawObject) { string[] WhitelistPlatformNames = null; string[] BlacklistPlatformNames = null; string[] SupportedTargetPlatformNames = null; PluginReferenceDescriptor Descriptor = new PluginReferenceDescriptor(RawObject.GetStringField("Name"), null, RawObject.GetBoolField("Enabled")); RawObject.TryGetBoolField("Optional", out Descriptor.bOptional); RawObject.TryGetStringField("Description", out Descriptor.Description); RawObject.TryGetStringField("MarketplaceURL", out Descriptor.MarketplaceURL); // Only parse platform information if enabled if (Descriptor.bEnabled) { RawObject.TryGetStringArrayField("WhitelistPlatforms", out WhitelistPlatformNames); RawObject.TryGetStringArrayField("BlacklistPlatforms", out BlacklistPlatformNames); RawObject.TryGetEnumArrayField <UnrealTargetConfiguration>("WhitelistTargetConfigurations", out Descriptor.WhitelistTargetConfigurations); RawObject.TryGetEnumArrayField <UnrealTargetConfiguration>("BlacklistTargetConfigurations", out Descriptor.BlacklistTargetConfigurations); RawObject.TryGetEnumArrayField <TargetType>("WhitelistTargets", out Descriptor.WhitelistTargets); RawObject.TryGetEnumArrayField <TargetType>("BlacklistTargets", out Descriptor.BlacklistTargets); RawObject.TryGetStringArrayField("SupportedTargetPlatforms", out SupportedTargetPlatformNames); } try { // convert string array to UnrealTargetPlatform arrays if (WhitelistPlatformNames != null) { Descriptor.WhitelistPlatforms = WhitelistPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } if (BlacklistPlatformNames != null) { Descriptor.BlacklistPlatforms = BlacklistPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } if (SupportedTargetPlatformNames != null) { Descriptor.SupportedTargetPlatforms = SupportedTargetPlatformNames.Select(x => UnrealTargetPlatform.Parse(x)).ToList(); } } catch (BuildException Ex) { ExceptionUtils.AddContext(Ex, "while parsing PluginReferenceDescriptor {0}", Descriptor.Name); throw; } return(Descriptor); }
/// <summary> /// Attempt to merge a child plugin up into a parent plugin (via file naming scheme). Very little merging happens /// but it does allow for platform extensions to extend a plugin with module files /// </summary> /// <param name="Child">Child plugin that needs to merge to a main, parent plugin</param> /// <param name="Filename">Child plugin's filename, used to determine the parent's name</param> private static void TryMergeWithParent(PluginInfo Child, FileReference Filename) { // find the parent PluginInfo Parent = null; string[] Tokens = Filename.GetFileNameWithoutAnyExtensions().Split("_".ToCharArray()); if (Tokens.Length == 2) { string ParentPluginName = Tokens[0]; foreach (KeyValuePair <DirectoryReference, List <PluginInfo> > Pair in PluginInfoCache) { Parent = Pair.Value.FirstOrDefault(x => x.Name.Equals(ParentPluginName, StringComparison.InvariantCultureIgnoreCase)); if (Parent != null) { break; } } } // did we find a parent plugin? if (Parent == null) { throw new BuildException("Child plugin {0} was not named properly. It should be in the form <ParentPlugin>_<Platform>.uplugin", Filename); } // validate child plugin file name string PlatformName = Tokens[1]; if (!IsValidChildPluginSuffix(PlatformName)) { Log.TraceWarning("Ignoring child plugin: {0} - Unknown suffix \"{1}\". Expected valid platform or group", Child.File.GetFileName(), PlatformName); return; } // add our uplugin file to the existing plugin to be used to search for modules later Parent.ChildFiles.Add(Child.File); // merge the supported platforms Parent.Descriptor.MergeSupportedTargetPlatforms(Child.Descriptor.SupportedTargetPlatforms); // make sure we are whitelisted for any modules we list, if the parent had a whitelist if (Child.Descriptor.Modules != null) { // this should cause an error if it's invalid platform name UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(PlatformName); foreach (ModuleDescriptor ChildModule in Child.Descriptor.Modules) { ModuleDescriptor ParentModule = Parent.Descriptor.Modules.FirstOrDefault(x => x.Name.Equals(ChildModule.Name) && x.Type == ChildModule.Type); if (ParentModule != null) { // merge white/blacklists (if the parent had a list, and child didn't specify a list, just add the child platform to the parent list - for white and black!) if (ParentModule.WhitelistPlatforms != null && ParentModule.WhitelistPlatforms.Length > 0) { List <UnrealTargetPlatform> Whitelist = ParentModule.WhitelistPlatforms.ToList(); if (ChildModule.WhitelistPlatforms != null && ChildModule.WhitelistPlatforms.Length > 0) { Whitelist.AddRange(ChildModule.WhitelistPlatforms); } else { Whitelist.Add(Platform); } ParentModule.WhitelistPlatforms = Whitelist.ToArray(); } if (ParentModule.BlacklistPlatforms != null && ParentModule.BlacklistPlatforms.Length > 0) { if (ChildModule.BlacklistPlatforms != null && ChildModule.BlacklistPlatforms.Length > 0) { List <UnrealTargetPlatform> Blacklist = ParentModule.BlacklistPlatforms.ToList(); Blacklist.AddRange(ChildModule.BlacklistPlatforms); ParentModule.BlacklistPlatforms = Blacklist.ToArray(); } } } } } // @todo platplug: what else do we want to support merging?!? }
/// <summary> /// Constructs a ModuleDescriptor from a Json object /// </summary> /// <param name="InObject"></param> /// <returns>The new module descriptor</returns> public static ModuleDescriptor FromJsonObject(JsonObject InObject) { ModuleDescriptor Module = new ModuleDescriptor(InObject.GetStringField("Name"), InObject.GetEnumField <ModuleHostType>("Type")); ModuleLoadingPhase LoadingPhase; if (InObject.TryGetEnumField <ModuleLoadingPhase>("LoadingPhase", out LoadingPhase)) { Module.LoadingPhase = LoadingPhase; } try { string[] WhitelistPlatforms; if (InObject.TryGetStringArrayField("WhitelistPlatforms", out WhitelistPlatforms)) { Module.WhitelistPlatforms = Array.ConvertAll(WhitelistPlatforms, x => UnrealTargetPlatform.Parse(x)); } string[] BlacklistPlatforms; if (InObject.TryGetStringArrayField("BlacklistPlatforms", out BlacklistPlatforms)) { Module.BlacklistPlatforms = Array.ConvertAll(BlacklistPlatforms, x => UnrealTargetPlatform.Parse(x)); } } catch (BuildException Ex) { ExceptionUtils.AddContext(Ex, "while parsing module descriptor '{0}'", Module.Name); throw; } TargetType[] WhitelistTargets; if (InObject.TryGetEnumArrayField <TargetType>("WhitelistTargets", out WhitelistTargets)) { Module.WhitelistTargets = WhitelistTargets; } TargetType[] BlacklistTargets; if (InObject.TryGetEnumArrayField <TargetType>("BlacklistTargets", out BlacklistTargets)) { Module.BlacklistTargets = BlacklistTargets; } UnrealTargetConfiguration[] WhitelistTargetConfigurations; if (InObject.TryGetEnumArrayField <UnrealTargetConfiguration>("WhitelistTargetConfigurations", out WhitelistTargetConfigurations)) { Module.WhitelistTargetConfigurations = WhitelistTargetConfigurations; } UnrealTargetConfiguration[] BlacklistTargetConfigurations; if (InObject.TryGetEnumArrayField <UnrealTargetConfiguration>("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); }