2019-01-02 14:54:39 -05:00
// Copyright 1998-2019 Epic Games, Inc. All Rights Reserved.
2014-03-14 14:13:41 -04:00
using System ;
using System.Collections.Generic ;
using System.Text ;
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
2014-04-29 11:21:18 -04:00
using System.Text.RegularExpressions ;
2014-03-14 14:13:41 -04:00
using System.Xml ;
2017-08-31 12:08:38 -04:00
using Tools.DotNETCommon ;
2014-03-14 14:13:41 -04:00
namespace UnrealBuildTool
{
2015-09-24 13:47:13 -04:00
/// <summary>
/// A unit of code compilation and linking.
/// </summary>
2017-01-30 16:52:08 -05:00
abstract class UEBuildModule
2014-03-14 14:13:41 -04:00
{
2015-09-24 13:47:13 -04:00
/// <summary>
/// The rules for this module
/// </summary>
2018-08-14 18:32:34 -04:00
public readonly ModuleRules Rules ;
/// <summary>
/// The name that uniquely identifies the module.
/// </summary>
public string Name
{
get { return Rules . Name ; }
}
2015-08-28 08:39:42 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Path to the module directory
/// </summary>
2018-08-14 18:32:34 -04:00
public DirectoryReference ModuleDirectory
{
get { return Rules . Directory ; }
}
2019-05-29 20:48:56 -04:00
/// <summary>
/// Paths to all potential module source directories (with platform extension directories added in)
/// </summary>
protected DirectoryReference [ ] ModuleDirectories ;
2018-08-14 18:32:34 -04:00
/// <summary>
/// The name of the .Build.cs file this module was created from, if any
/// </summary>
public FileReference RulesFile
{
get { return Rules . File ; }
}
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Is this module allowed to be redistributed.
/// </summary>
2014-07-21 04:28:22 -04:00
private readonly bool? IsRedistributableOverride ;
2015-09-24 13:47:13 -04:00
/// <summary>
/// The binary the module will be linked into for the current target. Only set after UEBuildBinary.BindModules is called.
/// </summary>
2014-03-14 14:13:41 -04:00
public UEBuildBinary Binary = null ;
2015-09-24 13:47:13 -04:00
/// <summary>
/// The name of the _API define for this module
/// </summary>
2015-09-08 15:50:24 -04:00
protected readonly string ModuleApiDefine ;
2019-02-06 14:44:31 -05:00
/// <summary>
/// The name of the _VTABLE define for this module
/// </summary>
protected readonly string ModuleVTableDefine ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all the public definitions
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < string > PublicDefinitions ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all public include paths
/// </summary>
2018-01-20 11:19:29 -05:00
protected readonly HashSet < DirectoryReference > PublicIncludePaths ;
/// <summary>
/// Nested public include paths which used to be added automatically, but are now only added for modules with bNestedPublicIncludePaths set.
/// </summary>
protected readonly HashSet < DirectoryReference > LegacyPublicIncludePaths = new HashSet < DirectoryReference > ( ) ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all private include paths
/// </summary>
2018-01-20 11:19:29 -05:00
protected readonly HashSet < DirectoryReference > PrivateIncludePaths ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all system include paths
/// </summary>
2018-01-20 11:19:29 -05:00
protected readonly HashSet < DirectoryReference > PublicSystemIncludePaths ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all public library paths
/// </summary>
2018-01-20 11:19:29 -05:00
protected readonly HashSet < DirectoryReference > PublicLibraryPaths ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of all additional libraries
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < string > PublicAdditionalLibraries ;
2017-01-30 16:52:08 -05:00
/// <summary>
/// Set of additional frameworks
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < string > PublicFrameworks ;
2017-01-30 16:52:08 -05:00
/// <summary>
///
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < string > PublicWeakFrameworks ;
2017-01-30 16:52:08 -05:00
/// <summary>
///
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < UEBuildFramework > PublicAdditionalFrameworks ;
2017-01-30 16:52:08 -05:00
/// <summary>
///
/// </summary>
2014-09-11 03:21:51 -04:00
protected readonly HashSet < UEBuildBundleResource > PublicAdditionalBundleResources ;
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Names of modules with header files that this module's public interface needs access to.
/// </summary>
2015-08-28 15:47:20 -04:00
protected List < UEBuildModule > PublicIncludePathModules ;
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Names of modules that this module's public interface depends on.
/// </summary>
2015-08-28 15:47:20 -04:00
protected List < UEBuildModule > PublicDependencyModules ;
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Names of DLLs that this module should delay load
/// </summary>
2014-09-11 03:21:51 -04:00
protected HashSet < string > PublicDelayLoadDLLs ;
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Names of modules with header files that this module's private implementation needs access to.
/// </summary>
2015-08-28 15:47:20 -04:00
protected List < UEBuildModule > PrivateIncludePathModules ;
2015-09-24 12:37:21 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Names of modules that this module's private implementation depends on.
/// </summary>
2015-08-28 15:47:20 -04:00
protected List < UEBuildModule > PrivateDependencyModules ;
2014-03-14 14:13:41 -04:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Extra modules this module may require at run time
/// </summary>
2015-08-28 15:47:20 -04:00
protected List < UEBuildModule > DynamicallyLoadedModules ;
2014-03-14 14:13:41 -04:00
2016-01-27 12:09:53 -05:00
/// <summary>
2017-01-30 16:52:08 -05:00
/// Set of all whitelisted restricted folder references
2016-01-27 12:09:53 -05:00
/// </summary>
2017-01-30 16:52:08 -05:00
private readonly HashSet < DirectoryReference > WhitelistRestrictedFolders ;
2016-01-27 12:09:53 -05:00
2017-01-30 16:52:08 -05:00
/// <summary>
/// Constructor
/// </summary>
2018-08-14 18:32:34 -04:00
/// <param name="Rules">Rules for this module</param>
public UEBuildModule ( ModuleRules Rules )
2014-03-14 14:13:41 -04:00
{
2018-08-14 18:32:34 -04:00
this . Rules = Rules ;
2015-09-08 07:59:23 -04:00
2015-09-08 15:50:24 -04:00
ModuleApiDefine = Name . ToUpperInvariant ( ) + "_API" ;
2019-02-06 14:44:31 -05:00
ModuleVTableDefine = Name . ToUpperInvariant ( ) + "_VTABLE" ;
2015-09-08 15:50:24 -04:00
2018-08-14 18:32:34 -04:00
PublicDefinitions = HashSetFromOptionalEnumerableStringParameter ( Rules . PublicDefinitions ) ;
PublicIncludePaths = CreateDirectoryHashSet ( Rules . PublicIncludePaths ) ;
PublicSystemIncludePaths = CreateDirectoryHashSet ( Rules . PublicSystemIncludePaths ) ;
PublicLibraryPaths = CreateDirectoryHashSet ( Rules . PublicLibraryPaths ) ;
PublicAdditionalLibraries = HashSetFromOptionalEnumerableStringParameter ( Rules . PublicAdditionalLibraries ) ;
PublicFrameworks = HashSetFromOptionalEnumerableStringParameter ( Rules . PublicFrameworks ) ;
PublicWeakFrameworks = HashSetFromOptionalEnumerableStringParameter ( Rules . PublicWeakFrameworks ) ;
2019-01-15 18:47:22 -05:00
PublicAdditionalFrameworks = new HashSet < UEBuildFramework > ( ) ;
if ( Rules . PublicAdditionalFrameworks ! = null )
{
foreach ( ModuleRules . Framework FrameworkRules in Rules . PublicAdditionalFrameworks )
{
UEBuildFramework Framework ;
if ( String . IsNullOrEmpty ( FrameworkRules . ZipPath ) )
{
Framework = new UEBuildFramework ( FrameworkRules . Name , FrameworkRules . CopyBundledAssets ) ;
}
else
{
Framework = new UEBuildFramework ( FrameworkRules . Name , FileReference . Combine ( ModuleDirectory , FrameworkRules . ZipPath ) , DirectoryReference . Combine ( UnrealBuildTool . EngineDirectory , "Intermediate" , "UnzippedFrameworks" , Name , Path . GetFileNameWithoutExtension ( FrameworkRules . ZipPath ) ) , FrameworkRules . CopyBundledAssets ) ;
}
PublicAdditionalFrameworks . Add ( Framework ) ;
}
}
PublicAdditionalBundleResources = Rules . AdditionalBundleResources = = null ? new HashSet < UEBuildBundleResource > ( ) : new HashSet < UEBuildBundleResource > ( Rules . AdditionalBundleResources . Select ( x = > new UEBuildBundleResource ( x ) ) ) ;
2018-08-14 18:32:34 -04:00
PublicDelayLoadDLLs = HashSetFromOptionalEnumerableStringParameter ( Rules . PublicDelayLoadDLLs ) ;
2018-05-29 15:28:56 -04:00
if ( Rules . bUsePrecompiled )
{
PrivateIncludePaths = new HashSet < DirectoryReference > ( ) ;
}
else
{
2018-08-14 18:32:34 -04:00
PrivateIncludePaths = CreateDirectoryHashSet ( Rules . PrivateIncludePaths ) ;
2018-05-29 15:28:56 -04:00
}
2018-08-14 18:32:34 -04:00
IsRedistributableOverride = Rules . IsRedistributableOverride ;
2017-01-30 16:52:08 -05:00
2018-08-14 18:32:34 -04:00
WhitelistRestrictedFolders = new HashSet < DirectoryReference > ( Rules . WhitelistRestrictedFolders . Select ( x = > DirectoryReference . Combine ( ModuleDirectory , x ) ) ) ;
2019-05-29 20:48:56 -04:00
// merge the main directory and any others set in the Rules
List < DirectoryReference > MergedDirectories = new List < DirectoryReference > { ModuleDirectory } ;
DirectoryReference [ ] ExtraModuleDirectories = Rules . GetModuleDirectoriesForAllSubClasses ( ) ;
if ( ExtraModuleDirectories ! = null )
{
MergedDirectories . AddRange ( ExtraModuleDirectories ) ;
}
// cache the results (it will always at least have the ModuleDirectory)
ModuleDirectories = MergedDirectories . ToArray ( ) ;
2017-01-30 16:52:08 -05:00
}
2017-03-30 10:07:15 -04:00
/// <summary>
/// Returns a list of this module's dependencies.
/// </summary>
/// <returns>An enumerable containing the dependencies of the module.</returns>
public HashSet < UEBuildModule > GetDependencies ( bool bWithIncludePathModules , bool bWithDynamicallyLoadedModules )
{
HashSet < UEBuildModule > Modules = new HashSet < UEBuildModule > ( ) ;
Modules . UnionWith ( PublicDependencyModules ) ;
Modules . UnionWith ( PrivateDependencyModules ) ;
if ( bWithIncludePathModules )
{
Modules . UnionWith ( PublicIncludePathModules ) ;
Modules . UnionWith ( PrivateIncludePathModules ) ;
}
if ( bWithDynamicallyLoadedModules )
{
Modules . UnionWith ( DynamicallyLoadedModules ) ;
}
return Modules ;
2018-02-27 17:30:35 -05:00
}
/// <summary>
/// Returns a list of this module's frameworks.
/// </summary>
/// <returns>A List containing the frameworks this module requires.</returns>
public List < string > GetPublicFrameworks ( )
{
return new List < string > ( PublicFrameworks ) ;
}
2017-03-30 10:07:15 -04:00
2017-01-30 16:52:08 -05:00
/// <summary>
/// Returns a list of this module's immediate dependencies.
/// </summary>
/// <returns>An enumerable containing the dependencies of the module.</returns>
public IEnumerable < UEBuildModule > GetDirectDependencyModules ( )
{
2018-01-20 11:19:29 -05:00
return PublicDependencyModules . Concat ( PrivateDependencyModules ) . Concat ( DynamicallyLoadedModules ) ;
}
/// <summary>
/// Converts an optional string list parameter to a well-defined hash set.
/// </summary>
2018-04-26 14:11:04 -04:00
protected HashSet < DirectoryReference > CreateDirectoryHashSet ( IEnumerable < string > InEnumerableStrings )
2018-01-20 11:19:29 -05:00
{
HashSet < DirectoryReference > Directories = new HashSet < DirectoryReference > ( ) ;
if ( InEnumerableStrings ! = null )
{
foreach ( string InputString in InEnumerableStrings )
{
2018-08-22 12:31:56 -04:00
DirectoryReference Dir = new DirectoryReference ( ExpandPathVariables ( InputString , null , null ) ) ;
2019-05-29 20:48:56 -04:00
if ( DirectoryLookupCache . DirectoryExists ( Dir ) )
2018-04-26 14:11:04 -04:00
{
Directories . Add ( Dir ) ;
}
else
{
Log . WriteLineOnce ( LogEventType . Warning , LogFormatOptions . NoSeverityPrefix , "{0}: warning: Referenced directory '{1}' does not exist." , RulesFile , Dir ) ;
}
2018-01-20 11:19:29 -05:00
}
}
return Directories ;
2017-01-30 16:52:08 -05:00
}
/// <summary>
/// Converts an optional string list parameter to a well-defined hash set.
/// </summary>
2019-01-15 18:47:22 -05:00
protected HashSet < string > HashSetFromOptionalEnumerableStringParameter ( IEnumerable < string > InEnumerableStrings )
2017-01-30 16:52:08 -05:00
{
2019-01-15 18:47:22 -05:00
return InEnumerableStrings = = null ? new HashSet < string > ( ) : new HashSet < string > ( InEnumerableStrings . Select ( x = > ExpandPathVariables ( x , null , null ) ) ) ;
2014-03-14 14:13:41 -04:00
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Determines whether this module has a circular dependency on the given module
/// </summary>
2015-08-28 15:47:20 -04:00
public bool HasCircularDependencyOn ( string ModuleName )
{
return Rules . CircularlyReferencedDependentModules . Contains ( ModuleName ) ;
}
2017-01-30 16:52:08 -05:00
/// <summary>
/// Enumerates additional build products which may be produced by this module. Some platforms (eg. Mac, Linux) can link directly against .so/.dylibs, but they
/// are also copied to the output folder by the toolchain.
/// </summary>
/// <param name="Libraries">List to which libraries required by this module are added</param>
/// <param name="BundleResources">List of bundle resources required by this module</param>
public void GatherAdditionalResources ( List < string > Libraries , List < UEBuildBundleResource > BundleResources )
{
Libraries . AddRange ( PublicAdditionalLibraries ) ;
BundleResources . AddRange ( PublicAdditionalBundleResources ) ;
}
/// <summary>
/// Determines the distribution level of a module based on its directory and includes.
/// </summary>
/// <param name="ProjectDir">The project directory, if available</param>
/// <returns>Map of the restricted folder types to the first found instance</returns>
public Dictionary < RestrictedFolder , DirectoryReference > FindRestrictedFolderReferences ( DirectoryReference ProjectDir )
{
Dictionary < RestrictedFolder , DirectoryReference > References = new Dictionary < RestrictedFolder , DirectoryReference > ( ) ;
if ( ! Rules . bOutputPubliclyDistributable )
{
// Find all the directories that this module references
HashSet < DirectoryReference > ReferencedDirs = new HashSet < DirectoryReference > ( ) ;
GetReferencedDirectories ( ReferencedDirs ) ;
// Remove all the whitelisted folders
ReferencedDirs . ExceptWith ( WhitelistRestrictedFolders ) ;
ReferencedDirs . ExceptWith ( PublicDependencyModules . SelectMany ( x = > x . WhitelistRestrictedFolders ) ) ;
ReferencedDirs . ExceptWith ( PrivateDependencyModules . SelectMany ( x = > x . WhitelistRestrictedFolders ) ) ;
// Add flags for each of them
foreach ( DirectoryReference ReferencedDir in ReferencedDirs )
{
// Find the base directory containing this reference
DirectoryReference BaseDir ;
2019-05-29 20:48:56 -04:00
// @todo platplug does this need to check platform extension engine directories? what are ReferencedDir's here?
2017-01-30 16:52:08 -05:00
if ( ReferencedDir . IsUnderDirectory ( UnrealBuildTool . EngineDirectory ) )
{
BaseDir = UnrealBuildTool . EngineDirectory ;
}
else if ( ProjectDir ! = null & & ReferencedDir . IsUnderDirectory ( ProjectDir ) )
{
BaseDir = ProjectDir ;
}
else
{
continue ;
}
// Add references to each of the restricted folders
List < RestrictedFolder > Folders = RestrictedFolders . FindRestrictedFolders ( BaseDir , ReferencedDir ) ;
foreach ( RestrictedFolder Folder in Folders )
{
if ( ! References . ContainsKey ( Folder ) )
{
References . Add ( Folder , ReferencedDir ) ;
}
}
}
}
return References ;
}
/// <summary>
/// Finds all the directories that this folder references when building
/// </summary>
/// <param name="Directories">Set of directories to add to</param>
protected virtual void GetReferencedDirectories ( HashSet < DirectoryReference > Directories )
{
Directories . Add ( ModuleDirectory ) ;
2018-01-20 11:19:29 -05:00
foreach ( DirectoryReference PublicIncludePath in PublicIncludePaths )
2017-01-30 16:52:08 -05:00
{
2018-01-20 11:19:29 -05:00
Directories . Add ( PublicIncludePath ) ;
2017-01-30 16:52:08 -05:00
}
2018-01-20 11:19:29 -05:00
foreach ( DirectoryReference PrivateIncludePath in PrivateIncludePaths )
2017-01-30 16:52:08 -05:00
{
2018-01-20 11:19:29 -05:00
Directories . Add ( PrivateIncludePath ) ;
2017-01-30 16:52:08 -05:00
}
2018-01-20 11:19:29 -05:00
foreach ( DirectoryReference PublicSystemIncludePath in PublicSystemIncludePaths )
2017-01-30 16:52:08 -05:00
{
2018-01-20 11:19:29 -05:00
Directories . Add ( PublicSystemIncludePath ) ;
2017-01-30 16:52:08 -05:00
}
2018-01-20 11:19:29 -05:00
foreach ( DirectoryReference PublicLibraryPath in PublicLibraryPaths )
2017-01-30 16:52:08 -05:00
{
2018-01-20 11:19:29 -05:00
Directories . Add ( PublicLibraryPath ) ;
2017-01-30 16:52:08 -05:00
}
}
2016-03-17 11:10:14 -04:00
/// <summary>
2018-01-20 11:19:29 -05:00
/// Find all the modules which affect the private compile environment.
2016-03-17 11:10:14 -04:00
/// </summary>
2017-01-30 16:52:08 -05:00
/// <param name="ModuleToIncludePathsOnlyFlag"></param>
2018-01-20 11:19:29 -05:00
protected void FindModulesInPrivateCompileEnvironment ( Dictionary < UEBuildModule , bool > ModuleToIncludePathsOnlyFlag )
{
// Add in all the modules that are only in the private compile environment
foreach ( UEBuildModule PrivateDependencyModule in PrivateDependencyModules )
{
PrivateDependencyModule . FindModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
}
foreach ( UEBuildModule PrivateIncludePathModule in PrivateIncludePathModules )
{
PrivateIncludePathModule . FindIncludePathModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
}
// Add the modules in the public compile environment
FindModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
}
/// <summary>
/// Find all the modules which affect the public compile environment.
/// </summary>
/// <param name="ModuleToIncludePathsOnlyFlag"></param>
protected void FindModulesInPublicCompileEnvironment ( Dictionary < UEBuildModule , bool > ModuleToIncludePathsOnlyFlag )
2016-03-17 11:10:14 -04:00
{
//
bool bModuleIncludePathsOnly ;
2018-01-20 11:19:29 -05:00
if ( ModuleToIncludePathsOnlyFlag . TryGetValue ( this , out bModuleIncludePathsOnly ) & & ! bModuleIncludePathsOnly )
2016-03-17 11:10:14 -04:00
{
return ;
}
ModuleToIncludePathsOnlyFlag [ this ] = false ;
foreach ( UEBuildModule DependencyModule in PublicDependencyModules )
{
2018-01-20 11:19:29 -05:00
DependencyModule . FindModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
2016-03-17 11:10:14 -04:00
}
// Now add an include paths from modules with header files that we need access to, but won't necessarily be importing
foreach ( UEBuildModule IncludePathModule in PublicIncludePathModules )
{
2018-01-20 11:19:29 -05:00
IncludePathModule . FindIncludePathModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
2016-03-17 11:10:14 -04:00
}
}
/// <summary>
/// Find all the modules which affect the public compile environment. Searches through
/// </summary>
2017-01-30 16:52:08 -05:00
/// <param name="ModuleToIncludePathsOnlyFlag"></param>
2018-01-20 11:19:29 -05:00
protected void FindIncludePathModulesInPublicCompileEnvironment ( Dictionary < UEBuildModule , bool > ModuleToIncludePathsOnlyFlag )
2016-03-17 11:10:14 -04:00
{
if ( ! ModuleToIncludePathsOnlyFlag . ContainsKey ( this ) )
{
// Add this module to the list
ModuleToIncludePathsOnlyFlag . Add ( this , true ) ;
// Include any of its public include path modules in the compile environment too
foreach ( UEBuildModule IncludePathModule in PublicIncludePathModules )
{
2018-01-20 11:19:29 -05:00
IncludePathModule . FindIncludePathModulesInPublicCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
2016-03-17 11:10:14 -04:00
}
}
}
2018-01-21 18:22:09 -05:00
private void AddIncludePaths ( HashSet < DirectoryReference > IncludePaths , HashSet < DirectoryReference > IncludePathsToAdd )
{
// Need to check whether directories exist to avoid bloating compiler command line with generated code directories
foreach ( DirectoryReference IncludePathToAdd in IncludePathsToAdd )
{
2018-04-26 14:11:04 -04:00
IncludePaths . Add ( IncludePathToAdd ) ;
2018-01-21 18:22:09 -05:00
}
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Sets up the environment for compiling any module that includes the public interface of this module.
/// </summary>
2018-04-26 14:11:04 -04:00
public virtual void AddModuleToCompileEnvironment (
2014-03-14 14:13:41 -04:00
UEBuildBinary SourceBinary ,
2018-01-20 11:19:29 -05:00
HashSet < DirectoryReference > IncludePaths ,
HashSet < DirectoryReference > SystemIncludePaths ,
2015-03-21 11:34:08 -04:00
List < string > Definitions ,
2018-01-20 11:19:29 -05:00
List < UEBuildFramework > AdditionalFrameworks ,
bool bLegacyPublicIncludePaths
2014-03-14 14:13:41 -04:00
)
{
2018-01-20 11:19:29 -05:00
// Add the module's parent directory to the include path, so we can root #includes from generated source files to it
IncludePaths . Add ( ModuleDirectory . ParentDirectory ) ;
2016-03-17 11:10:14 -04:00
// Add this module's public include paths and definitions.
2018-01-21 18:22:09 -05:00
AddIncludePaths ( IncludePaths , PublicIncludePaths ) ;
2018-01-20 11:19:29 -05:00
if ( bLegacyPublicIncludePaths )
{
2018-01-21 18:22:09 -05:00
AddIncludePaths ( IncludePaths , LegacyPublicIncludePaths ) ;
2018-01-20 11:19:29 -05:00
}
SystemIncludePaths . UnionWith ( PublicSystemIncludePaths ) ;
2016-03-17 11:10:14 -04:00
Definitions . AddRange ( PublicDefinitions ) ;
2015-09-24 12:37:21 -04:00
2018-03-29 13:32:35 -04:00
// Add the import or export declaration for the module
2018-01-20 11:19:29 -05:00
if ( Rules . Type = = ModuleRules . ModuleType . CPlusPlus )
2016-11-23 15:34:07 -05:00
{
2018-01-20 11:19:29 -05:00
if ( Rules . Target . LinkType = = TargetLinkType . Monolithic )
2016-11-23 15:34:07 -05:00
{
2019-03-27 15:03:08 -04:00
if ( Rules . Target . bShouldCompileAsDLL & & ( Rules . Target . bHasExports | | Rules . ModuleSymbolVisibility = = ModuleRules . SymbolVisibility . VisibileForDll ) )
2018-03-29 13:32:35 -04:00
{
2019-02-06 14:44:31 -05:00
Definitions . Add ( ModuleVTableDefine + "=DLLEXPORT_VTABLE" ) ;
2018-03-29 13:32:35 -04:00
Definitions . Add ( ModuleApiDefine + "=DLLEXPORT" ) ;
}
else
{
2019-02-06 14:44:31 -05:00
Definitions . Add ( ModuleVTableDefine + "=" ) ;
2018-03-29 13:32:35 -04:00
Definitions . Add ( ModuleApiDefine + "=" ) ;
}
2016-03-17 11:10:14 -04:00
}
2018-01-20 11:19:29 -05:00
else if ( Binary = = null | | SourceBinary ! = Binary )
2016-03-17 11:10:14 -04:00
{
2019-02-06 14:44:31 -05:00
Definitions . Add ( ModuleVTableDefine + "=DLLIMPORT_VTABLE" ) ;
2018-01-20 11:19:29 -05:00
Definitions . Add ( ModuleApiDefine + "=DLLIMPORT" ) ;
2016-03-17 11:10:14 -04:00
}
2018-01-20 11:19:29 -05:00
else if ( ! Binary . bAllowExports )
2016-03-17 11:10:14 -04:00
{
2019-02-06 14:44:31 -05:00
Definitions . Add ( ModuleVTableDefine + "=" ) ;
2018-01-20 11:19:29 -05:00
Definitions . Add ( ModuleApiDefine + "=" ) ;
2015-08-10 13:10:18 -04:00
}
else
2014-03-14 14:13:41 -04:00
{
2019-02-06 14:44:31 -05:00
Definitions . Add ( ModuleVTableDefine + "=DLLEXPORT_VTABLE" ) ;
2018-01-20 11:19:29 -05:00
Definitions . Add ( ModuleApiDefine + "=DLLEXPORT" ) ;
2014-03-14 14:13:41 -04:00
}
2016-03-17 11:10:14 -04:00
}
2014-03-14 14:13:41 -04:00
2016-03-17 11:10:14 -04:00
// Add the additional frameworks so that the compiler can know about their #include paths
AdditionalFrameworks . AddRange ( PublicAdditionalFrameworks ) ;
2014-08-22 08:23:53 -04:00
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Sets up the environment for compiling this module.
/// </summary>
2014-03-14 14:13:41 -04:00
protected virtual void SetupPrivateCompileEnvironment (
2018-01-20 11:19:29 -05:00
HashSet < DirectoryReference > IncludePaths ,
HashSet < DirectoryReference > SystemIncludePaths ,
2015-03-21 11:34:08 -04:00
List < string > Definitions ,
2018-01-20 11:19:29 -05:00
List < UEBuildFramework > AdditionalFrameworks ,
bool bWithLegacyPublicIncludePaths
2014-03-14 14:13:41 -04:00
)
{
2018-03-27 14:27:07 -04:00
if ( ! Rules . bTreatAsEngineModule )
2014-10-30 17:10:56 -04:00
{
Definitions . Add ( "DEPRECATED_FORGAME=DEPRECATED" ) ;
2018-11-16 11:15:08 -05:00
Definitions . Add ( "UE_DEPRECATED_FORGAME=UE_DEPRECATED" ) ;
2014-10-30 17:10:56 -04:00
}
2014-03-14 14:13:41 -04:00
// Add this module's private include paths and definitions.
2018-01-20 11:19:29 -05:00
IncludePaths . UnionWith ( PrivateIncludePaths ) ;
2014-03-14 14:13:41 -04:00
2016-03-17 11:10:14 -04:00
// Find all the modules that are part of the public compile environment for this module.
Dictionary < UEBuildModule , bool > ModuleToIncludePathsOnlyFlag = new Dictionary < UEBuildModule , bool > ( ) ;
2018-01-20 11:19:29 -05:00
FindModulesInPrivateCompileEnvironment ( ModuleToIncludePathsOnlyFlag ) ;
2016-03-17 11:10:14 -04:00
// Now set up the compile environment for the modules in the original order that we encountered them
2018-01-20 11:19:29 -05:00
foreach ( UEBuildModule Module in ModuleToIncludePathsOnlyFlag . Keys )
2016-03-17 11:10:14 -04:00
{
2018-01-20 11:19:29 -05:00
Module . AddModuleToCompileEnvironment ( Binary , IncludePaths , SystemIncludePaths , Definitions , AdditionalFrameworks , bWithLegacyPublicIncludePaths ) ;
2014-03-14 14:13:41 -04:00
}
}
2018-08-14 18:32:34 -04:00
/// <summary>
/// Expand path variables within the context of this module
/// </summary>
/// <param name="Path">Path to expand variables within</param>
2018-08-22 12:31:56 -04:00
/// <param name="BinaryOutputDir">Directory containing the binary that links this module. May be mull.</param>
/// <param name="TargetOutputDir">Directory containing the output executable. May be null.</param>
2018-08-14 18:32:34 -04:00
/// <returns>The path with variables expanded</returns>
2018-08-22 12:31:56 -04:00
public string ExpandPathVariables ( string Path , DirectoryReference BinaryOutputDir , DirectoryReference TargetOutputDir )
2018-08-14 18:32:34 -04:00
{
if ( Path . StartsWith ( "$(" , StringComparison . Ordinal ) )
{
int StartIdx = 2 ;
for ( int EndIdx = StartIdx ; EndIdx < Path . Length ; EndIdx + + )
{
if ( Path [ EndIdx ] = = ')' )
{
if ( MatchVariableName ( Path , StartIdx , EndIdx , "EngineDir" ) )
{
Path = UnrealBuildTool . EngineDirectory + Path . Substring ( EndIdx + 1 ) ;
}
else if ( MatchVariableName ( Path , StartIdx , EndIdx , "ProjectDir" ) )
{
if ( Rules . Target . ProjectFile = = null )
{
Path = UnrealBuildTool . EngineDirectory + Path . Substring ( EndIdx + 1 ) ;
}
else
{
Path = Rules . Target . ProjectFile . Directory + Path . Substring ( EndIdx + 1 ) ;
}
}
else if ( MatchVariableName ( Path , StartIdx , EndIdx , "ModuleDir" ) )
{
Path = Rules . ModuleDirectory + Path . Substring ( EndIdx + 1 ) ;
}
else if ( MatchVariableName ( Path , StartIdx , EndIdx , "PluginDir" ) )
{
Path = Rules . PluginDirectory + Path . Substring ( EndIdx + 1 ) ;
}
2018-08-22 12:31:56 -04:00
else if ( BinaryOutputDir ! = null & & MatchVariableName ( Path , StartIdx , EndIdx , "BinaryOutputDir" ) )
2018-08-14 18:32:34 -04:00
{
2018-08-22 12:31:56 -04:00
Path = BinaryOutputDir . FullName + Path . Substring ( EndIdx + 1 ) ;
}
else if ( TargetOutputDir ! = null & & MatchVariableName ( Path , StartIdx , EndIdx , "TargetOutputDir" ) )
{
Path = TargetOutputDir . FullName + Path . Substring ( EndIdx + 1 ) ;
2018-08-14 18:32:34 -04:00
}
else
{
string Name = Path . Substring ( StartIdx , EndIdx - StartIdx ) ;
string Value = Environment . GetEnvironmentVariable ( Name ) ;
if ( String . IsNullOrEmpty ( Value ) )
{
throw new BuildException ( "Environment variable '{0}' is not defined (referenced by {1})" , Name , Rules . File ) ;
}
Path = Value + Path . Substring ( EndIdx + 1 ) ;
}
break ;
}
}
}
return Path ;
}
/// <summary>
/// Match a variable name within a path
/// </summary>
/// <param name="Path">The path variable</param>
/// <param name="StartIdx">Start index of the substring to match</param>
/// <param name="EndIdx">End index of the substring to match</param>
/// <param name="Name">Variable name to compare against</param>
/// <returns>True if the variable name matches</returns>
private bool MatchVariableName ( string Path , int StartIdx , int EndIdx , string Name )
{
return Name . Length = = EndIdx - StartIdx & & String . Compare ( Path , StartIdx , Name , 0 , EndIdx - StartIdx ) = = 0 ;
}
/// <summary>
/// Expand path variables within the context of this module
/// </summary>
/// <param name="Paths">Path to expand variables within</param>
2018-08-22 12:31:56 -04:00
/// <param name="BinaryDir">Directory containing the binary that links this module. May be mull.</param>
/// <param name="ExeDir">Directory containing the output executable. May be null.</param>
2018-08-14 18:32:34 -04:00
/// <returns>The path with variables expanded</returns>
2018-08-22 12:31:56 -04:00
private IEnumerable < string > ExpandPathVariables ( IEnumerable < string > Paths , DirectoryReference BinaryDir , DirectoryReference ExeDir )
2018-08-14 18:32:34 -04:00
{
foreach ( string Path in Paths )
{
2018-08-22 12:31:56 -04:00
yield return ExpandPathVariables ( Path , BinaryDir , ExeDir ) ;
2018-08-14 18:32:34 -04:00
}
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Sets up the environment for linking any module that includes the public interface of this module.
/// </summary>
2014-03-14 14:13:41 -04:00
protected virtual void SetupPublicLinkEnvironment (
UEBuildBinary SourceBinary ,
2018-01-20 11:19:29 -05:00
List < DirectoryReference > LibraryPaths ,
2015-03-21 11:34:08 -04:00
List < string > AdditionalLibraries ,
2018-08-14 18:32:34 -04:00
List < string > RuntimeLibraryPaths ,
2015-03-21 11:34:08 -04:00
List < string > Frameworks ,
List < string > WeakFrameworks ,
List < UEBuildFramework > AdditionalFrameworks ,
List < UEBuildBundleResource > AdditionalBundleResources ,
List < string > DelayLoadDLLs ,
List < UEBuildBinary > BinaryDependencies ,
2018-08-22 12:31:56 -04:00
HashSet < UEBuildModule > VisitedModules ,
DirectoryReference ExeDir
2014-03-14 14:13:41 -04:00
)
{
// There may be circular dependencies in compile dependencies, so we need to avoid reentrance.
2015-09-24 12:37:21 -04:00
if ( VisitedModules . Add ( this ) )
2014-03-14 14:13:41 -04:00
{
2016-01-07 11:21:22 -05:00
// Add this module's binary to the binary dependencies.
if ( Binary ! = null
2014-03-14 14:13:41 -04:00
& & Binary ! = SourceBinary
& & ! BinaryDependencies . Contains ( Binary ) )
2016-01-07 11:21:22 -05:00
{
BinaryDependencies . Add ( Binary ) ;
}
2014-03-14 14:13:41 -04:00
2016-01-07 11:21:22 -05:00
// If this module belongs to a static library that we are not currently building, recursively add the link environment settings for all of its dependencies too.
// Keep doing this until we reach a module that is not part of a static library (or external module, since they have no associated binary).
// Static libraries do not contain the symbols for their dependencies, so we need to recursively gather them to be linked into other binary types.
2018-01-20 11:19:29 -05:00
bool bIsBuildingAStaticLibrary = ( SourceBinary ! = null & & SourceBinary . Type = = UEBuildBinaryType . StaticLibrary ) ;
bool bIsModuleBinaryAStaticLibrary = ( Binary ! = null & & Binary . Type = = UEBuildBinaryType . StaticLibrary ) ;
2016-01-07 11:21:22 -05:00
if ( ! bIsBuildingAStaticLibrary & & bIsModuleBinaryAStaticLibrary )
{
// Gather all dependencies and recursively call SetupPublicLinkEnvironmnet
List < UEBuildModule > AllDependencyModules = new List < UEBuildModule > ( ) ;
AllDependencyModules . AddRange ( PrivateDependencyModules ) ;
AllDependencyModules . AddRange ( PublicDependencyModules ) ;
2014-03-14 14:13:41 -04:00
2016-01-07 11:21:22 -05:00
foreach ( UEBuildModule DependencyModule in AllDependencyModules )
{
2017-01-30 16:52:08 -05:00
bool bIsExternalModule = ( DependencyModule as UEBuildModuleExternal ! = null ) ;
2018-01-20 11:19:29 -05:00
bool bIsInStaticLibrary = ( DependencyModule . Binary ! = null & & DependencyModule . Binary . Type = = UEBuildBinaryType . StaticLibrary ) ;
2016-01-07 11:21:22 -05:00
if ( bIsExternalModule | | bIsInStaticLibrary )
2014-03-14 14:13:41 -04:00
{
2018-08-14 18:32:34 -04:00
DependencyModule . SetupPublicLinkEnvironment ( SourceBinary , LibraryPaths , AdditionalLibraries , RuntimeLibraryPaths , Frameworks , WeakFrameworks ,
2019-01-15 18:47:22 -05:00
AdditionalFrameworks , AdditionalBundleResources , DelayLoadDLLs , BinaryDependencies , VisitedModules , ExeDir ) ;
2014-03-14 14:13:41 -04:00
}
}
}
2016-01-07 11:21:22 -05:00
// Add this module's public include library paths and additional libraries.
LibraryPaths . AddRange ( PublicLibraryPaths ) ;
AdditionalLibraries . AddRange ( PublicAdditionalLibraries ) ;
2018-08-22 12:31:56 -04:00
RuntimeLibraryPaths . AddRange ( ExpandPathVariables ( Rules . PublicRuntimeLibraryPaths , SourceBinary . OutputDir , ExeDir ) ) ;
2016-01-07 11:21:22 -05:00
Frameworks . AddRange ( PublicFrameworks ) ;
WeakFrameworks . AddRange ( PublicWeakFrameworks ) ;
AdditionalBundleResources . AddRange ( PublicAdditionalBundleResources ) ;
AdditionalFrameworks . AddRange ( PublicAdditionalFrameworks ) ;
DelayLoadDLLs . AddRange ( PublicDelayLoadDLLs ) ;
2014-03-14 14:13:41 -04:00
}
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Sets up the environment for linking this module.
/// </summary>
2014-03-14 14:13:41 -04:00
public virtual void SetupPrivateLinkEnvironment (
2015-05-22 08:57:34 -04:00
UEBuildBinary SourceBinary ,
2015-03-21 11:34:08 -04:00
LinkEnvironment LinkEnvironment ,
List < UEBuildBinary > BinaryDependencies ,
2018-08-22 12:31:56 -04:00
HashSet < UEBuildModule > VisitedModules ,
DirectoryReference ExeDir
2014-03-14 14:13:41 -04:00
)
{
2018-08-14 18:32:34 -04:00
// Add the private rpaths
2018-08-22 12:31:56 -04:00
LinkEnvironment . RuntimeLibraryPaths . AddRange ( ExpandPathVariables ( Rules . PrivateRuntimeLibraryPaths , SourceBinary . OutputDir , ExeDir ) ) ;
2018-08-14 18:32:34 -04:00
2014-03-14 14:13:41 -04:00
// Allow the module's public dependencies to add library paths and additional libraries to the link environment.
2018-08-14 18:32:34 -04:00
SetupPublicLinkEnvironment ( SourceBinary , LinkEnvironment . LibraryPaths , LinkEnvironment . AdditionalLibraries , LinkEnvironment . RuntimeLibraryPaths , LinkEnvironment . Frameworks , LinkEnvironment . WeakFrameworks ,
2019-01-15 18:47:22 -05:00
LinkEnvironment . AdditionalFrameworks , LinkEnvironment . AdditionalBundleResources , LinkEnvironment . DelayLoadDLLs , BinaryDependencies , VisitedModules , ExeDir ) ;
2014-03-14 14:13:41 -04:00
// Also allow the module's public and private dependencies to modify the link environment.
2015-08-28 15:47:20 -04:00
List < UEBuildModule > AllDependencyModules = new List < UEBuildModule > ( ) ;
AllDependencyModules . AddRange ( PrivateDependencyModules ) ;
AllDependencyModules . AddRange ( PublicDependencyModules ) ;
2014-03-14 14:13:41 -04:00
2015-08-28 15:47:20 -04:00
foreach ( UEBuildModule DependencyModule in AllDependencyModules )
2014-03-14 14:13:41 -04:00
{
2018-08-14 18:32:34 -04:00
DependencyModule . SetupPublicLinkEnvironment ( SourceBinary , LinkEnvironment . LibraryPaths , LinkEnvironment . AdditionalLibraries , LinkEnvironment . RuntimeLibraryPaths , LinkEnvironment . Frameworks , LinkEnvironment . WeakFrameworks ,
2019-01-15 18:47:22 -05:00
LinkEnvironment . AdditionalFrameworks , LinkEnvironment . AdditionalBundleResources , LinkEnvironment . DelayLoadDLLs , BinaryDependencies , VisitedModules , ExeDir ) ;
2014-03-14 14:13:41 -04:00
}
2019-01-15 18:47:22 -05:00
// Add all the additional properties
LinkEnvironment . AdditionalProperties . AddRange ( Rules . AdditionalPropertiesForReceipt . Inner ) ;
2019-02-28 08:52:50 -05:00
// this is a link-time property that needs to be accumulated (if any modules contributing to this module is ignoring, all are ignoring)
LinkEnvironment . bIgnoreUnresolvedSymbols | = Rules . bIgnoreUnresolvedSymbols ;
2014-03-14 14:13:41 -04:00
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Compiles the module, and returns a list of files output by the compiler.
/// </summary>
2019-01-15 18:47:22 -05:00
public abstract List < FileItem > Compile ( ReadOnlyTargetRules Target , UEToolChain ToolChain , CppCompileEnvironment CompileEnvironment , ISourceFileWorkingSet WorkingSet , TargetMakefile Makefile ) ;
2015-09-24 12:37:21 -04:00
2014-03-14 14:13:41 -04:00
// Object interface.
public override string ToString ( )
{
return Name ;
}
2016-01-07 11:21:22 -05:00
/// <summary>
/// Finds the modules referenced by this module which have not yet been bound to a binary
/// </summary>
/// <returns>List of unbound modules</returns>
public List < UEBuildModule > GetUnboundReferences ( )
{
List < UEBuildModule > Modules = new List < UEBuildModule > ( ) ;
Modules . AddRange ( PrivateDependencyModules . Where ( x = > x . Binary = = null ) ) ;
Modules . AddRange ( PublicDependencyModules . Where ( x = > x . Binary = = null ) ) ;
return Modules ;
}
2015-09-24 13:47:13 -04:00
/// <summary>
/// Gets all of the modules referenced by this module
/// </summary>
/// <param name="ReferencedModules">Hash of all referenced modules with their addition index.</param>
2016-03-08 09:00:48 -05:00
/// <param name="IgnoreReferencedModules">Hashset used to ignore modules which are already added to the list</param>
2015-09-24 13:47:13 -04:00
/// <param name="bIncludeDynamicallyLoaded">True if dynamically loaded modules (and all of their dependent modules) should be included.</param>
/// <param name="bForceCircular">True if circular dependencies should be processed</param>
/// <param name="bOnlyDirectDependencies">True to return only this module's direct dependencies</param>
2016-03-08 09:00:48 -05:00
public virtual void GetAllDependencyModules ( List < UEBuildModule > ReferencedModules , HashSet < UEBuildModule > IgnoreReferencedModules , bool bIncludeDynamicallyLoaded , bool bForceCircular , bool bOnlyDirectDependencies )
2014-03-14 14:13:41 -04:00
{
}
2017-07-21 12:42:36 -04:00
public delegate UEBuildModule CreateModuleDelegate ( string Name , string ReferenceChain ) ;
2017-01-30 16:52:08 -05:00
2015-09-24 13:47:13 -04:00
/// <summary>
/// Creates all the modules required for this target
/// </summary>
2017-07-21 12:42:36 -04:00
/// <param name="CreateModule">Delegate to create a module with a given name</param>
/// <param name="ReferenceChain">Chain of references before reaching this module</param>
public void RecursivelyCreateModules ( CreateModuleDelegate CreateModule , string ReferenceChain )
2014-03-14 14:13:41 -04:00
{
2017-07-21 12:42:36 -04:00
// Get the reference chain for anything referenced by this module
string NextReferenceChain = String . Format ( "{0} -> {1}" , ReferenceChain , ( RulesFile = = null ) ? Name : RulesFile . GetFileName ( ) ) ;
2015-08-28 15:47:20 -04:00
2017-07-21 12:42:36 -04:00
// Recursively create all the public include path modules. These modules may not be added to the target (and we don't process their referenced
// dependencies), but they need to be created to set up their include paths.
RecursivelyCreateIncludePathModulesByName ( Rules . PublicIncludePathModuleNames , ref PublicIncludePathModules , CreateModule , NextReferenceChain ) ;
// Create all the referenced modules. This path can be recursive, so we check against PrivateIncludePathModules to ensure we don't recurse through the
// same module twice (it produces better errors if something fails).
if ( PrivateIncludePathModules = = null )
{
// Create the private include path modules
RecursivelyCreateIncludePathModulesByName ( Rules . PrivateIncludePathModuleNames , ref PrivateIncludePathModules , CreateModule , NextReferenceChain ) ;
// Create all the dependency modules
RecursivelyCreateModulesByName ( Rules . PublicDependencyModuleNames , ref PublicDependencyModules , CreateModule , NextReferenceChain ) ;
RecursivelyCreateModulesByName ( Rules . PrivateDependencyModuleNames , ref PrivateDependencyModules , CreateModule , NextReferenceChain ) ;
RecursivelyCreateModulesByName ( Rules . DynamicallyLoadedModuleNames , ref DynamicallyLoadedModules , CreateModule , NextReferenceChain ) ;
}
2015-08-28 15:47:20 -04:00
}
2017-07-21 12:42:36 -04:00
private static void RecursivelyCreateModulesByName ( List < string > ModuleNames , ref List < UEBuildModule > Modules , CreateModuleDelegate CreateModule , string ReferenceChain )
2015-08-28 15:47:20 -04:00
{
// Check whether the module list is already set. We set this immediately (via the ref) to avoid infinite recursion.
2015-09-24 12:37:21 -04:00
if ( Modules = = null )
2015-08-28 15:47:20 -04:00
{
Modules = new List < UEBuildModule > ( ) ;
2015-09-24 12:37:21 -04:00
foreach ( string ModuleName in ModuleNames )
2015-08-28 15:47:20 -04:00
{
2017-07-21 12:42:36 -04:00
UEBuildModule Module = CreateModule ( ModuleName , ReferenceChain ) ;
2015-09-24 12:37:21 -04:00
if ( ! Modules . Contains ( Module ) )
2015-09-08 07:59:23 -04:00
{
2017-07-21 12:42:36 -04:00
Module . RecursivelyCreateModules ( CreateModule , ReferenceChain ) ;
2015-09-08 07:59:23 -04:00
Modules . Add ( Module ) ;
}
2015-08-28 15:47:20 -04:00
}
}
}
2017-07-21 12:42:36 -04:00
private static void RecursivelyCreateIncludePathModulesByName ( List < string > ModuleNames , ref List < UEBuildModule > Modules , CreateModuleDelegate CreateModule , string ReferenceChain )
2015-08-28 15:47:20 -04:00
{
// Check whether the module list is already set. We set this immediately (via the ref) to avoid infinite recursion.
2015-09-24 12:37:21 -04:00
if ( Modules = = null )
2015-08-28 15:47:20 -04:00
{
Modules = new List < UEBuildModule > ( ) ;
2015-09-24 12:37:21 -04:00
foreach ( string ModuleName in ModuleNames )
2015-08-28 15:47:20 -04:00
{
2017-07-21 12:42:36 -04:00
UEBuildModule Module = CreateModule ( ModuleName , ReferenceChain ) ;
RecursivelyCreateIncludePathModulesByName ( Module . Rules . PublicIncludePathModuleNames , ref Module . PublicIncludePathModules , CreateModule , ReferenceChain ) ;
2015-08-28 15:47:20 -04:00
Modules . Add ( Module ) ;
}
}
2014-03-14 14:13:41 -04:00
}
2016-11-23 15:34:07 -05:00
/// <summary>
/// Write information about this binary to a JSON file
/// </summary>
2019-04-22 18:56:08 -04:00
/// <param name="BinaryOutputDir">The output directory for the binary containing this module</param>
/// <param name="TargetOutputDir">The output directory for the target executable</param>
2016-11-23 15:34:07 -05:00
/// <param name="Writer">Writer for this binary's data</param>
2019-04-22 18:56:08 -04:00
public virtual void ExportJson ( DirectoryReference BinaryOutputDir , DirectoryReference TargetOutputDir , JsonWriter Writer )
2016-11-23 15:34:07 -05:00
{
Writer . WriteValue ( "Name" , Name ) ;
Writer . WriteValue ( "Directory" , ModuleDirectory . FullName ) ;
Writer . WriteValue ( "Rules" , RulesFile . FullName ) ;
Writer . WriteValue ( "PCHUsage" , Rules . PCHUsage . ToString ( ) ) ;
2016-11-23 15:48:37 -05:00
if ( Rules . PrivatePCHHeaderFile ! = null )
2016-11-23 15:34:07 -05:00
{
2016-11-23 15:48:37 -05:00
Writer . WriteValue ( "PrivatePCH" , FileReference . Combine ( ModuleDirectory , Rules . PrivatePCHHeaderFile ) . FullName ) ;
}
if ( Rules . SharedPCHHeaderFile ! = null )
{
Writer . WriteValue ( "SharedPCH" , FileReference . Combine ( ModuleDirectory , Rules . SharedPCHHeaderFile ) . FullName ) ;
2016-11-23 15:34:07 -05:00
}
ExportJsonModuleArray ( Writer , "PublicDependencyModules" , PublicDependencyModules ) ;
ExportJsonModuleArray ( Writer , "PublicIncludePathModules" , PublicIncludePathModules ) ;
ExportJsonModuleArray ( Writer , "PrivateDependencyModules" , PrivateDependencyModules ) ;
ExportJsonModuleArray ( Writer , "PrivateIncludePathModules" , PrivateIncludePathModules ) ;
ExportJsonModuleArray ( Writer , "DynamicallyLoadedModules" , DynamicallyLoadedModules ) ;
2018-01-20 11:19:29 -05:00
ExportJsonStringArray ( Writer , "PublicSystemIncludePaths" , PublicSystemIncludePaths . Select ( x = > x . FullName ) ) ;
ExportJsonStringArray ( Writer , "PublicIncludePaths" , PublicIncludePaths . Select ( x = > x . FullName ) ) ;
ExportJsonStringArray ( Writer , "PrivateIncludePaths" , PrivateIncludePaths . Select ( x = > x . FullName ) ) ;
ExportJsonStringArray ( Writer , "PublicLibraryPaths" , PublicLibraryPaths . Select ( x = > x . FullName ) ) ;
2017-12-12 18:32:45 -05:00
ExportJsonStringArray ( Writer , "PublicAdditionalLibraries" , PublicAdditionalLibraries ) ;
ExportJsonStringArray ( Writer , "PublicFrameworks" , PublicFrameworks ) ;
ExportJsonStringArray ( Writer , "PublicWeakFrameworks" , PublicWeakFrameworks ) ;
ExportJsonStringArray ( Writer , "PublicDelayLoadDLLs" , PublicDelayLoadDLLs ) ;
ExportJsonStringArray ( Writer , "PublicDefinitions" , PublicDefinitions ) ;
2016-11-23 15:34:07 -05:00
Writer . WriteArrayStart ( "CircularlyReferencedModules" ) ;
2016-11-23 15:48:37 -05:00
foreach ( string ModuleName in Rules . CircularlyReferencedDependentModules )
2016-11-23 15:34:07 -05:00
{
2016-11-23 15:48:37 -05:00
Writer . WriteValue ( ModuleName ) ;
2016-11-23 15:34:07 -05:00
}
Writer . WriteArrayEnd ( ) ;
2019-04-22 18:56:08 -04:00
Writer . WriteArrayStart ( "RuntimeDependencies" ) ;
foreach ( ModuleRules . RuntimeDependency RuntimeDependency in Rules . RuntimeDependencies . Inner )
{
Writer . WriteObjectStart ( ) ;
Writer . WriteValue ( "Path" , ExpandPathVariables ( RuntimeDependency . Path , BinaryOutputDir , TargetOutputDir ) ) ;
if ( RuntimeDependency . SourcePath ! = null )
{
Writer . WriteValue ( "SourcePath" , ExpandPathVariables ( RuntimeDependency . SourcePath , BinaryOutputDir , TargetOutputDir ) ) ;
}
Writer . WriteValue ( "Type" , RuntimeDependency . Type . ToString ( ) ) ;
Writer . WriteObjectEnd ( ) ;
}
Writer . WriteArrayEnd ( ) ;
2016-11-23 15:34:07 -05:00
}
/// <summary>
/// Write an array of module names to a JSON writer
/// </summary>
/// <param name="Writer">Writer for the array data</param>
/// <param name="ArrayName">Name of the array property</param>
/// <param name="Modules">Sequence of modules to write. May be null.</param>
void ExportJsonModuleArray ( JsonWriter Writer , string ArrayName , IEnumerable < UEBuildModule > Modules )
{
Writer . WriteArrayStart ( ArrayName ) ;
if ( Modules ! = null )
{
foreach ( UEBuildModule Module in Modules )
{
Writer . WriteValue ( Module . Name ) ;
}
}
Writer . WriteArrayEnd ( ) ;
}
2017-12-12 18:32:45 -05:00
/// <summary>
/// Write an array of strings to a JSON writer
/// </summary>
/// <param name="Writer">Writer for the array data</param>
/// <param name="ArrayName">Name of the array property</param>
/// <param name="Strings">Sequence of strings to write. May be null.</param>
void ExportJsonStringArray ( JsonWriter Writer , string ArrayName , IEnumerable < string > Strings )
{
Writer . WriteArrayStart ( ArrayName ) ;
if ( Strings ! = null )
{
foreach ( string String in Strings )
{
Writer . WriteValue ( String ) ;
}
}
Writer . WriteArrayEnd ( ) ;
}
2014-03-14 14:13:41 -04:00
} ;
}