Пример #1
0
		/// <summary>
		/// Read all the plugins available to a given project
		/// </summary>
		/// <param name="EngineDir">Path to the engine directory</param>
		/// <param name="ProjectFileName">Path to the project file (or null)</param>
		/// <returns>Sequence of PluginInfo objects, one for each discovered plugin</returns>
		public static List<PluginInfo> ReadAvailablePlugins(string EngineDir, string ProjectFileName)
		{
			List<PluginInfo> Plugins = new List<PluginInfo>();

			// Read all the engine plugins
			string EnginePluginsDir = Path.Combine(EngineDir, "Plugins");
			foreach(string PluginFileName in EnumeratePlugins(EnginePluginsDir))
			{
				PluginInfo Plugin = new PluginInfo(PluginFileName, PluginLoadedFrom.Engine);
				Plugins.Add(Plugin);
			}

			// Read all the project plugins
			if(!String.IsNullOrEmpty(ProjectFileName))
			{
				string ProjectPluginsDir = Path.Combine(Path.GetDirectoryName(ProjectFileName), "Plugins");
				foreach(string PluginFileName in EnumeratePlugins(ProjectPluginsDir))
				{
					PluginInfo Plugin = new PluginInfo(PluginFileName, PluginLoadedFrom.GameProject);
					Plugins.Add(Plugin);
				}
			}

			return Plugins;
		}
Пример #2
0
        /** Updates the intermediate include directory timestamps of all the passed in UObject modules */
        private static void UpdateDirectoryTimestamps(List <UHTModuleInfo> UObjectModules)
        {
            foreach (var Module in UObjectModules)
            {
                string GeneratedCodeDirectory     = Path.GetDirectoryName(Module.GeneratedCPPFilenameBase);
                var    GeneratedCodeDirectoryInfo = new DirectoryInfo(GeneratedCodeDirectory);

                try
                {
                    if (GeneratedCodeDirectoryInfo.Exists)
                    {
                        if (UnrealBuildTool.RunningRocket())
                        {
                            // If it is an Engine folder and we are building a rocket project do NOT update the timestamp!
                            // @todo Rocket: This contains check is hacky/fragile
                            string FullGeneratedCodeDirectory = GeneratedCodeDirectoryInfo.FullName;
                            FullGeneratedCodeDirectory = FullGeneratedCodeDirectory.Replace("\\", "/");
                            if (FullGeneratedCodeDirectory.Contains("Engine/Intermediate/Build"))
                            {
                                continue;
                            }

                            // Skip checking timestamps for engine plugin intermediate headers in Rocket
                            PluginInfo Info = Plugins.GetPluginInfoForModule(Module.ModuleName);
                            if (Info != null)
                            {
                                if (Info.LoadedFrom == PluginInfo.LoadedFromType.Engine)
                                {
                                    continue;
                                }
                            }
                        }

                        // Touch the include directory since we have technically 'generated' the headers
                        // However, the headers might not be touched at all since that would cause the compiler to recompile everything
                        // We can't alter the directory timestamp directly, because this may throw exceptions when the directory is
                        // open in visual studio or windows explorer, so instead we create a blank file that will change the timestamp for us
                        string TimestampFile = GeneratedCodeDirectoryInfo.FullName + Path.DirectorySeparatorChar + @"Timestamp";

                        if (!GeneratedCodeDirectoryInfo.Exists)
                        {
                            GeneratedCodeDirectoryInfo.Create();
                        }

                        // Save all of the UObject files to a timestamp file.  We'll load these on the next run to see if any new
                        // files with UObject classes were deleted, so that we'll know to run UHT even if the timestamps of all
                        // of the other source files were unchanged
                        {
                            var AllUObjectFiles = new List <string>();
                            AllUObjectFiles.AddRange(Module.PublicUObjectClassesHeaders.ConvertAll(Item => Item.AbsolutePath));
                            AllUObjectFiles.AddRange(Module.PublicUObjectHeaders.ConvertAll(Item => Item.AbsolutePath));
                            AllUObjectFiles.AddRange(Module.PrivateUObjectHeaders.ConvertAll(Item => Item.AbsolutePath));
                            ResponseFile.Create(TimestampFile, AllUObjectFiles);
                        }
                    }
                }
                catch (Exception Exception)
                {
                    throw new BuildException(Exception, "Couldn't touch header directories: " + Exception.Message);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Loads a plugin descriptor file and fills out a new PluginInfo structure.  Throws an exception on failure.
        /// </summary>
        /// <param name="PluginFile">The path to the plugin file to load</param>
        /// <param name="LoadedFrom">Where the plugin was loaded from</param>
        /// <returns>New PluginInfo for the loaded descriptor.</returns>
        private static PluginInfo LoadPluginDescriptor( FileInfo PluginFileInfo, PluginInfo.LoadedFromType LoadedFrom )
        {
            // Load the file up (JSon format)
            Dictionary<string, object> PluginDescriptorDict;
            {
                string FileContent;
                using( var StreamReader = new StreamReader( PluginFileInfo.FullName ) )
                {
                    FileContent = StreamReader.ReadToEnd();
                }

                // Parse the Json into a dictionary
                var CaseSensitiveJSonDict = fastJSON.JSON.Instance.ToObject< Dictionary< string, object > >( FileContent );

                // Convert to a case-insensitive dictionary, so that we can be more tolerant of hand-typed files
                PluginDescriptorDict = new Dictionary<string, object>( CaseSensitiveJSonDict, StringComparer.InvariantCultureIgnoreCase );
            }

            // File version check
            long PluginVersionNumber;
            {
                // Try to get the version of the plugin
                object PluginVersionObject;
                if( !PluginDescriptorDict.TryGetValue( "FileVersion", out PluginVersionObject ) )
                {
                    if( !PluginDescriptorDict.TryGetValue( "PluginFileVersion", out PluginVersionObject ) )
                    {
                        throw new BuildException( "Plugin descriptor file '{0}' does not contain a valid FileVersion entry", PluginFileInfo.FullName );
                    }
                }

                if( !( PluginVersionObject is long ) )
                {
                    throw new BuildException( "Unable to parse the version number of the plugin descriptor file '{0}'", PluginFileInfo.FullName );
                }

                PluginVersionNumber = (long)PluginVersionObject;
                if( PluginVersionNumber > LatestPluginDescriptorFileVersion )
                {
                    throw new BuildException( "Plugin descriptor file '{0}' appears to be in a newer version ({1}) of the file format that we can load (max version: {2}).", PluginFileInfo.FullName, PluginVersionNumber, LatestPluginDescriptorFileVersion );
                }

                // @todo plugin: Should we also test the engine version here?  (we would need to load it from build.properties)
            }

            // NOTE: At this point, we can use PluginVersionNumber to handle backwards compatibility when loading the rest of the file!

            var PluginInfo = new PluginInfo();
            PluginInfo.LoadedFrom = LoadedFrom;
            PluginInfo.Directory = PluginFileInfo.Directory.FullName;
            PluginInfo.Name = Path.GetFileName(PluginInfo.Directory);

            // Determine whether the plugin should be enabled by default
            object EnabledByDefaultObject;
            if(PluginDescriptorDict.TryGetValue("EnabledByDefault", out EnabledByDefaultObject) && (EnabledByDefaultObject is bool))
            {
                PluginInfo.bEnabledByDefault = (bool)EnabledByDefaultObject;
            }

            // This plugin might have some modules that we need to know about.  Let's take a look.
            {
                object ModulesObject;
                if( PluginDescriptorDict.TryGetValue( "Modules", out ModulesObject ) )
                {
                    if( !( ModulesObject is Array ) )
                    {
                        throw new BuildException( "Found a 'Modules' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName );
                    }

                    var ModulesArray = (Array)ModulesObject;
                    foreach( var ModuleObject in ModulesArray )
                    {
                        var ModuleDict = new Dictionary<string,object>( (Dictionary< string, object >)ModuleObject, StringComparer.InvariantCultureIgnoreCase );

                        var PluginModuleInfo = new PluginInfo.PluginModuleInfo();

                        // Module name
                        {
                            // All modules require a name to be set
                            object ModuleNameObject;
                            if( !ModuleDict.TryGetValue( "Name", out ModuleNameObject ) )
                            {
                                throw new BuildException( "Found a 'Module' entry with a missing 'Name' field in plugin descriptor file '{0}'", PluginFileInfo.FullName );
                            }
                            string ModuleName = (string)ModuleNameObject;

                            // @todo plugin: Locate this module right now and validate it?  Repair case?
                            PluginModuleInfo.Name = ModuleName;
                        }

                        // Module type
                        {
                            // Check to see if the user specified the module's type
                            object ModuleTypeObject;
                            if( !ModuleDict.TryGetValue( "Type", out ModuleTypeObject ) )
                            {
                                throw new BuildException( "Found a Module entry '{0}' with a missing 'Type' field in plugin descriptor file '{1}'", PluginModuleInfo.Name, PluginFileInfo.FullName );
                            }
                            string ModuleTypeString = (string)ModuleTypeObject;

                            // Check to see if this is a valid type
                            bool FoundValidType = false;
                            foreach( PluginInfo.PluginModuleType PossibleType in Enum.GetValues( typeof( PluginInfo.PluginModuleType ) ) )
                            {
                                if( ModuleTypeString.Equals( PossibleType.ToString(), StringComparison.InvariantCultureIgnoreCase ) )
                                {
                                    FoundValidType = true;
                                    PluginModuleInfo.Type = PossibleType;
                                    break;
                                }
                            }
                            if( !FoundValidType )
                            {
                                throw new BuildException( "Module entry '{0}' specified an unrecognized module Type '{1}' in plugin descriptor file '{0}'", PluginModuleInfo.Name, ModuleTypeString, PluginFileInfo.FullName );
                            }
                        }

                        // Supported platforms
                        PluginModuleInfo.Platforms = new List<UnrealTargetPlatform>();

                        // look for white and blacklists
                        object WhitelistObject, BlacklistObject;
                        ModuleDict.TryGetValue( "WhitelistPlatforms", out WhitelistObject );
                        ModuleDict.TryGetValue( "BlacklistPlatforms", out BlacklistObject );

                        if (WhitelistObject != null && BlacklistObject != null)
                        {
                            throw new BuildException( "Found a module '{0}' with both blacklist and whitelist platform lists in plugin file '{1}'", PluginModuleInfo.Name, PluginFileInfo.FullName );
                        }

                        // now process the whitelist
                        if (WhitelistObject != null)
                        {
                            if (!(WhitelistObject is Array))
                            {
                                throw new BuildException("Found a 'WhitelistPlatforms' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName);
                            }

                            // put the whitelist array directly into the plugin's modulelist
                            ConvertPlatformArrayToList((Array)WhitelistObject, ref PluginModuleInfo.Platforms, PluginFileInfo.FullName);
                        }
                        // handle the blacklist (or lack of blacklist and whitelist which means all platforms)
                        else
                        {
                            // start with all platforms supported
                            foreach (UnrealTargetPlatform Platform in Enum.GetValues( typeof( UnrealTargetPlatform ) ) )
                            {
                                PluginModuleInfo.Platforms.Add(Platform);
                            }

                            // if we want to disallow some platforms, then pull them out now
                            if (BlacklistObject != null)
                            {
                                if (!(BlacklistObject is Array))
                                {
                                    throw new BuildException("Found a 'BlacklistPlatforms' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName);
                                }

                                // put the whitelist array directly into the plugin's modulelist
                                List<UnrealTargetPlatform> Blacklist = new List<UnrealTargetPlatform>();
                                ConvertPlatformArrayToList((Array)BlacklistObject, ref Blacklist, PluginFileInfo.FullName);

                                // now remove them from the module platform list
                                foreach (UnrealTargetPlatform Platform in Blacklist)
                                {
                                    PluginModuleInfo.Platforms.Remove(Platform);
                                }
                            }
                        }

                        object ModuleShouldBuild;
                        if( ModuleDict.TryGetValue( "bShouldBuild", out ModuleShouldBuild ) )
                        {
                            PluginInfo.bShouldBuild = (Int64)ModuleShouldBuild == 1 ? true : false;
                        }
                        else
                        {
                            PluginInfo.bShouldBuild = true;
                        }

                        if (PluginInfo.bShouldBuild)
                        {
                            // add to list of modules
                            PluginInfo.Modules.Add(PluginModuleInfo);
                        }
                    }
                }
                else
                {
                    // Plugin contains no modules array.  That's fine.
                }
            }

            return PluginInfo;
        }
Пример #4
0
        /// <summary>
        /// Recursively locates all plugins in the specified folder, appending to the incoming list
        /// </summary>
        /// <param name="PluginsDirectory">Directory to search</param>
        /// <param name="LoadedFrom">Where we're loading these plugins from</param>
        /// <param name="Plugins">List of plugins found so far</param>
        private static void FindPluginsRecursively(string PluginsDirectory, PluginInfo.LoadedFromType LoadedFrom, ref List<PluginInfo> Plugins)
        {
            // NOTE: The logic in this function generally matches that of the C++ code for FindPluginsRecursively
            //       in the core engine code.  These routines should be kept in sync.

            // Each sub-directory is possibly a plugin.  If we find that it contains a plugin, we won't recurse any
            // further -- you can't have plugins within plugins.  If we didn't find a plugin, we'll keep recursing.

            var PluginsDirectoryInfo = new DirectoryInfo(PluginsDirectory);
            foreach( var PossiblePluginDirectory in PluginsDirectoryInfo.EnumerateDirectories() )
            {
                if (!UnrealBuildTool.IsPathIgnoredForBuild(PossiblePluginDirectory.FullName))
                {
                    // Do we have a plugin descriptor in this directory?
                    bool bFoundPlugin = false;
                    foreach (var PluginDescriptorFileName in Directory.GetFiles(PossiblePluginDirectory.FullName, "*" + PluginDescriptorFileExtension))
                    {
                        // Found a plugin directory!  No need to recurse any further, but make sure it's unique.
                        if (!Plugins.Any(x => x.Directory == PossiblePluginDirectory.FullName))
                        {
                            // Load the plugin info and keep track of it
                            var PluginDescriptorFile = new FileInfo(PluginDescriptorFileName);
                            var PluginInfo = LoadPluginDescriptor(PluginDescriptorFile, LoadedFrom);

                            Plugins.Add(PluginInfo);
                            bFoundPlugin = true;
                            Log.TraceVerbose("Found plugin in: " + PluginInfo.Directory);
                        }

                        // No need to search for more plugins
                        break;
                    }

                    if (!bFoundPlugin)
                    {
                        // Didn't find a plugin in this directory.  Continue to look in subfolders.
                        FindPluginsRecursively(PossiblePluginDirectory.FullName, LoadedFrom, ref Plugins);
                    }
                }
            }
        }
Пример #5
0
        /// <summary>
        /// Read all the plugin descriptors under the given directory
        /// </summary>
        /// <param name="ParentDirectory">The parent directory to look in.</param>
        /// <param name="LoadedFrom">The directory type</param>
        /// <returns>Sequence of the found PluginInfo object.</returns>
        public static IReadOnlyList<PluginInfo> ReadPluginsFromDirectory(DirectoryReference ParentDirectory, PluginLoadedFrom LoadedFrom)
		{
			List<PluginInfo> Plugins;
			if (!PluginInfoCache.TryGetValue(ParentDirectory, out Plugins))
			{
				Plugins = new List<PluginInfo>();
				foreach (FileReference PluginFileName in EnumeratePlugins(ParentDirectory))
				{
					PluginInfo Plugin = new PluginInfo(PluginFileName, LoadedFrom);
					Plugins.Add(Plugin);
				}
				PluginInfoCache.Add(ParentDirectory, Plugins);
			}
			return Plugins;
		}
Пример #6
0
		/// <summary>
		/// Determine if a plugin is enabled for a given project
		/// </summary>
		/// <param name="Project">The project to check</param>
		/// <param name="Plugin">Information about the plugin</param>
		/// <param name="Platform">The target platform</param>
		/// <returns>True if the plugin should be enabled for this project</returns>
		public static bool IsPluginDescriptorRequiredForProject(PluginInfo Plugin, ProjectDescriptor Project, UnrealTargetPlatform Platform, TargetRules.TargetType TargetType, bool bBuildDeveloperTools, bool bBuildEditor)
		{
			// Check if it's referenced by name from the project descriptor. If it is, we'll need the plugin to be included with the project regardless of whether it has
			// any platform-specific modules or content, just so the runtime can make the call.
			if (Project != null && Project.Plugins != null)
			{
				foreach (PluginReferenceDescriptor PluginReference in Project.Plugins)
				{
					if (String.Compare(PluginReference.Name, Plugin.Name, true) == 0)
					{
						return PluginReference.IsEnabledForPlatform(Platform) && PluginReference.IsEnabledForTarget(TargetType);
					}
				}
			}

			// If the plugin contains content, it should be included for all platforms
			if(Plugin.Descriptor.bCanContainContent)
			{
				return true;
			}

			// Check if the plugin has any modules for the given target
			foreach (ModuleDescriptor Module in Plugin.Descriptor.Modules)
			{
				if(Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor))
				{
					return true;
				}
			}

			return false;
		}
Пример #7
0
        /// <summary>
        /// Loads a plugin descriptor file and fills out a new PluginInfo structure.  Throws an exception on failure.
        /// </summary>
        /// <param name="PluginFile">The path to the plugin file to load</param>
        /// <param name="LoadedFrom">Where the plugin was loaded from</param>
        /// <returns>New PluginInfo for the loaded descriptor.</returns>
        private static PluginInfo LoadPluginDescriptor(FileInfo PluginFileInfo, PluginInfo.LoadedFromType LoadedFrom)
        {
            // Load the file up (JSon format)
            Dictionary <string, object> PluginDescriptorDict;
            {
                string FileContent;
                using (var StreamReader = new StreamReader(PluginFileInfo.FullName))
                {
                    FileContent = StreamReader.ReadToEnd();
                }

                // Parse the Json into a dictionary
                var CaseSensitiveJSonDict = fastJSON.JSON.Instance.ToObject <Dictionary <string, object> >(FileContent);

                // Convert to a case-insensitive dictionary, so that we can be more tolerant of hand-typed files
                PluginDescriptorDict = new Dictionary <string, object>(CaseSensitiveJSonDict, StringComparer.InvariantCultureIgnoreCase);
            }


            // File version check
            long PluginVersionNumber;
            {
                // Try to get the version of the plugin
                object PluginVersionObject;
                if (!PluginDescriptorDict.TryGetValue("FileVersion", out PluginVersionObject))
                {
                    if (!PluginDescriptorDict.TryGetValue("PluginFileVersion", out PluginVersionObject))
                    {
                        throw new BuildException("Plugin descriptor file '{0}' does not contain a valid FileVersion entry", PluginFileInfo.FullName);
                    }
                }

                if (!(PluginVersionObject is long))
                {
                    throw new BuildException("Unable to parse the version number of the plugin descriptor file '{0}'", PluginFileInfo.FullName);
                }

                PluginVersionNumber = (long)PluginVersionObject;
                if (PluginVersionNumber > LatestPluginDescriptorFileVersion)
                {
                    throw new BuildException("Plugin descriptor file '{0}' appears to be in a newer version ({1}) of the file format that we can load (max version: {2}).", PluginFileInfo.FullName, PluginVersionNumber, LatestPluginDescriptorFileVersion);
                }

                // @todo plugin: Should we also test the engine version here?  (we would need to load it from build.properties)
            }


            // NOTE: At this point, we can use PluginVersionNumber to handle backwards compatibility when loading the rest of the file!


            var PluginInfo = new PluginInfo();

            PluginInfo.LoadedFrom = LoadedFrom;
            PluginInfo.Directory  = PluginFileInfo.Directory.FullName;
            PluginInfo.Name       = Path.GetFileName(PluginInfo.Directory);

            // Determine whether the plugin should be enabled by default
            object EnabledByDefaultObject;

            if (PluginDescriptorDict.TryGetValue("EnabledByDefault", out EnabledByDefaultObject) && (EnabledByDefaultObject is bool))
            {
                PluginInfo.bEnabledByDefault = (bool)EnabledByDefaultObject;
            }

            // This plugin might have some modules that we need to know about.  Let's take a look.
            {
                object ModulesObject;
                if (PluginDescriptorDict.TryGetValue("Modules", out ModulesObject))
                {
                    if (!(ModulesObject is Array))
                    {
                        throw new BuildException("Found a 'Modules' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName);
                    }

                    var ModulesArray = (Array)ModulesObject;
                    foreach (var ModuleObject in ModulesArray)
                    {
                        var ModuleDict = new Dictionary <string, object>((Dictionary <string, object>)ModuleObject, StringComparer.InvariantCultureIgnoreCase);

                        var PluginModuleInfo = new PluginInfo.PluginModuleInfo();

                        // Module name
                        {
                            // All modules require a name to be set
                            object ModuleNameObject;
                            if (!ModuleDict.TryGetValue("Name", out ModuleNameObject))
                            {
                                throw new BuildException("Found a 'Module' entry with a missing 'Name' field in plugin descriptor file '{0}'", PluginFileInfo.FullName);
                            }
                            string ModuleName = (string)ModuleNameObject;

                            // @todo plugin: Locate this module right now and validate it?  Repair case?
                            PluginModuleInfo.Name = ModuleName;
                        }


                        // Module type
                        {
                            // Check to see if the user specified the module's type
                            object ModuleTypeObject;
                            if (!ModuleDict.TryGetValue("Type", out ModuleTypeObject))
                            {
                                throw new BuildException("Found a Module entry '{0}' with a missing 'Type' field in plugin descriptor file '{1}'", PluginModuleInfo.Name, PluginFileInfo.FullName);
                            }
                            string ModuleTypeString = (string)ModuleTypeObject;

                            // Check to see if this is a valid type
                            bool FoundValidType = false;
                            foreach (PluginInfo.PluginModuleType PossibleType in Enum.GetValues(typeof(PluginInfo.PluginModuleType)))
                            {
                                if (ModuleTypeString.Equals(PossibleType.ToString(), StringComparison.InvariantCultureIgnoreCase))
                                {
                                    FoundValidType        = true;
                                    PluginModuleInfo.Type = PossibleType;
                                    break;
                                }
                            }
                            if (!FoundValidType)
                            {
                                throw new BuildException("Module entry '{0}' specified an unrecognized module Type '{1}' in plugin descriptor file '{0}'", PluginModuleInfo.Name, ModuleTypeString, PluginFileInfo.FullName);
                            }
                        }

                        // Supported platforms
                        PluginModuleInfo.Platforms = new List <UnrealTargetPlatform>();

                        // look for white and blacklists
                        object WhitelistObject, BlacklistObject;
                        ModuleDict.TryGetValue("WhitelistPlatforms", out WhitelistObject);
                        ModuleDict.TryGetValue("BlacklistPlatforms", out BlacklistObject);

                        if (WhitelistObject != null && BlacklistObject != null)
                        {
                            throw new BuildException("Found a module '{0}' with both blacklist and whitelist platform lists in plugin file '{1}'", PluginModuleInfo.Name, PluginFileInfo.FullName);
                        }

                        // now process the whitelist
                        if (WhitelistObject != null)
                        {
                            if (!(WhitelistObject is Array))
                            {
                                throw new BuildException("Found a 'WhitelistPlatforms' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName);
                            }

                            // put the whitelist array directly into the plugin's modulelist
                            ConvertPlatformArrayToList((Array)WhitelistObject, ref PluginModuleInfo.Platforms, PluginFileInfo.FullName);
                        }
                        // handle the blacklist (or lack of blacklist and whitelist which means all platforms)
                        else
                        {
                            // start with all platforms supported
                            foreach (UnrealTargetPlatform Platform in Enum.GetValues(typeof(UnrealTargetPlatform)))
                            {
                                PluginModuleInfo.Platforms.Add(Platform);
                            }

                            // if we want to disallow some platforms, then pull them out now
                            if (BlacklistObject != null)
                            {
                                if (!(BlacklistObject is Array))
                                {
                                    throw new BuildException("Found a 'BlacklistPlatforms' entry in plugin descriptor file '{0}', but it doesn't appear to be in the array format that we were expecting.", PluginFileInfo.FullName);
                                }

                                // put the whitelist array directly into the plugin's modulelist
                                List <UnrealTargetPlatform> Blacklist = new List <UnrealTargetPlatform>();
                                ConvertPlatformArrayToList((Array)BlacklistObject, ref Blacklist, PluginFileInfo.FullName);

                                // now remove them from the module platform list
                                foreach (UnrealTargetPlatform Platform in Blacklist)
                                {
                                    PluginModuleInfo.Platforms.Remove(Platform);
                                }
                            }
                        }

                        object ModuleShouldBuild;
                        if (ModuleDict.TryGetValue("bShouldBuild", out ModuleShouldBuild))
                        {
                            PluginInfo.bShouldBuild = (Int64)ModuleShouldBuild == 1 ? true : false;
                        }
                        else
                        {
                            PluginInfo.bShouldBuild = true;
                        }

                        if (PluginInfo.bShouldBuild)
                        {
                            // add to list of modules
                            PluginInfo.Modules.Add(PluginModuleInfo);
                        }
                    }
                }
                else
                {
                    // Plugin contains no modules array.  That's fine.
                }
            }

            return(PluginInfo);
        }
Пример #8
0
        /// <summary>
        /// Read all the plugin descriptors under the given directory
        /// </summary>
        /// <param name="RootDirectory">The directory to look in.</param>
        /// <param name="Subdirectory">A subdirectory to look in in RootDirectory and any other Platform directories under Root</param>
        /// <param name="Type">The plugin type</param>
        /// <returns>Sequence of the found PluginInfo object.</returns>
        public static IReadOnlyList <PluginInfo> ReadPluginsFromDirectory(DirectoryReference RootDirectory, string Subdirectory, PluginType Type)
        {
            // look for directories in RootDirectory and and Platform directories under RootDirectory
            List <DirectoryReference> RootDirectories = new List <DirectoryReference>()
            {
                DirectoryReference.Combine(RootDirectory, Subdirectory)
            };

            // now look for platform subdirectories with the Subdirectory
            DirectoryReference PlatformDirectory = DirectoryReference.Combine(RootDirectory, "Platforms");

            if (DirectoryReference.Exists(PlatformDirectory))
            {
                foreach (DirectoryReference Dir in DirectoryReference.EnumerateDirectories(PlatformDirectory))
                {
                    RootDirectories.Add(DirectoryReference.Combine(Dir, Subdirectory));
                }
            }

            Dictionary <PluginInfo, FileReference> ChildPlugins = new Dictionary <PluginInfo, FileReference>();
            List <PluginInfo> AllParentPlugins = new List <PluginInfo>();

            foreach (DirectoryReference Dir in RootDirectories)
            {
                if (!DirectoryReference.Exists(Dir))
                {
                    continue;
                }

                List <PluginInfo> Plugins;
                if (!PluginInfoCache.TryGetValue(Dir, out Plugins))
                {
                    Plugins = new List <PluginInfo>();
                    foreach (FileReference PluginFileName in EnumeratePlugins(Dir))
                    {
                        PluginInfo Plugin = new PluginInfo(PluginFileName, Type);

                        // is there a parent to merge up into?
                        if (Plugin.Descriptor.bIsPluginExtension)
                        {
                            ChildPlugins.Add(Plugin, PluginFileName);
                        }
                        else
                        {
                            Plugins.Add(Plugin);
                        }
                    }
                    PluginInfoCache.Add(Dir, Plugins);
                }

                // gather all of the plugins into one list
                AllParentPlugins.AddRange(Plugins);
            }

            // now that all parent plugins are read in, we can let the children look up the parents
            foreach (KeyValuePair <PluginInfo, FileReference> Pair in ChildPlugins)
            {
                TryMergeWithParent(Pair.Key, Pair.Value);
            }

            return(AllParentPlugins);
        }
Пример #9
0
		/** Checks whether a plugin path contains a platform directory fragment */
		private static bool ShouldExcludePlugin(PluginInfo Plugin, List<string> ExcludeFragments)
		{
			string RelativePathFromRoot;
			if(Plugin.LoadedFrom == PluginLoadedFrom.Engine)
			{
				RelativePathFromRoot = Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(Plugin.FileName, BuildConfiguration.RelativeEnginePath), '/');
			}
			else
			{
				RelativePathFromRoot = Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(Plugin.FileName, UnrealBuildTool.GetUProjectPath()), '/');
			}
			return ExcludeFragments.Any(x => RelativePathFromRoot.Contains(x));
		}
Пример #10
0
        /// <summary>
        /// Include the given plugin module in the target. Will be built in the appropriate subfolder under the plugin directory.
        /// </summary>
        public List<string> AddPluginModule(PluginInfo Plugin, PluginInfo.PluginModuleInfo Module)
        {
            var SpecialRocketLibFilesThatAreBuildProducts = new List<string>();

            bool bCompileMonolithic = ShouldCompileMonolithic();

            // Get the binary type to build
            UEBuildBinaryType BinaryType = bCompileMonolithic ? UEBuildBinaryType.StaticLibrary : UEBuildBinaryType.DynamicLinkLibrary;

            // Get the output path. Don't prefix the app name for Rocket
            string[] OutputFilePaths;
            if ((UnrealBuildTool.BuildingRocket() || UnrealBuildTool.RunningRocket()) && bCompileMonolithic)
            {
                OutputFilePaths = MakeBinaryPaths(Module.Name, Module.Name, BinaryType, TargetType, Plugin, AppName);
                if (UnrealBuildTool.BuildingRocket())
                {
                    SpecialRocketLibFilesThatAreBuildProducts.AddRange(OutputFilePaths);
                }
            }
            else
            {
                OutputFilePaths = MakeBinaryPaths(Module.Name, GetAppName() + "-" + Module.Name, BinaryType, TargetType, Plugin, AppName);
            }

            // Try to determine if we have the rules file
            var ModuleFilename = RulesCompiler.GetModuleFilename(Module.Name);
            var bHasModuleRules = String.IsNullOrEmpty(ModuleFilename) == false;

            // Figure out whether we should build it from source
            var ModuleSourceFolder = bHasModuleRules ? Path.GetDirectoryName(RulesCompiler.GetModuleFilename(Module.Name)) : ModuleFilename;
            bool bShouldBeBuiltFromSource = bHasModuleRules && Directory.GetFiles(ModuleSourceFolder, "*.cpp", SearchOption.AllDirectories).Length > 0;

            string PluginIntermediateBuildPath;
            {
                if (Plugin.LoadedFrom == PluginInfo.LoadedFromType.Engine)
                {
                    // Plugin folder is in the engine directory
                    var PluginConfiguration = Configuration == UnrealTargetConfiguration.DebugGame ? UnrealTargetConfiguration.Development : Configuration;
                    PluginIntermediateBuildPath = Path.GetFullPath(Path.Combine(BuildConfiguration.RelativeEnginePath, BuildConfiguration.PlatformIntermediateFolder, AppName, PluginConfiguration.ToString()));
                }
                else
                {
                    // Plugin folder is in the project directory
                    PluginIntermediateBuildPath = Path.GetFullPath(Path.Combine(ProjectDirectory, BuildConfiguration.PlatformIntermediateFolder, GetTargetName(), Configuration.ToString()));
                }
                PluginIntermediateBuildPath = Path.Combine(PluginIntermediateBuildPath, "Plugins", ShouldCompileMonolithic() ? "Static" : "Dynamic");
            }

            // Create the binary
            UEBuildBinaryConfiguration Config = new UEBuildBinaryConfiguration( InType:                  BinaryType,
                                                                                InOutputFilePaths:       OutputFilePaths,
                                                                                InIntermediateDirectory: PluginIntermediateBuildPath,
                                                                                bInAllowExports:         true,
                                                                                bInAllowCompilation:     bShouldBeBuiltFromSource,
                                                                                bInHasModuleRules:       bHasModuleRules,
                                                                                InModuleNames:           new List<string> { Module.Name } );
            AppBinaries.Add(new UEBuildBinaryCPP(this, Config));
            return SpecialRocketLibFilesThatAreBuildProducts;
        }
Пример #11
0
 /// <summary>
 /// Include the given plugin in the target. It may be included as a separate binary, or compiled into a monolithic executable.
 /// </summary>
 public List<string> AddPlugin(PluginInfo Plugin)
 {
     var SpecialRocketLibFilesThatAreBuildProducts = new List<string>();
     foreach(PluginInfo.PluginModuleInfo Module in Plugin.Modules)
     {
         if (ShouldIncludePluginModule(Plugin, Module))
         {
             SpecialRocketLibFilesThatAreBuildProducts.AddRange(AddPluginModule(Plugin, Module));
         }
     }
     return SpecialRocketLibFilesThatAreBuildProducts;
 }
Пример #12
0
        /** Given a UBT-built binary name (e.g. "Core"), returns a relative path to the binary for the current build configuration (e.g. "../Binaries/Win64/Core-Win64-Debug.lib") */
        public static string[] MakeBinaryPaths(string ModuleName, string BinaryName, UnrealTargetPlatform Platform, 
			UnrealTargetConfiguration Configuration, UEBuildBinaryType BinaryType, TargetRules.TargetType? TargetType, PluginInfo PluginInfo, string AppName, bool bForceNameAsForDevelopment = false, string ExeBinariesSubFolder = null)
        {
            // Determine the binary extension for the platform and binary type.
            var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform);
            string BinaryExtension = BuildPlatform.GetBinaryExtension(BinaryType);

            UnrealTargetConfiguration LocalConfig = Configuration;
            if(Configuration == UnrealTargetConfiguration.DebugGame && !String.IsNullOrEmpty(ModuleName) && !RulesCompiler.IsGameModule(ModuleName))
            {
                LocalConfig = UnrealTargetConfiguration.Development;
            }

            string ModuleBinariesSubDir = "";
            if (BinaryType == UEBuildBinaryType.DynamicLinkLibrary && (string.IsNullOrEmpty(ModuleName) == false))
            {
                // Allow for modules to specify sub-folders in the Binaries folder
                var RulesFilename = RulesCompiler.GetModuleFilename(ModuleName);
                // Plugins can be binary-only and can have no rules object
                if (PluginInfo == null || !String.IsNullOrEmpty(RulesFilename))
                {
                    ModuleRules ModuleRulesObj = RulesCompiler.CreateModuleRules(ModuleName, new TargetInfo(Platform, Configuration, TargetType), out RulesFilename);
                    if (ModuleRulesObj != null)
                    {
                        ModuleBinariesSubDir = ModuleRulesObj.BinariesSubFolder;
                    }
                }
            }
            else if ( BinaryType == UEBuildBinaryType.Executable && string.IsNullOrEmpty(ExeBinariesSubFolder) == false )
            {
                ModuleBinariesSubDir = ExeBinariesSubFolder;
            }

            //@todo.Rocket: This just happens to work since exp and lib files go into intermediate...

            // Build base directory string ("../Binaries/<Platform>/")
            string BinariesDirName;
            if(TargetType.HasValue && TargetType.Value == TargetRules.TargetType.Program && UnrealBuildTool.HasUProjectFile() && !ProjectFileGenerator.bGenerateProjectFiles)
            {
                BinariesDirName = Path.Combine( UnrealBuildTool.GetUProjectPath(), "Binaries" );
            }
            else if( PluginInfo != null )
            {
                BinariesDirName = Path.Combine( PluginInfo.Directory, "Binaries" );
            }
            else
            {
                BinariesDirName = Path.Combine( "..", "Binaries" );
            }
            var BaseDirectory = Path.Combine( BinariesDirName, Platform.ToString());
            if (ModuleBinariesSubDir.Length > 0)
            {
                BaseDirectory = Path.Combine(BaseDirectory, ModuleBinariesSubDir);
            }

            string BinarySuffix = "";
            if ((PluginInfo != null) && (BinaryType != UEBuildBinaryType.DynamicLinkLibrary))
            {
                BinarySuffix = "-Static";
            }

            // append the architecture to the end of the binary name
            BinarySuffix = BuildPlatform.ApplyArchitectureName(BinarySuffix);

            string OutBinaryPath = "";
            // Append binary file name
            string Prefix = "";
            if (Platform == UnrealTargetPlatform.Linux && (BinaryType == UEBuildBinaryType.DynamicLinkLibrary || BinaryType == UEBuildBinaryType.StaticLibrary))
            {
                Prefix = "lib";
            }
            if (LocalConfig == UnrealTargetConfiguration.Development || bForceNameAsForDevelopment)
            {
                OutBinaryPath = Path.Combine(BaseDirectory, String.Format("{3}{0}{1}{2}", BinaryName, BinarySuffix, BinaryExtension, Prefix));
            }
            else
            {
                OutBinaryPath = Path.Combine(BaseDirectory, String.Format("{5}{0}-{1}-{2}{3}{4}",
                    BinaryName, Platform.ToString(), LocalConfig.ToString(), BinarySuffix, BinaryExtension, Prefix));
            }

            return BuildPlatform.FinalizeBinaryPaths(OutBinaryPath);
        }
Пример #13
0
        /// <summary>
        /// Determines whether the given plugin module is part of the current build.
        /// </summary>
        private bool ShouldIncludePluginModule(PluginInfo Plugin, PluginInfo.PluginModuleInfo Module)
        {
            // Check it can be built for this platform...
            if (Module.Platforms.Contains(Platform))
            {
                // ...and that it's appropriate for the current build environment.
                switch (Module.Type)
                {
                    case PluginInfo.PluginModuleType.Runtime:
                    case PluginInfo.PluginModuleType.RuntimeNoCommandlet:
                        return true;

                    case PluginInfo.PluginModuleType.Developer:
                        return UEBuildConfiguration.bBuildDeveloperTools;

                    case PluginInfo.PluginModuleType.Editor:
                    case PluginInfo.PluginModuleType.EditorNoCommandlet:
                        return UEBuildConfiguration.bBuildEditor;

                    case PluginInfo.PluginModuleType.Program:
                        return TargetType == TargetRules.TargetType.Program;
                }
            }
            return false;
        }
Пример #14
0
 /** Given a UBT-built binary name (e.g. "Core"), returns a relative path to the binary for the current build configuration (e.g. "../../Binaries/Win64/Core-Win64-Debug.lib") */
 public string[] MakeBinaryPaths(string ModuleName, string BinaryName, UEBuildBinaryType BinaryType, TargetRules.TargetType? TargetType, PluginInfo PluginInfo, string AppName, bool bForceNameAsForDevelopment = false, string ExeBinariesSubFolder = null)
 {
     if (String.IsNullOrEmpty(ModuleName) && Configuration == UnrealTargetConfiguration.DebugGame && !bCompileMonolithic)
     {
         return MakeBinaryPaths(ModuleName, BinaryName, Platform, UnrealTargetConfiguration.Development, BinaryType, TargetType, PluginInfo, AppName, bForceNameAsForDevelopment);
     }
     else
     {
         return MakeBinaryPaths(ModuleName, BinaryName, Platform, Configuration, BinaryType, TargetType, PluginInfo, AppName, bForceNameAsForDevelopment, ExeBinariesSubFolder);
     }
 }
Пример #15
0
		/// <summary>
		/// Tries to find the PluginInfo associated with a given module file
		/// </summary>
		/// <param name="ModuleFile">The module to search for</param>
		/// <param name="Plugin">The matching plugin info, or null.</param>
		/// <returns>True if the module belongs to a plugin</returns>
		public bool TryGetPluginForModule(FileReference ModuleFile, out PluginInfo Plugin)
		{
			if (ModuleFileToPluginInfo.TryGetValue(ModuleFile, out Plugin))
			{
				return true;
			}
			else
			{
				return (Parent == null) ? false : Parent.TryGetPluginForModule(ModuleFile, out Plugin);
			}
		}
Пример #16
0
        /// <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?!?
        }
Пример #17
0
        /// <summary>
        /// Include the given plugin in the target. It may be included as a separate binary, or compiled into a monolithic executable.
        /// </summary>
        public void AddPlugin(PluginInfo Plugin)
        {
            UEBuildBinaryType BinaryType = ShouldCompileMonolithic() ? UEBuildBinaryType.StaticLibrary : UEBuildBinaryType.DynamicLinkLibrary;
            if(Plugin.Descriptor.Modules != null)
            {
                foreach(ModuleDescriptor Module in Plugin.Descriptor.Modules)
                {
                    if (Module.IsCompiledInConfiguration(Platform, TargetType, UEBuildConfiguration.bBuildDeveloperTools, UEBuildConfiguration.bBuildEditor))
                    {
                        // Add the corresponding binary for it
                        string ModuleFileName = RulesCompiler.GetModuleFilename(Module.Name);
                        bool bHasSource = (!String.IsNullOrEmpty(ModuleFileName) && Directory.EnumerateFiles(Path.GetDirectoryName(ModuleFileName), "*.cpp", SearchOption.AllDirectories).Any());
                        AddBinaryForModule(Module.Name, BinaryType, bAllowCompilation: bHasSource, bIsCrossTarget: false);

                        // Add it to the binary if we're compiling monolithic (and it's enabled)
                        if(ShouldCompileMonolithic() && EnabledPlugins.Contains(Plugin))
                        {
                            AppBinaries[0].AddModule(Module.Name);
                        }
                    }
                }
            }
        }
Пример #18
0
 /// <summary>
 /// Determine if a plugin is enabled for a given project
 /// </summary>
 /// <param name="Project">The project to check</param>
 /// <param name="Plugin">Information about the plugin</param>
 /// <param name="Platform">The target platform</param>
 /// <returns>True if the plugin should be enabled for this project</returns>
 public static bool IsPluginEnabledForProject(PluginInfo Plugin, ProjectDescriptor Project, UnrealTargetPlatform Platform)
 {
     bool bEnabled = Plugin.Descriptor.bEnabledByDefault || Plugin.LoadedFrom == PluginLoadedFrom.GameProject;
     if(Project != null && Project.Plugins != null)
     {
         foreach(PluginReferenceDescriptor PluginReference in Project.Plugins)
         {
             if(String.Compare(PluginReference.Name, Plugin.Name, true) == 0)
             {
                 bEnabled = PluginReference.IsEnabledForPlatform(Platform);
             }
         }
     }
     return bEnabled;
 }
Пример #19
0
        /** Sets up the plugins for this target */
        protected virtual void SetupPlugins()
        {
            // Filter the plugins list by the current project
            ValidPlugins = Plugins.ReadAvailablePlugins(UnrealBuildTool.GetUProjectFile());

            // Remove any plugins for platforms we don't have
            foreach (UnrealTargetPlatform TargetPlatform in Enum.GetValues(typeof(UnrealTargetPlatform)))
            {
                if (TargetPlatform != UnrealTargetPlatform.Desktop && UEBuildPlatform.GetBuildPlatform(TargetPlatform, true) == null)
                {
                    string DirectoryFragment = String.Format("/{0}/", TargetPlatform.ToString());
                    ValidPlugins.RemoveAll(x => x.Directory.Replace('\\', '/').Contains(DirectoryFragment));
                }
            }

            // Build a list of enabled plugins
            EnabledPlugins = new List<PluginInfo>();

            // If we're compiling against the engine, add the plugins enabled for this target
            if(UEBuildConfiguration.bCompileAgainstEngine)
            {
                ProjectDescriptor Project = UnrealBuildTool.HasUProjectFile()? ProjectDescriptor.FromFile(UnrealBuildTool.GetUProjectFile()) : null;
                foreach(PluginInfo ValidPlugin in ValidPlugins)
                {
                    if(UProjectInfo.IsPluginEnabledForProject(ValidPlugin, Project, Platform))
                    {
                        EnabledPlugins.Add(ValidPlugin);
                    }
                }
            }

            // Add the plugins explicitly required by the target rules
            foreach(string AdditionalPlugin in Rules.AdditionalPlugins)
            {
                PluginInfo Plugin = ValidPlugins.FirstOrDefault(ValidPlugin => ValidPlugin.Name == AdditionalPlugin);
                if(Plugin == null)
                {
                    throw new BuildException("Plugin '{0}' is in the list of additional plugins for {1}, but was not found.", AdditionalPlugin, TargetName);
                }
                if(!EnabledPlugins.Contains(Plugin))
                {
                    EnabledPlugins.Add(Plugin);
                }
            }

            // Set the list of plugins that should be built
            if (bPrecompile && TargetType != TargetRules.TargetType.Program)
            {
                BuildPlugins = new List<PluginInfo>(ValidPlugins);
            }
            else
            {
                BuildPlugins = new List<PluginInfo>(EnabledPlugins);
            }

            // Add any foreign plugins to the list
            if(ForeignPlugins != null)
            {
                foreach(string ForeignPlugin in ForeignPlugins)
                {
                    PluginInfo ForeignPluginInfo = new PluginInfo(ForeignPlugin, PluginLoadedFrom.GameProject);
                    ValidPlugins.Add(ForeignPluginInfo);
                    BuildPlugins.Add(ForeignPluginInfo);
                }
            }
        }
Пример #20
0
		/// <summary>
		/// Determine if a plugin is enabled for a given project
		/// </summary>
		/// <param name="Project">The project to check</param>
		/// <param name="Plugin">Information about the plugin</param>
		/// <param name="Platform">The target platform</param>
		/// <returns>True if the plugin should be enabled for this project</returns>
		public static bool IsPluginEnabledForProject(PluginInfo Plugin, ProjectDescriptor Project, UnrealTargetPlatform Platform, TargetRules.TargetType Target)
		{
			bool bEnabled = Plugin.Descriptor.bEnabledByDefault;
			if (Project != null && Project.Plugins != null)
			{
				foreach (PluginReferenceDescriptor PluginReference in Project.Plugins)
				{
					if (String.Compare(PluginReference.Name, Plugin.Name, true) == 0)
					{
						bEnabled = PluginReference.IsEnabledForPlatform(Platform) && PluginReference.IsEnabledForTarget(Target);
					}
				}
			}
			return bEnabled;
		}
Пример #21
0
 /// <summary>
 /// Finds all plugins in the specified base directory
 /// </summary>
 /// <param name="PluginsDirectory">Base directory to search.  All subdirectories will be searched, except directories within other plugins.</param>
 /// <param name="LoadedFrom">Where we're loading these plugins from</param>
 /// <param name="Plugins">List of all of the plugins we found</param>
 public static void FindPluginsIn(string PluginsDirectory, PluginInfo.LoadedFromType LoadedFrom, ref List<PluginInfo> Plugins)
 {
     if (Directory.Exists(PluginsDirectory))
     {
         FindPluginsRecursively(PluginsDirectory, LoadedFrom, ref Plugins);
     }
 }
Пример #22
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="Info">The static plugin information</param>
 public UEBuildPlugin(PluginInfo Info)
 {
     this.Info = Info;
 }
Пример #23
0
        /// <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;
                    }
                }
            }
            else
            {
                throw new BuildException("Platform extension plugin {0} was named improperly. It must be in the form <ParentPlugin>_<Platform>.uplugin", Filename);
            }

            // did we find a parent plugin?
            if (Parent == null)
            {
                throw new BuildException("Unable to find parent plugin {0} for platform extension plugin {1}. Make sure {0}.uplugin exists.", Tokens[0], 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);

            // this should cause an error if it's invalid platform name
            //UnrealTargetPlatform Platform = UnrealTargetPlatform.Parse(PlatformName);

            // merge the supported platforms
            if (Child.Descriptor.SupportedTargetPlatforms != null)
            {
                if (Parent.Descriptor.SupportedTargetPlatforms == null)
                {
                    Parent.Descriptor.SupportedTargetPlatforms = Child.Descriptor.SupportedTargetPlatforms;
                }
                else
                {
                    Parent.Descriptor.SupportedTargetPlatforms = Parent.Descriptor.SupportedTargetPlatforms.Union(Child.Descriptor.SupportedTargetPlatforms).ToList();
                }
            }

            // make sure we are whitelisted for any modules we list
            if (Child.Descriptor.Modules != null)
            {
                if (Parent.Descriptor.Modules == null)
                {
                    Parent.Descriptor.Modules = Child.Descriptor.Modules;
                }
                else
                {
                    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 (ChildModule.WhitelistPlatforms != null)
                            {
                                if (ParentModule.WhitelistPlatforms == null)
                                {
                                    ParentModule.WhitelistPlatforms = ChildModule.WhitelistPlatforms;
                                }
                                else
                                {
                                    ParentModule.WhitelistPlatforms = ParentModule.WhitelistPlatforms.Union(ChildModule.WhitelistPlatforms).ToList();
                                }
                            }
                            if (ChildModule.BlacklistPlatforms != null)
                            {
                                if (ParentModule.BlacklistPlatforms == null)
                                {
                                    ParentModule.BlacklistPlatforms = ChildModule.BlacklistPlatforms;
                                }
                                else
                                {
                                    ParentModule.BlacklistPlatforms = ParentModule.BlacklistPlatforms.Union(ChildModule.BlacklistPlatforms).ToList();
                                }
                            }
                        }
                        else
                        {
                            Parent.Descriptor.Modules.Add(ChildModule);
                        }
                    }
                }
            }

            // make sure we are whitelisted for any plugins we list
            if (Child.Descriptor.Plugins != null)
            {
                if (Parent.Descriptor.Plugins == null)
                {
                    Parent.Descriptor.Plugins = Child.Descriptor.Plugins;
                }
                else
                {
                    foreach (PluginReferenceDescriptor ChildPluginReference in Child.Descriptor.Plugins)
                    {
                        PluginReferenceDescriptor ParentPluginReference = Parent.Descriptor.Plugins.FirstOrDefault(x => x.Name.Equals(ChildPluginReference.Name));
                        if (ParentPluginReference != null)
                        {
                            // we only need to whitelist the platform if the parent had a whitelist (otherwise, we could mistakenly remove all other platforms)
                            if (ParentPluginReference.WhitelistPlatforms != null)
                            {
                                if (ChildPluginReference.WhitelistPlatforms != null)
                                {
                                    ParentPluginReference.WhitelistPlatforms = ParentPluginReference.WhitelistPlatforms.Union(ChildPluginReference.WhitelistPlatforms).ToList();
                                }
                            }

                            // if we want to blacklist a platform, add it even if the parent didn't have a blacklist. this won't cause problems with other platforms
                            if (ChildPluginReference.BlacklistPlatforms != null)
                            {
                                if (ParentPluginReference.BlacklistPlatforms == null)
                                {
                                    ParentPluginReference.BlacklistPlatforms = ChildPluginReference.BlacklistPlatforms;
                                }
                                else
                                {
                                    ParentPluginReference.BlacklistPlatforms = ParentPluginReference.BlacklistPlatforms.Union(ChildPluginReference.BlacklistPlatforms).ToList();
                                }
                            }
                        }
                        else
                        {
                            Parent.Descriptor.Plugins.Add(ChildPluginReference);
                        }
                    }
                }
            }
            // @todo platplug: what else do we want to support merging?!?
        }