/// <summary> /// Expand path variables within the context of this module /// </summary> /// <param name="Paths">Path to expand variables within</param> /// <param name="Binary">The source binary containing the module. May be null.</param> /// <returns>The path with variables expanded</returns> private IEnumerable <string> ExpandPathVariables(IEnumerable <string> Paths, UEBuildBinary Binary) { foreach (string Path in Paths) { yield return(ExpandPathVariables(Path, Binary)); } }
public override void AddFilesToManifest(ref FileManifest Manifest, UEBuildBinary Binary) { // the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest) string ApkFile = Path.ChangeExtension(RemoveArchName(Binary.Config.OutputFilePaths[0]), ".apk"); Manifest.AddFileName(ApkFile); }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { if (Binary.Config.Type == UEBuildBinaryType.DynamicLinkLibrary) { Receipt.AddBuildProduct(Path.Combine(Binary.Config.IntermediateDirectory, Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath) + ".lib"), BuildProductType.ImportLibrary); } }
public override void AddFilesToManifest(ref FileManifest Manifest, UEBuildBinary Binary) { // we need to include the generated .mem file. string MemFile = Binary.Config.OutputFilePath + ".mem"; // make sure we don't add mem files more than once. Manifest.AddBinaryNames(MemFile, null); }
/// <summary> /// Sets up the environment for linking this module. /// </summary> public virtual void SetupPrivateLinkEnvironment( UEBuildBinary SourceBinary, LinkEnvironment LinkEnvironment, List <UEBuildBinary> BinaryDependencies, HashSet <UEBuildModule> VisitedModules, DirectoryReference ExeDir ) { // Add the private rpaths LinkEnvironment.RuntimeLibraryPaths.AddRange(ExpandPathVariables(Rules.PrivateRuntimeLibraryPaths, SourceBinary.OutputDir, ExeDir)); // Allow the module's public dependencies to add library paths and additional libraries to the link environment. SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.RuntimeLibraryPaths, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalShadowFiles, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules, ExeDir); // Also allow the module's public and private dependencies to modify the link environment. List <UEBuildModule> AllDependencyModules = new List <UEBuildModule>(); AllDependencyModules.AddRange(PrivateDependencyModules); AllDependencyModules.AddRange(PublicDependencyModules); foreach (UEBuildModule DependencyModule in AllDependencyModules) { DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.RuntimeLibraryPaths, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalShadowFiles, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules, ExeDir); } }
/// <summary> /// Sets up the environment for linking this module. /// </summary> public virtual void SetupPrivateLinkEnvironment( UEBuildBinary SourceBinary, LinkEnvironment LinkEnvironment, List <UEBuildBinary> BinaryDependencies, HashSet <UEBuildModule> VisitedModules, DirectoryReference ExeDir ) { // Add the private rpaths LinkEnvironment.RuntimeLibraryPaths.AddRange(ExpandPathVariables(Rules.PrivateRuntimeLibraryPaths, SourceBinary.OutputDir, ExeDir)); // Allow the module's public dependencies to add library paths and additional libraries to the link environment. SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.RuntimeLibraryPaths, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules, ExeDir); // Also allow the module's public and private dependencies to modify the link environment. List <UEBuildModule> AllDependencyModules = new List <UEBuildModule>(); AllDependencyModules.AddRange(PrivateDependencyModules); AllDependencyModules.AddRange(PublicDependencyModules); foreach (UEBuildModule DependencyModule in AllDependencyModules) { DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.RuntimeLibraryPaths, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules, ExeDir); } // Add all the additional properties LinkEnvironment.AdditionalProperties.AddRange(Rules.AdditionalPropertiesForReceipt.Inner); // 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; }
/// <summary> /// Sets up the environment for compiling any module that includes the public interface of this module. /// </summary> public virtual void AddModuleToCompileEnvironment( UEBuildBinary SourceBinary, HashSet <DirectoryReference> IncludePaths, HashSet <DirectoryReference> SystemIncludePaths, List <string> Definitions, List <UEBuildFramework> AdditionalFrameworks, bool bLegacyPublicIncludePaths ) { // 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); // Add this module's public include paths and definitions. AddIncludePaths(IncludePaths, PublicIncludePaths); if (bLegacyPublicIncludePaths) { AddIncludePaths(IncludePaths, LegacyPublicIncludePaths); } SystemIncludePaths.UnionWith(PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // Add the import or export declaration for the module if (Rules.Type == ModuleRules.ModuleType.CPlusPlus) { if (Rules.Target.LinkType == TargetLinkType.Monolithic) { if (Rules.Target.bShouldCompileAsDLL && Rules.Target.bHasExports) { Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } else { Definitions.Add(ModuleApiDefine + "="); } } else if (Binary == null || SourceBinary != Binary) { Definitions.Add(ModuleApiDefine + "=DLLIMPORT"); } else if (!Binary.bAllowExports) { Definitions.Add(ModuleApiDefine + "="); } else { Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } } // Add the additional frameworks so that the compiler can know about their #include paths AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); // Remember the module so we can refer to it when needed foreach (UEBuildFramework Framework in PublicAdditionalFrameworks) { Framework.OwningModule = this; } }
public override void AddFilesToManifest(BuildManifest Manifest, UEBuildBinary Binary) { // the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest) foreach (string BinaryPath in Binary.Config.OutputFilePaths) { string ApkFile = Path.ChangeExtension(BinaryPath, ".apk"); Manifest.AddBuildProduct(ApkFile); } }
public override void ModifyBuildProducts(UEBuildBinary Binary, Dictionary <FileReference, BuildProductType> BuildProducts) { // we need to include the generated .mem and .symbols file. if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { BuildProducts.Add(Binary.Config.OutputFilePath + ".mem", BuildProductType.RequiredResource); BuildProducts.Add(Binary.Config.OutputFilePath + ".symbols", BuildProductType.RequiredResource); } }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { // we need to include the generated .mem and .symbols file. if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".mem", BuildProductType.RequiredResource); Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".symbols", BuildProductType.RequiredResource); } }
public override void ModifyBuildProducts(ReadOnlyTargetRules Target, UEBuildBinary Binary, List <string> Libraries, List <UEBuildBundleResource> BundleResources, Dictionary <FileReference, BuildProductType> BuildProducts) { // we need to include the generated .mem and .symbols file. if (Binary.Type != UEBuildBinaryType.StaticLibrary) { BuildProducts.Add(Binary.OutputFilePath.ChangeExtension("wasm"), BuildProductType.RequiredResource); BuildProducts.Add(Binary.OutputFilePath + ".symbols", BuildProductType.RequiredResource); } }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { // we need to include the generated .mem and .symbols file. if(Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".mem", BuildProductType.RequiredResource); Receipt.AddBuildProduct(Binary.Config.OutputFilePath + ".symbols", BuildProductType.RequiredResource); } }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { // the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest) if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { foreach (string BinaryPath in Binary.Config.OutputFilePaths) { string ApkFile = Path.ChangeExtension(BinaryPath, ".apk"); Receipt.AddBuildProduct(ApkFile, BuildProductType.Executable); } } }
public override void ModifyBuildProducts(UEBuildBinary Binary, Dictionary<FileReference, BuildProductType> BuildProducts) { // the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest) if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { foreach (FileReference BinaryPath in Binary.Config.OutputFilePaths) { FileReference ApkFile = BinaryPath.ChangeExtension(".apk"); BuildProducts.Add(ApkFile, BuildProductType.Executable); } } }
/// <summary> /// Write information about this binary to a JSON file /// </summary> /// <param name="Binary"></param> /// <param name="Writer">Writer for this binary's data</param> private static void ExportBinary(UEBuildBinary Binary, JsonWriter Writer) { Writer.WriteValue("File", Binary.OutputFilePath.FullName); Writer.WriteValue("Type", Binary.Type.ToString()); Writer.WriteArrayStart("Modules"); foreach (UEBuildModule Module in Binary.Modules) { Writer.WriteValue(Module.Name); } Writer.WriteArrayEnd(); }
public override void AddFilesToManifest(ref FileManifest Manifest, UEBuildBinary Binary) { // ok, this is pretty awful, we want the import libraries that go with the editor, only on the PC if (UnrealBuildTool.BuildingRocket() && Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath).StartsWith("UE4Editor-", StringComparison.InvariantCultureIgnoreCase) && Path.GetExtension(Binary.Config.OutputFilePath).EndsWith("dll", StringComparison.InvariantCultureIgnoreCase) && Binary.Config.Type == UEBuildBinaryType.DynamicLinkLibrary) { // ok, this is pretty awful, we want the import libraries that go with the editor, only on the PC Manifest.AddBinaryNames(Path.Combine(Binary.Config.IntermediateDirectory, Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath) + ".lib"), ""); } }
/// <summary> /// Expand path variables within the context of this module /// </summary> /// <param name="Path">Path to expand variables within</param> /// <param name="Binary">The source binary containing the module. May be null.</param> /// <returns>The path with variables expanded</returns> public string ExpandPathVariables(string Path, UEBuildBinary Binary) { 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); } else if (Binary != null && MatchVariableName(Path, StartIdx, EndIdx, "OutputDir")) { Path = Binary.OutputFilePaths[0].Directory.FullName + Path.Substring(EndIdx + 1); } 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); }
public static void AddAppBundleContentsToManifest(ref FileManifest Manifest, UEBuildBinary Binary) { if (Binary.Target.GlobalLinkEnvironment.Config.bIsBuildingConsoleApplication || Binary.Config.Type != UEBuildBinaryType.Executable) { return; } string ContentsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Binary.Config.OutputFilePath)) + "/"; // We need to know what third party dylibs would be copied to the bundle var Modules = Binary.GetAllDependencyModules(bIncludeDynamicallyLoaded: false, bForceCircular: false); var BinaryLinkEnvironment = new LinkEnvironment(Binary.Target.GlobalLinkEnvironment); var BinaryDependencies = new List<UEBuildBinary>(); var LinkEnvironmentVisitedModules = new Dictionary<UEBuildModule, bool>(); foreach (var Module in Modules) { Module.SetupPrivateLinkEnvironment(ref BinaryLinkEnvironment, ref BinaryDependencies, ref LinkEnvironmentVisitedModules); } foreach (string AdditionalLibrary in BinaryLinkEnvironment.Config.AdditionalLibraries) { string LibName = Path.GetFileName(AdditionalLibrary); if (LibName.StartsWith("lib")) { if (Path.GetExtension(AdditionalLibrary) == ".dylib") { Manifest.AddFileName(ContentsDirectory + "MacOS/" + LibName); } } } // And we also need all the resources Manifest.AddFileName(ContentsDirectory + "Info.plist"); Manifest.AddFileName(ContentsDirectory + "PkgInfo"); Manifest.AddFileName(ContentsDirectory + "Resources/UE4.icns"); Manifest.AddFileName(ContentsDirectory + "Resources/OpenXcodeAtFileAndLine.applescript"); Manifest.AddFileName(ContentsDirectory + "Resources/English.lproj/InfoPlist.strings"); Manifest.AddFileName(ContentsDirectory + "Resources/English.lproj/MainMenu.nib"); Manifest.AddFileName(ContentsDirectory + "Resources/RadioEffectUnit.component/Contents/MacOS/RadioEffectUnit"); Manifest.AddFileName(ContentsDirectory + "Resources/RadioEffectUnit.component/Contents/Resources/English.lproj/Localizable.strings"); Manifest.AddFileName(ContentsDirectory + "Resources/RadioEffectUnit.component/Contents/Resources/RadioEffectUnit.rsrc"); Manifest.AddFileName(ContentsDirectory + "Resources/RadioEffectUnit.component/Contents/Info.plist"); }
/// <summary> /// Process all modules that aren't yet bound, creating binaries for modules that don't yet have one (if needed), /// and updating modules for circular dependencies. /// </summary> /// <param name="ExecutableBinary">The executable binary, which links against all unbound modules when building monolithically</param> /// <returns>List of newly-created binaries (may be empty)</returns> public override List <UEBuildBinary> ProcessUnboundModules(UEBuildBinary ExecutableBinary) { var Binaries = new Dictionary <string, UEBuildBinary>(StringComparer.InvariantCultureIgnoreCase); if (Config.bHasModuleRules) { foreach (var ModuleName in ModuleNames) { var Module = Target.FindOrCreateModuleByName(ModuleName); Module.RecursivelyProcessUnboundModules(Target, ref Binaries, ExecutableBinary); } } else { // There's only one module in this case, so just bind it to this binary foreach (var ModuleName in ModuleNames) { Binaries.Add(ModuleName, this); } } // Now build a final list of newly-created binaries that were bound to. The hash may contain duplicates, so // we filter those out here. var BinaryList = new List <UEBuildBinary>(); foreach (var CurBinary in Binaries.Values) { // Never include ourselves in the new binary list (monolithic case) if (CurBinary != this) { if (!BinaryList.Contains(CurBinary)) { BinaryList.Add(CurBinary); } } } return(BinaryList); }
/// <summary> /// Sets up the environment for linking this module. /// </summary> public virtual void SetupPrivateLinkEnvironment( UEBuildBinary SourceBinary, LinkEnvironment LinkEnvironment, List <UEBuildBinary> BinaryDependencies, HashSet <UEBuildModule> VisitedModules ) { // Allow the module's public dependencies to add library paths and additional libraries to the link environment. SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalShadowFiles, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules); // Also allow the module's public and private dependencies to modify the link environment. List <UEBuildModule> AllDependencyModules = new List <UEBuildModule>(); AllDependencyModules.AddRange(PrivateDependencyModules); AllDependencyModules.AddRange(PublicDependencyModules); foreach (UEBuildModule DependencyModule in AllDependencyModules) { DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.LibraryPaths, LinkEnvironment.AdditionalLibraries, LinkEnvironment.Frameworks, LinkEnvironment.WeakFrameworks, LinkEnvironment.AdditionalFrameworks, LinkEnvironment.AdditionalShadowFiles, LinkEnvironment.AdditionalBundleResources, LinkEnvironment.DelayLoadDLLs, BinaryDependencies, VisitedModules); } }
public override void AddFilesToManifest(BuildManifest Manifest, UEBuildBinary Binary) { if (BuildConfiguration.bCreateStubIPA) { string StubFile = Path.Combine (Path.GetDirectoryName (Binary.Config.OutputFilePath), Path.GetFileNameWithoutExtension (Binary.Config.OutputFilePath) + ".stub"); Manifest.AddBuildProduct(StubFile); } }
public virtual void AddFilesToManifest(BuildManifest Manifest, UEBuildBinary Binary) { }
public override void SetupPrivateLinkEnvironment( UEBuildBinary SourceBinary, LinkEnvironment LinkEnvironment, List<UEBuildBinary> BinaryDependencies, Dictionary<UEBuildModule, bool> VisitedModules ) { base.SetupPrivateLinkEnvironment(SourceBinary, LinkEnvironment, BinaryDependencies, VisitedModules); // Setup the link environment for linking a CLR binary. LinkEnvironment.Config.CLRMode = CPPCLRMode.CLREnabled; }
public override void AddFilesToManifest(BuildManifest Manifest, UEBuildBinary Binary) { // we need to include the generated .mem file. Manifest.AddBuildProduct(Binary.Config.OutputFilePath + ".mem"); }
/// <summary> /// Sets up the environment for linking any module that includes the public interface of this module. /// </summary> protected virtual void SetupPublicLinkEnvironment( UEBuildBinary SourceBinary, List <DirectoryReference> LibraryPaths, List <string> AdditionalLibraries, List <string> RuntimeLibraryPaths, List <string> Frameworks, List <string> WeakFrameworks, List <UEBuildFramework> AdditionalFrameworks, List <string> AdditionalShadowFiles, List <UEBuildBundleResource> AdditionalBundleResources, List <string> DelayLoadDLLs, List <UEBuildBinary> BinaryDependencies, HashSet <UEBuildModule> VisitedModules, DirectoryReference ExeDir ) { // There may be circular dependencies in compile dependencies, so we need to avoid reentrance. if (VisitedModules.Add(this)) { // Add this module's binary to the binary dependencies. if (Binary != null && Binary != SourceBinary && !BinaryDependencies.Contains(Binary)) { BinaryDependencies.Add(Binary); } // 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. bool bIsBuildingAStaticLibrary = (SourceBinary != null && SourceBinary.Type == UEBuildBinaryType.StaticLibrary); bool bIsModuleBinaryAStaticLibrary = (Binary != null && Binary.Type == UEBuildBinaryType.StaticLibrary); if (!bIsBuildingAStaticLibrary && bIsModuleBinaryAStaticLibrary) { // Gather all dependencies and recursively call SetupPublicLinkEnvironmnet List <UEBuildModule> AllDependencyModules = new List <UEBuildModule>(); AllDependencyModules.AddRange(PrivateDependencyModules); AllDependencyModules.AddRange(PublicDependencyModules); foreach (UEBuildModule DependencyModule in AllDependencyModules) { bool bIsExternalModule = (DependencyModule as UEBuildModuleExternal != null); bool bIsInStaticLibrary = (DependencyModule.Binary != null && DependencyModule.Binary.Type == UEBuildBinaryType.StaticLibrary); if (bIsExternalModule || bIsInStaticLibrary) { DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LibraryPaths, AdditionalLibraries, RuntimeLibraryPaths, Frameworks, WeakFrameworks, AdditionalFrameworks, AdditionalShadowFiles, AdditionalBundleResources, DelayLoadDLLs, BinaryDependencies, VisitedModules, ExeDir); } } } // Add this module's public include library paths and additional libraries. LibraryPaths.AddRange(PublicLibraryPaths); AdditionalLibraries.AddRange(PublicAdditionalLibraries); RuntimeLibraryPaths.AddRange(ExpandPathVariables(Rules.PublicRuntimeLibraryPaths, SourceBinary.OutputDir, ExeDir)); Frameworks.AddRange(PublicFrameworks); WeakFrameworks.AddRange(PublicWeakFrameworks); AdditionalBundleResources.AddRange(PublicAdditionalBundleResources); // Remember the module so we can refer to it when needed foreach (UEBuildFramework Framework in PublicAdditionalFrameworks) { Framework.OwningModule = this; } AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); AdditionalShadowFiles.AddRange(PublicAdditionalShadowFiles); DelayLoadDLLs.AddRange(PublicDelayLoadDLLs); } }
/** Sets up the environment for compiling any module that includes the public interface of this module. */ protected virtual void SetupPublicCompileEnvironment( UEBuildBinary SourceBinary, bool bIncludePathsOnly, HashSet<string> IncludePaths, HashSet<string> SystemIncludePaths, List<string> Definitions, List<UEBuildFramework> AdditionalFrameworks, Dictionary<UEBuildModule, bool> VisitedModules ) { // There may be circular dependencies in compile dependencies, so we need to avoid reentrance. if(!VisitedModules.ContainsKey(this)) { VisitedModules.Add(this,true); // Add this module's public include paths and definitions. AddIncludePathsWithChecks(IncludePaths, PublicIncludePaths); AddIncludePathsWithChecks(SystemIncludePaths, PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // If this module is being built into a DLL or EXE, set up an IMPORTS or EXPORTS definition for it. if (Binary == null) { // If we're referencing include paths for a module that's not being built, we don't actually need to import anything from it, but we need to avoid barfing when // the compiler encounters an _API define. We also want to avoid changing the compile environment in cases where the module happens to be compiled because it's a dependency // of something else, which cause a fall-through to the code below and set up an empty _API define. if(bIncludePathsOnly) { Log.TraceVerbose( "{0}: Include paths only for {1} (no binary)", Path.GetFileNameWithoutExtension( SourceBinary.Config.OutputFilePaths[0] ), Name ); Definitions.Add( Name.ToUpperInvariant() + "_API=" ); } } else { string BinaryPath = Binary.Config.OutputFilePaths[0]; string SourceBinaryPath = SourceBinary.Config.OutputFilePaths[0]; if (ProjectFileGenerator.bGenerateProjectFiles || (Binary.Config.Type == UEBuildBinaryType.StaticLibrary)) { // When generating IntelliSense files, never add dllimport/dllexport specifiers as it // simply confuses the compiler Definitions.Add( Name.ToUpperInvariant() + "_API=" ); } else if( Binary == SourceBinary ) { if( Binary.Config.bAllowExports ) { Log.TraceVerbose( "{0}: Exporting {1} from {2}", Path.GetFileNameWithoutExtension( SourceBinaryPath ), Name, Path.GetFileNameWithoutExtension( BinaryPath ) ); Definitions.Add( Name.ToUpperInvariant() + "_API=DLLEXPORT" ); } else { Log.TraceVerbose( "{0}: Not importing/exporting {1} (binary: {2})", Path.GetFileNameWithoutExtension( SourceBinaryPath ), Name, Path.GetFileNameWithoutExtension( BinaryPath ) ); Definitions.Add( Name.ToUpperInvariant() + "_API=" ); } } else { // @todo SharedPCH: Public headers included from modules that are not importing the module of that public header, seems invalid. // Those public headers have no business having APIs in them. OnlineSubsystem has some public headers like this. Without changing // this, we need to suppress warnings at compile time. if( bIncludePathsOnly ) { Log.TraceVerbose( "{0}: Include paths only for {1} (binary: {2})", Path.GetFileNameWithoutExtension( SourceBinaryPath ), Name, Path.GetFileNameWithoutExtension( BinaryPath ) ); Definitions.Add( Name.ToUpperInvariant() + "_API=" ); } else if (Binary.Config.bAllowExports) { Log.TraceVerbose( "{0}: Importing {1} from {2}", Path.GetFileNameWithoutExtension( SourceBinaryPath ), Name, Path.GetFileNameWithoutExtension( BinaryPath ) ); Definitions.Add( Name.ToUpperInvariant() + "_API=DLLIMPORT" ); } else { Log.TraceVerbose( "{0}: Not importing/exporting {1} (binary: {2})", Path.GetFileNameWithoutExtension( SourceBinaryPath ), Name, Path.GetFileNameWithoutExtension( BinaryPath )); Definitions.Add( Name.ToUpperInvariant() + "_API=" ); } } } if( !bIncludePathsOnly ) { // Recurse on this module's public dependencies. foreach(var DependencyName in PublicDependencyModuleNames) { var DependencyModule = Target.GetModuleByName(DependencyName); DependencyModule.SetupPublicCompileEnvironment(SourceBinary,bIncludePathsOnly, IncludePaths, SystemIncludePaths, Definitions, AdditionalFrameworks, VisitedModules); } } // Now add an include paths from modules with header files that we need access to, but won't necessarily be importing foreach( var IncludePathModuleName in PublicIncludePathModuleNames ) { bool bInnerIncludePathsOnly = true; var IncludePathModule = Target.GetModuleByName(IncludePathModuleName); IncludePathModule.SetupPublicCompileEnvironment( SourceBinary, bInnerIncludePathsOnly, IncludePaths, SystemIncludePaths, Definitions, AdditionalFrameworks, VisitedModules ); } // Add the module's directory to the include path, so we can root #includes to it IncludePaths.Add(Utils.CleanDirectorySeparators(Utils.MakePathRelativeTo(ModuleDirectory, Path.Combine(ProjectFileGenerator.RootRelativePath, "Engine/Source")), '/')); // Add the additional frameworks so that the compiler can know about their #include paths AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); // Remember the module so we can refer to it when needed foreach (var Framework in PublicAdditionalFrameworks) { Framework.OwningModule = this; } } }
/// <summary> /// Sets up the environment for compiling any module that includes the public interface of this module. /// </summary> public void AddModuleToCompileEnvironment( UEBuildBinary SourceBinary, bool bIncludePathsOnly, HashSet <string> IncludePaths, HashSet <string> SystemIncludePaths, List <string> Definitions, List <UEBuildFramework> AdditionalFrameworks ) { // Add this module's public include paths and definitions. AddIncludePathsWithChecks(IncludePaths, PublicIncludePaths); AddIncludePathsWithChecks(SystemIncludePaths, PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // If this module is being built into a DLL or EXE, set up an IMPORTS or EXPORTS definition for it. if (SourceBinary == null) { // No source binary means a shared PCH, so always import all symbols. It's possible that an include path module now may be a imported module for the shared PCH consumer. if (!bIncludePathsOnly) { if (Binary == null || !Binary.Config.bAllowExports) { Definitions.Add(ModuleApiDefine + "="); } else { Definitions.Add(ModuleApiDefine + "=DLLIMPORT"); } } } else if (Binary == null) { // If we're referencing include paths for a module that's not being built, we don't actually need to import anything from it, but we need to avoid barfing when // the compiler encounters an _API define. We also want to avoid changing the compile environment in cases where the module happens to be compiled because it's a dependency // of something else, which cause a fall-through to the code below and set up an empty _API define. if (bIncludePathsOnly) { Log.TraceVerbose("{0}: Include paths only for {1} (no binary)", SourceBinary.Config.OutputFilePaths[0].GetFileNameWithoutExtension(), Name); Definitions.Add(ModuleApiDefine + "="); } } else { FileReference BinaryPath = Binary.Config.OutputFilePaths[0]; FileReference SourceBinaryPath = SourceBinary.Config.OutputFilePaths[0]; if (ProjectFileGenerator.bGenerateProjectFiles || (Binary.Config.Type == UEBuildBinaryType.StaticLibrary)) { // When generating IntelliSense files, never add dllimport/dllexport specifiers as it // simply confuses the compiler Definitions.Add(ModuleApiDefine + "="); } else if (Binary == SourceBinary) { if (Binary.Config.bAllowExports) { Log.TraceVerbose("{0}: Exporting {1} from {2}", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } else { Log.TraceVerbose("{0}: Not importing/exporting {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } } else { // @todo SharedPCH: Public headers included from modules that are not importing the module of that public header, seems invalid. // Those public headers have no business having APIs in them. OnlineSubsystem has some public headers like this. Without changing // this, we need to suppress warnings at compile time. if (bIncludePathsOnly) { Log.TraceVerbose("{0}: Include paths only for {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } else if (Binary.Config.bAllowExports) { Log.TraceVerbose("{0}: Importing {1} from {2}", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "=DLLIMPORT"); } else { Log.TraceVerbose("{0}: Not importing/exporting {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } } } // Add the module's directory to the include path, so we can root #includes to it IncludePaths.Add(NormalizedModuleIncludePath); // Add the additional frameworks so that the compiler can know about their #include paths AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); // Remember the module so we can refer to it when needed foreach (UEBuildFramework Framework in PublicAdditionalFrameworks) { Framework.OwningModule = this; } }
public virtual void ModifyBuildProducts(UEBuildBinary Binary, Dictionary <FileReference, BuildProductType> BuildProducts) { }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { if (Binary.Target.GlobalLinkEnvironment.Config.bIsBuildingConsoleApplication) { return; } if (BundleContentsDirectory == "" && Binary.Config.Type == UEBuildBinaryType.Executable) { BundleContentsDirectory = Path.GetDirectoryName(Path.GetDirectoryName(Binary.Config.OutputFilePath)) + "/"; } // We need to know what third party dylibs would be copied to the bundle if(Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { var Modules = Binary.GetAllDependencyModules(bIncludeDynamicallyLoaded: false, bForceCircular: false); var BinaryLinkEnvironment = Binary.Target.GlobalLinkEnvironment.DeepCopy(); var BinaryDependencies = new List<UEBuildBinary>(); var LinkEnvironmentVisitedModules = new Dictionary<UEBuildModule, bool>(); foreach (var Module in Modules) { Module.SetupPrivateLinkEnvironment(Binary, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules); } foreach (string AdditionalLibrary in BinaryLinkEnvironment.Config.AdditionalLibraries) { string LibName = Path.GetFileName(AdditionalLibrary); if (LibName.StartsWith("lib")) { if (Path.GetExtension(AdditionalLibrary) == ".dylib" && !String.IsNullOrEmpty(BundleContentsDirectory)) { string Entry = BundleContentsDirectory + "MacOS/" + LibName; Receipt.AddBuildProduct(Entry, BuildProductType.DynamicLibrary); } } } foreach (UEBuildBundleResource Resource in BinaryLinkEnvironment.Config.AdditionalBundleResources) { if (Directory.Exists(Resource.ResourcePath)) { foreach (string ResourceFile in Directory.GetFiles(Resource.ResourcePath, "*", SearchOption.AllDirectories)) { Receipt.AddBuildProduct(Path.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, ResourceFile.Substring(Path.GetDirectoryName(Resource.ResourcePath).Length + 1)), BuildProductType.RequiredResource); } } else { Receipt.AddBuildProduct(Path.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, Path.GetFileName(Resource.ResourcePath)), BuildProductType.RequiredResource); } } } if (Binary.Config.Type == UEBuildBinaryType.Executable) { // And we also need all the resources Receipt.AddBuildProduct(BundleContentsDirectory + "Info.plist", BuildProductType.RequiredResource); Receipt.AddBuildProduct(BundleContentsDirectory + "PkgInfo", BuildProductType.RequiredResource); Receipt.AddBuildProduct(BundleContentsDirectory + "Resources/UE4.icns", BuildProductType.RequiredResource); if (Binary.Target.AppName.StartsWith("UE4Editor")) { Receipt.AddBuildProduct(BundleContentsDirectory + "Resources/UProject.icns", BuildProductType.RequiredResource); } } }
/// <summary> /// Sets up the environment for compiling any module that includes the public interface of this module. /// </summary> public void AddModuleToCompileEnvironment( UEBuildBinary SourceBinary, bool bIncludePathsOnly, HashSet<string> IncludePaths, HashSet<string> SystemIncludePaths, List<string> Definitions, List<UEBuildFramework> AdditionalFrameworks ) { // Add this module's public include paths and definitions. AddIncludePathsWithChecks(IncludePaths, PublicIncludePaths); AddIncludePathsWithChecks(SystemIncludePaths, PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // If this module is being built into a DLL or EXE, set up an IMPORTS or EXPORTS definition for it. if (Binary == null) { // If we're referencing include paths for a module that's not being built, we don't actually need to import anything from it, but we need to avoid barfing when // the compiler encounters an _API define. We also want to avoid changing the compile environment in cases where the module happens to be compiled because it's a dependency // of something else, which cause a fall-through to the code below and set up an empty _API define. if (bIncludePathsOnly) { Log.TraceVerbose("{0}: Include paths only for {1} (no binary)", SourceBinary.Config.OutputFilePaths[0].GetFileNameWithoutExtension(), Name); Definitions.Add(ModuleApiDefine + "="); } } else { FileReference BinaryPath = Binary.Config.OutputFilePaths[0]; FileReference SourceBinaryPath = SourceBinary.Config.OutputFilePaths[0]; if (ProjectFileGenerator.bGenerateProjectFiles || (Binary.Config.Type == UEBuildBinaryType.StaticLibrary)) { // When generating IntelliSense files, never add dllimport/dllexport specifiers as it // simply confuses the compiler Definitions.Add(ModuleApiDefine + "="); } else if (Binary == SourceBinary) { if (Binary.Config.bAllowExports) { Log.TraceVerbose("{0}: Exporting {1} from {2}", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } else { Log.TraceVerbose("{0}: Not importing/exporting {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } } else { // @todo SharedPCH: Public headers included from modules that are not importing the module of that public header, seems invalid. // Those public headers have no business having APIs in them. OnlineSubsystem has some public headers like this. Without changing // this, we need to suppress warnings at compile time. if (bIncludePathsOnly) { Log.TraceVerbose("{0}: Include paths only for {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } else if (Binary.Config.bAllowExports) { Log.TraceVerbose("{0}: Importing {1} from {2}", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "=DLLIMPORT"); } else { Log.TraceVerbose("{0}: Not importing/exporting {1} (binary: {2})", SourceBinaryPath.GetFileNameWithoutExtension(), Name, BinaryPath.GetFileNameWithoutExtension()); Definitions.Add(ModuleApiDefine + "="); } } } // Add the module's directory to the include path, so we can root #includes to it IncludePaths.Add(NormalizedModuleIncludePath); // Add the additional frameworks so that the compiler can know about their #include paths AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); // Remember the module so we can refer to it when needed foreach (UEBuildFramework Framework in PublicAdditionalFrameworks) { Framework.OwningModule = this; } }
public virtual void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary) { }
private List<string> GenerateLinkerFixupsContents(UEBuildBinary ExecutableBinary, CPPEnvironment CompileEnvironment, string HeaderFilename, string LinkerFixupsName, List<string> PrivateDependencyModuleNames) { var Result = new List<string>(); Result.Add("#include \"" + HeaderFilename + "\""); // To reduce the size of the command line for the compiler, we're going to put all definitions inside of the cpp file. foreach (var Definition in CompileEnvironment.Config.Definitions) { string MacroName; string MacroValue = String.Empty; int EqualsIndex = Definition.IndexOf('='); if (EqualsIndex >= 0) { MacroName = Definition.Substring(0, EqualsIndex); MacroValue = Definition.Substring(EqualsIndex + 1); } else { MacroName = Definition; } Result.Add("#ifndef " + MacroName); Result.Add(String.Format("\t#define {0} {1}", MacroName, MacroValue)); Result.Add("#endif"); } // Add a function that is not referenced by anything that invokes all the empty functions in the different static libraries Result.Add("void " + LinkerFixupsName + "()"); Result.Add("{"); // Fill out the body of the function with the empty function calls. This is what causes the static libraries to be considered relevant var DependencyModules = ExecutableBinary.GetAllDependencyModules(bIncludeDynamicallyLoaded: false, bForceCircular: false); foreach(string ModuleName in DependencyModules.OfType<UEBuildModuleCPP>().Where(CPPModule => CPPModule.AutoGenerateCppInfo != null).Select(CPPModule => CPPModule.Name).Distinct()) { Result.Add(" extern void EmptyLinkFunctionForGeneratedCode" + ModuleName + "();"); Result.Add(" EmptyLinkFunctionForGeneratedCode" + ModuleName + "();"); } foreach (var DependencyModuleName in PrivateDependencyModuleNames) { Result.Add(" extern void EmptyLinkFunctionForStaticInitialization" + DependencyModuleName + "();"); Result.Add(" EmptyLinkFunctionForStaticInitialization" + DependencyModuleName + "();"); } // End the function body that was started above Result.Add("}"); return Result; }
/** * Gathers and binds binaries for this module and all of it's dependent modules * * @param Target The target we are currently building * @param Binaries Dictionary of all binaries we've gathered so far * @param ExecutableBinary The binary for the target's main executable (used only when linking monolithically) * @param bBuildOnlyModules True to build only specific modules, false for all * @param ModulesToBuild The specific modules to build */ public virtual void RecursivelyProcessUnboundModules(UEBuildTarget Target, ref Dictionary<string, UEBuildBinary> Binaries, UEBuildBinary ExecutableBinary) { }
/// <summary> /// Binds artificial module to given binary. /// </summary> /// <param name="Module">Module to bind.</param> /// <param name="Binary">Binary to bind.</param> private void BindArtificialModuleToBinary(UEBuildModuleCPP Module, UEBuildBinary Binary) { Module.Binary = Binary; Module.bIncludedInTarget = true; // Process dependencies for this new module Module.CachePCHUsageForModuleSourceFiles(Module.CreateModuleCompileEnvironment(GlobalCompileEnvironment)); // Add module to binary Binary.AddModule(Module.Name); }
/// <summary> /// Process all modules that aren't yet bound, creating binaries for modules that don't yet have one (if needed), /// and updating modules for circular dependencies. /// </summary> /// <param name="ExecutableBinary">The executable binary, which links against all unbound modules when building monolithically</param> /// <returns>List of newly-created binaries (may be empty)</returns> public override List<UEBuildBinary> ProcessUnboundModules(UEBuildBinary ExecutableBinary) { var Binaries = new Dictionary<string, UEBuildBinary>( StringComparer.InvariantCultureIgnoreCase ); if (Config.bHasModuleRules) { foreach (var ModuleName in ModuleNames) { var Module = Target.FindOrCreateModuleByName(ModuleName); Module.RecursivelyProcessUnboundModules(Target, ref Binaries, ExecutableBinary); } } else { // There's only one module in this case, so just bind it to this binary foreach (var ModuleName in ModuleNames) { Binaries.Add(ModuleName, this); } } // Now build a final list of newly-created binaries that were bound to. The hash may contain duplicates, so // we filter those out here. var BinaryList = new List<UEBuildBinary>(); foreach( var CurBinary in Binaries.Values ) { // Never include ourselves in the new binary list (monolithic case) if( CurBinary != this ) { if( !BinaryList.Contains( CurBinary ) ) { BinaryList.Add( CurBinary ); } } } return BinaryList; }
public override void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { if (BuildConfiguration.bCreateStubIPA && Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { string StubFile = Path.Combine (Path.GetDirectoryName (Binary.Config.OutputFilePath), Path.GetFileNameWithoutExtension (Binary.Config.OutputFilePath) + ".stub"); Receipt.AddBuildProduct(StubFile, BuildProductType.Executable); } }
public virtual void AddFilesToReceipt(BuildReceipt Receipt, UEBuildBinary Binary) { }
public virtual void AddFilesToManifest(ref FileManifest manifest, UEBuildBinary Binary) { }
public virtual void ModifyBuildProducts(UEBuildBinary Binary, Dictionary<FileReference, BuildProductType> BuildProducts) { }
public override void RecursivelyProcessUnboundModules(UEBuildTarget Target, ref Dictionary<string, UEBuildBinary> Binaries, UEBuildBinary ExecutableBinary) { // Make sure this module is bound to a binary if( !bIncludedInTarget ) { throw new BuildException( "Module '{0}' should already have been bound to a binary!", Name ); } var AllModuleNames = new List<string>(); AllModuleNames.AddRange( PrivateDependencyModuleNames ); AllModuleNames.AddRange( PublicDependencyModuleNames ); AllModuleNames.AddRange( DynamicallyLoadedModuleNames ); AllModuleNames.AddRange( PlatformSpecificDynamicallyLoadedModuleNames ); foreach( var DependencyName in AllModuleNames ) { var DependencyModule = Target.FindOrCreateModuleByName(DependencyName); // Skip modules that are included with the target (externals) if( !DependencyModule.bIncludedInTarget ) { if( !Binaries.ContainsKey( DependencyModule.Name ) ) { UEBuildBinary BinaryToBindTo; if (Target.ShouldCompileMonolithic()) { // When linking monolithically, any unbound modules will be linked into the main executable BinaryToBindTo = ExecutableBinary; } else { // Is this a Rocket module? bool bIsRocketModule = RulesCompiler.IsRocketProjectModule(DependencyName); // Is this a plugin module? var PluginInfo = Plugins.GetPluginInfoForModule( DependencyName ); string OutputFilePath = Target.MakeBinaryPath(DependencyModule.Name, Target.GetAppName() + "-" + DependencyModule.Name, UEBuildBinaryType.DynamicLinkLibrary, Target.Rules.Type, bIsRocketModule, PluginInfo, ""); // If it's an engine module, output intermediates to the engine intermediates directory. string IntermediateDirectory = Binary.Config.IntermediateDirectory; if (PluginInfo == null && IntermediateDirectory != Target.EngineIntermediateDirectory && Path.GetFullPath(DependencyModule.ModuleDirectory).StartsWith(Path.GetFullPath(BuildConfiguration.RelativeEnginePath))) { IntermediateDirectory = Target.EngineIntermediateDirectory; } // When using modular linkage, unbound modules will be linked into their own DLL files UEBuildBinaryConfiguration Config = new UEBuildBinaryConfiguration( InType: UEBuildBinaryType.DynamicLinkLibrary, InOutputFilePath: OutputFilePath, InIntermediateDirectory: IntermediateDirectory, bInAllowExports: true, InModuleNames: new List<string> { DependencyModule.Name }, InTargetName: Target.GetAppName(), bInIsCrossTarget: PlatformSpecificDynamicallyLoadedModuleNames.Contains(DependencyName) && !DynamicallyLoadedModuleNames.Contains(DependencyName), InTargetConfiguration: Target.Configuration, bInCompileMonolithic: Target.ShouldCompileMonolithic() ); // Fix up the binary path if this is module specifies an alternate output directory Config.OutputFilePath = DependencyModule.FixupOutputPath(Config.OutputFilePath); BinaryToBindTo = new UEBuildBinaryCPP( Target, Config ); } Binaries[ DependencyModule.Name ] = BinaryToBindTo; // Bind this module DependencyModule.Binary = BinaryToBindTo; DependencyModule.bIncludedInTarget = true; // Also add binaries for this module's dependencies DependencyModule.RecursivelyProcessUnboundModules( Target, ref Binaries, ExecutableBinary ); } } if (Target.ShouldCompileMonolithic() == false) { // Check to see if there is a circular relationship between the module and it's referencer if( DependencyModule.Binary != null ) { if( CircularlyReferencedDependentModules.Contains( DependencyName ) ) { DependencyModule.Binary.SetCreateImportLibrarySeparately( true ); } } } } // Also make sure module entries are created for any module that is pulled in as an "include path" module. // These modules are never linked in unless they were referenced as an actual dependency of a different module, // but we still need to keep track of them so that we can find their include paths when setting up our // module's include paths. RecursivelyAddIncludePathModules( Target, bPublicIncludesOnly:false ); }
/// <summary> /// Process all modules that aren't yet bound, creating binaries for modules that don't yet have one (if needed), /// and updating modules for circular dependencies. /// </summary> /// <param name="ExecutableBinary">The executable binary, which links against all unbound modules when building monolithically</param> /// <returns>List of newly-created binaries (may be empty)</returns> public virtual List<UEBuildBinary> ProcessUnboundModules(UEBuildBinary ExecutableBinary) { return null; }
/** Sets up the environment for compiling any module that includes the public interface of this module. */ protected virtual void SetupPublicCompileEnvironment( UEBuildBinary SourceBinary, bool bIncludePathsOnly, ref List<string> IncludePaths, ref List<string> SystemIncludePaths, ref List<string> Definitions, ref Dictionary<UEBuildModule, bool> VisitedModules ) { // There may be circular dependencies in compile dependencies, so we need to avoid reentrance. if(!VisitedModules.ContainsKey(this)) { VisitedModules.Add(this,true); // Add this module's public include paths and definitions. IncludePaths.AddRange(PublicIncludePaths); SystemIncludePaths.AddRange(PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // If this module is being built into a DLL or EXE, set up an IMPORTS or EXPORTS definition for it. if (Binary != null) { if (ProjectFileGenerator.bGenerateProjectFiles || (Binary.Config.Type == UEBuildBinaryType.StaticLibrary)) { // When generating IntelliSense files, never add dllimport/dllexport specifiers as it // simply confuses the compiler Definitions.Add( string.Format( "{0}_API=", Name.ToUpperInvariant() ) ); } else if( Binary == SourceBinary ) { if( Binary.Config.bAllowExports ) { Log.TraceVerbose( "{0}: Exporting {1} from {2}", Path.GetFileNameWithoutExtension( SourceBinary.Config.OutputFilePath ), Name, Path.GetFileNameWithoutExtension( Binary.Config.OutputFilePath ) ); Definitions.Add( string.Format( "{0}_API=DLLEXPORT", Name.ToUpperInvariant() ) ); } else { Log.TraceVerbose( "{0}: Not importing/exporting {1} (binary: {2})", Path.GetFileNameWithoutExtension( SourceBinary.Config.OutputFilePath ), Name, Path.GetFileNameWithoutExtension( Binary.Config.OutputFilePath ) ); Definitions.Add( string.Format( "{0}_API=", Name.ToUpperInvariant() ) ); } } else { // @todo SharedPCH: Public headers included from modules that are not importing the module of that public header, seems invalid. // Those public headers have no business having APIs in them. OnlineSubsystem has some public headers like this. Without changing // this, we need to suppress warnings at compile time. if( bIncludePathsOnly ) { Log.TraceVerbose( "{0}: Include paths only for {1} (binary: {2})", Path.GetFileNameWithoutExtension( SourceBinary.Config.OutputFilePath ), Name, Path.GetFileNameWithoutExtension( Binary.Config.OutputFilePath ) ); Definitions.Add( string.Format( "{0}_API=", Name.ToUpperInvariant() ) ); } else if (Binary.Config.bAllowExports) { Log.TraceVerbose( "{0}: Importing {1} from {2}", Path.GetFileNameWithoutExtension( SourceBinary.Config.OutputFilePath ), Name, Path.GetFileNameWithoutExtension( Binary.Config.OutputFilePath ) ); Definitions.Add( string.Format( "{0}_API=DLLIMPORT", Name.ToUpperInvariant() ) ); } else { Log.TraceVerbose("{0}: Not importing/exporting {1} (binary: {2})", Path.GetFileNameWithoutExtension(SourceBinary.Config.OutputFilePath), Name, Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath)); Definitions.Add(string.Format("{0}_API=", Name.ToUpperInvariant())); } } } if( !bIncludePathsOnly ) { // Recurse on this module's public dependencies. foreach(var DependencyName in PublicDependencyModuleNames) { var DependencyModule = Target.GetModuleByName(DependencyName); DependencyModule.SetupPublicCompileEnvironment(SourceBinary,bIncludePathsOnly,ref IncludePaths,ref SystemIncludePaths,ref Definitions,ref VisitedModules); } } // Now add an include paths from modules with header files that we need access to, but won't necessarily be importing foreach( var IncludePathModuleName in PublicIncludePathModuleNames ) { bool bInnerIncludePathsOnly = true; var IncludePathModule = Target.GetModuleByName(IncludePathModuleName); IncludePathModule.SetupPublicCompileEnvironment( SourceBinary, bInnerIncludePathsOnly, ref IncludePaths, ref SystemIncludePaths, ref Definitions, ref VisitedModules ); } } }
/** Sets up the environment for linking this module. */ public virtual void SetupPrivateLinkEnvironment( UEBuildBinary SourceBinary, LinkEnvironment LinkEnvironment, List<UEBuildBinary> BinaryDependencies, Dictionary<UEBuildModule, bool> VisitedModules ) { // Allow the module's public dependencies to add library paths and additional libraries to the link environment. SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.Config.LibraryPaths, LinkEnvironment.Config.AdditionalLibraries, LinkEnvironment.Config.Frameworks, LinkEnvironment.Config.WeakFrameworks, LinkEnvironment.Config.AdditionalFrameworks,LinkEnvironment.Config.AdditionalShadowFiles, LinkEnvironment.Config.AdditionalBundleResources, LinkEnvironment.Config.DelayLoadDLLs, BinaryDependencies, VisitedModules); // Also allow the module's public and private dependencies to modify the link environment. List<string> AllDependencyModuleNames = new List<string>(PrivateDependencyModuleNames); AllDependencyModuleNames.AddRange(PublicDependencyModuleNames); foreach (var DependencyName in AllDependencyModuleNames) { var DependencyModule = Target.GetModuleByName(DependencyName); DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LinkEnvironment.Config.LibraryPaths, LinkEnvironment.Config.AdditionalLibraries, LinkEnvironment.Config.Frameworks, LinkEnvironment.Config.WeakFrameworks, LinkEnvironment.Config.AdditionalFrameworks, LinkEnvironment.Config.AdditionalShadowFiles, LinkEnvironment.Config.AdditionalBundleResources, LinkEnvironment.Config.DelayLoadDLLs, BinaryDependencies, VisitedModules); } }
/** Sets up the environment for linking any module that includes the public interface of this module. */ protected virtual void SetupPublicLinkEnvironment( UEBuildBinary SourceBinary, List<string> LibraryPaths, List<string> AdditionalLibraries, List<string> Frameworks, List<string> WeakFrameworks, List<UEBuildFramework> AdditionalFrameworks, List<string> AdditionalShadowFiles, List<UEBuildBundleResource> AdditionalBundleResources, List<string> DelayLoadDLLs, List<UEBuildBinary> BinaryDependencies, Dictionary<UEBuildModule, bool> VisitedModules ) { // There may be circular dependencies in compile dependencies, so we need to avoid reentrance. if(!VisitedModules.ContainsKey(this)) { VisitedModules.Add(this,true); // Only process modules that are included in the current target. if(bIncludedInTarget) { // Add this module's binary to the binary dependencies. if(Binary != null && Binary != SourceBinary && !BinaryDependencies.Contains(Binary)) { BinaryDependencies.Add(Binary); } // 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. bool bIsBuildingAStaticLibrary = (SourceBinary != null && SourceBinary.Config.Type == UEBuildBinaryType.StaticLibrary); bool bIsModuleBinaryAStaticLibrary = (Binary != null && Binary.Config.Type == UEBuildBinaryType.StaticLibrary); if (!bIsBuildingAStaticLibrary && bIsModuleBinaryAStaticLibrary) { // Gather all dependencies and recursively call SetupPublicLinkEnvironmnet List<string> AllDependencyModuleNames = new List<string>(PrivateDependencyModuleNames); AllDependencyModuleNames.AddRange(PublicDependencyModuleNames); foreach (var DependencyName in AllDependencyModuleNames) { var DependencyModule = Target.GetModuleByName(DependencyName); bool bIsExternalModule = (DependencyModule as UEBuildExternalModule != null); bool bIsInStaticLibrary = (DependencyModule.Binary != null && DependencyModule.Binary.Config.Type == UEBuildBinaryType.StaticLibrary); if (bIsExternalModule || bIsInStaticLibrary) { DependencyModule.SetupPublicLinkEnvironment(SourceBinary, LibraryPaths, AdditionalLibraries, Frameworks, WeakFrameworks, AdditionalFrameworks, AdditionalShadowFiles, AdditionalBundleResources, DelayLoadDLLs, BinaryDependencies, VisitedModules); } } } // Add this module's public include library paths and additional libraries. LibraryPaths.AddRange(PublicLibraryPaths); AdditionalLibraries.AddRange(PublicAdditionalLibraries); Frameworks.AddRange(PublicFrameworks); WeakFrameworks.AddRange(PublicWeakFrameworks); AdditionalBundleResources.AddRange(PublicAdditionalBundleResources); // Remember the module so we can refer to it when needed foreach ( var Framework in PublicAdditionalFrameworks ) { Framework.OwningModule = this; } AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); AdditionalShadowFiles.AddRange(PublicAdditionalShadowFiles); DelayLoadDLLs.AddRange(PublicDelayLoadDLLs); } } }
public virtual void AddFilesToManifest(ref FileManifest manifest, UEBuildBinary Binary ) { }
public virtual void ModifyBuildProducts(ReadOnlyTargetRules Target, UEBuildBinary Binary, List <string> Libraries, List <UEBuildBundleResource> BundleResources, Dictionary <FileReference, BuildProductType> BuildProducts) { }
/// <summary> /// Process all modules that aren't yet bound, creating binaries for modules that don't yet have one (if needed), /// and updating modules for circular dependencies. /// </summary> /// <param name="ExecutableBinary">The executable binary, which links against all unbound modules when building monolithically</param> /// <returns>List of newly-created binaries (may be empty)</returns> public virtual List <UEBuildBinary> ProcessUnboundModules(UEBuildBinary ExecutableBinary) { return(null); }
public override void ModifyBuildProducts(UEBuildBinary Binary, Dictionary<FileReference, BuildProductType> BuildProducts) { // we need to include the generated .mem and .symbols file. if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { BuildProducts.Add(Binary.Config.OutputFilePath + ".mem", BuildProductType.RequiredResource); BuildProducts.Add(Binary.Config.OutputFilePath + ".symbols", BuildProductType.RequiredResource); } }
/// <summary> /// Sets up the environment for compiling any module that includes the public interface of this module. /// </summary> public virtual void AddModuleToCompileEnvironment( UEBuildBinary SourceBinary, HashSet <DirectoryReference> IncludePaths, HashSet <DirectoryReference> SystemIncludePaths, List <string> Definitions, List <UEBuildFramework> AdditionalFrameworks, List <FileItem> AdditionalPrerequisites, bool bLegacyPublicIncludePaths ) { // 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); // Add this module's public include paths and definitions. AddIncludePaths(IncludePaths, PublicIncludePaths); if (bLegacyPublicIncludePaths) { AddIncludePaths(IncludePaths, LegacyPublicIncludePaths); } SystemIncludePaths.UnionWith(PublicSystemIncludePaths); Definitions.AddRange(PublicDefinitions); // Add the import or export declaration for the module if (Rules.Type == ModuleRules.ModuleType.CPlusPlus) { if (Rules.Target.LinkType == TargetLinkType.Monolithic) { if (Rules.Target.bShouldCompileAsDLL && (Rules.Target.bHasExports || Rules.ModuleSymbolVisibility == ModuleRules.SymbolVisibility.VisibileForDll)) { Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } else { Definitions.Add(ModuleApiDefine + "="); } } else if (Binary == null || SourceBinary != Binary) { Definitions.Add(ModuleApiDefine + "=DLLIMPORT"); } else if (!Binary.bAllowExports) { Definitions.Add(ModuleApiDefine + "="); } else { Definitions.Add(ModuleApiDefine + "=DLLEXPORT"); } } // Add the additional frameworks so that the compiler can know about their #include paths AdditionalFrameworks.AddRange(PublicAdditionalFrameworks); // Add any generated type library headers if (Rules.TypeLibraries.Count > 0) { IncludePaths.Add(IntermediateDirectory); foreach (ModuleRules.TypeLibrary TypeLibrary in Rules.TypeLibraries) { AdditionalPrerequisites.Add(FileItem.GetItemByFileReference(FileReference.Combine(IntermediateDirectory, TypeLibrary.Header))); } } }
public override void AddFilesToReceipt(TargetReceipt Receipt, UEBuildBinary Binary) { // the binary will have all of the .so's in the output files, we need to trim down to the shared apk (which is what needs to go into the manifest) if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { foreach (string BinaryPath in Binary.Config.OutputFilePaths) { string ApkFile = Path.ChangeExtension(BinaryPath, ".apk"); Receipt.AddBuildProduct(ApkFile, BuildProductType.Executable); } } }
public override void ModifyBuildProducts(UEBuildBinary Binary, Dictionary<FileReference, BuildProductType> BuildProducts) { if (BuildConfiguration.bUsePDBFiles == true) { KeyValuePair<FileReference, BuildProductType>[] BuildProductsArray = BuildProducts.ToArray(); foreach (KeyValuePair<FileReference, BuildProductType> BuildProductPair in BuildProductsArray) { string DebugExtension = ""; switch (BuildProductPair.Value) { case BuildProductType.Executable: DebugExtension = UEBuildPlatform.GetBuildPlatform(Binary.Target.Platform).GetDebugInfoExtension(UEBuildBinaryType.Executable); break; case BuildProductType.DynamicLibrary: DebugExtension = UEBuildPlatform.GetBuildPlatform(Binary.Target.Platform).GetDebugInfoExtension(UEBuildBinaryType.DynamicLinkLibrary); break; } if (DebugExtension == ".dSYM") { string BinaryPath = BuildProductPair.Key.FullName; if(BinaryPath.Contains(".app")) { while(BinaryPath.Contains(".app")) { BinaryPath = Path.GetDirectoryName(BinaryPath); } BinaryPath = Path.Combine(BinaryPath, BuildProductPair.Key.GetFileName()); BinaryPath = Path.ChangeExtension(BinaryPath, DebugExtension); FileReference Ref = new FileReference(BinaryPath); BuildProducts.Add(Ref, BuildProductType.SymbolFile); } } else if(BuildProductPair.Value == BuildProductType.SymbolFile && BuildProductPair.Key.FullName.Contains(".app")) { BuildProducts.Remove(BuildProductPair.Key); } } } if (Binary.Target.GlobalLinkEnvironment.Config.bIsBuildingConsoleApplication) { return; } if (BundleContentsDirectory == null && Binary.Config.Type == UEBuildBinaryType.Executable) { BundleContentsDirectory = Binary.Config.OutputFilePath.Directory.ParentDirectory; } // We need to know what third party dylibs would be copied to the bundle if (Binary.Config.Type != UEBuildBinaryType.StaticLibrary) { var Modules = Binary.GetAllDependencyModules(bIncludeDynamicallyLoaded: false, bForceCircular: false); var BinaryLinkEnvironment = Binary.Target.GlobalLinkEnvironment.DeepCopy(); var BinaryDependencies = new List<UEBuildBinary>(); var LinkEnvironmentVisitedModules = new HashSet<UEBuildModule>(); foreach (var Module in Modules) { Module.SetupPrivateLinkEnvironment(Binary, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules); } foreach (string AdditionalLibrary in BinaryLinkEnvironment.Config.AdditionalLibraries) { string LibName = Path.GetFileName(AdditionalLibrary); if (LibName.StartsWith("lib")) { if (Path.GetExtension(AdditionalLibrary) == ".dylib" && BundleContentsDirectory != null) { FileReference Entry = FileReference.Combine(BundleContentsDirectory, "MacOS", LibName); if (!BuildProducts.ContainsKey(Entry)) { BuildProducts.Add(Entry, BuildProductType.DynamicLibrary); } } } } foreach (UEBuildBundleResource Resource in BinaryLinkEnvironment.Config.AdditionalBundleResources) { if (Directory.Exists(Resource.ResourcePath)) { foreach (string ResourceFile in Directory.GetFiles(Resource.ResourcePath, "*", SearchOption.AllDirectories)) { BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, ResourceFile.Substring(Path.GetDirectoryName(Resource.ResourcePath).Length + 1)), BuildProductType.RequiredResource); } } else { BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, Resource.BundleContentsSubdir, Path.GetFileName(Resource.ResourcePath)), BuildProductType.RequiredResource); } } } if (Binary.Config.Type == UEBuildBinaryType.Executable) { // And we also need all the resources BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, "Info.plist"), BuildProductType.RequiredResource); BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, "PkgInfo"), BuildProductType.RequiredResource); if (Binary.Target.TargetType == TargetRules.TargetType.Editor) { BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, "Resources/UE4Editor.icns"), BuildProductType.RequiredResource); BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, "Resources/UProject.icns"), BuildProductType.RequiredResource); } else { string IconName = Binary.Target.TargetName; if (IconName == "EpicGamesBootstrapLauncher") { IconName = "EpicGamesLauncher"; } BuildProducts.Add(FileReference.Combine(BundleContentsDirectory, "Resources/" + IconName + ".icns"), BuildProductType.RequiredResource); } } }