Example #1
0
 public override void AddFilesToManifest(BuildManifest Manifest, STBuildBinary Binary)
 {
     // ok, this is pretty awful, we want the import libraries that go with the editor, only on the PC
     if (STBuildTool.BuildingRocket() &&
         Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath).StartsWith("UE4Editor-", StringComparison.InvariantCultureIgnoreCase) &&
         Path.GetExtension(Binary.Config.OutputFilePath).EndsWith("dll", StringComparison.InvariantCultureIgnoreCase) &&
         Binary.Config.Type == STBuildBinaryType.DynamicLinkLibrary)
     {
         // ok, this is pretty awful, we want the import libraries that go with the editor, only on the PC
         Manifest.AddBuildProduct(Path.Combine(Binary.Config.IntermediateDirectory, Path.GetFileNameWithoutExtension(Binary.Config.OutputFilePath) + ".lib"), "");
     }
 }
Example #2
0
        /// <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<STBuildBinary> ProcessUnboundModules(STBuildBinary ExecutableBinary)
        {
            var Binaries = new Dictionary<string, STBuildBinary>(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<STBuildBinary>();
            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;
        }
Example #3
0
 /// <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<STBuildBinary> ProcessUnboundModules(STBuildBinary ExecutableBinary)
 {
     return null;
 }
Example #4
0
 public virtual void AddFilesToManifest(BuildManifest Manifest, STBuildBinary Binary)
 {
 }
Example #5
0
        /** Sets up the environment for linking any module that includes the public interface of this module. */
        protected virtual void SetupPublicLinkEnvironment(
            STBuildBinary SourceBinary,
            ref List<string> LibraryPaths,
            ref List<string> AdditionalLibraries,
            ref List<string> Frameworks,
            ref List<string> WeakFrameworks,
            ref List<STBuildFramework> AdditionalFrameworks,
            ref List<string> AdditionalShadowFiles,
            ref List<STBuildBundleResource> AdditionalBundleResources,
            ref List<string> DelayLoadDLLs,
            ref List<STBuildBinary> BinaryDependencies,
            ref Dictionary<STBuildModule, 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 == STBuildBinaryType.StaticLibrary);
                    bool bIsModuleBinaryAStaticLibrary = (Binary != null && Binary.Config.Type == STBuildBinaryType.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 STBuildExternalModule != null);
                            bool bIsInStaticLibrary = (DependencyModule.Binary != null && DependencyModule.Binary.Config.Type == STBuildBinaryType.StaticLibrary);
                            if (bIsExternalModule || bIsInStaticLibrary)
                            {
                                DependencyModule.SetupPublicLinkEnvironment(SourceBinary, ref LibraryPaths, ref AdditionalLibraries, ref Frameworks, ref WeakFrameworks,
                                    ref AdditionalFrameworks, ref AdditionalShadowFiles, ref AdditionalBundleResources, ref DelayLoadDLLs, ref BinaryDependencies, ref 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);
                }
            }
        }
Example #6
0
        /** Sets up the environment for compiling any module that includes the public interface of this module. */
        protected virtual void SetupPublicCompileEnvironment(
            STBuildBinary SourceBinary,
            bool bIncludePathsOnly,
            ref HashSet<string> IncludePaths,
            ref HashSet<string> SystemIncludePaths,
            ref List<string> Definitions,
            ref List<STBuildFramework> AdditionalFrameworks,
            ref Dictionary<STBuildModule, 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)
                {
                    string BinaryPath = Binary.Config.OutputFilePaths[0];
                    string SourceBinaryPath = SourceBinary.Config.OutputFilePaths[0];

                    if (ProjectFileGenerator.bGenerateProjectFiles || (Binary.Config.Type == STBuildBinaryType.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, ref IncludePaths, ref SystemIncludePaths, ref Definitions, ref AdditionalFrameworks, 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 AdditionalFrameworks, ref 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);
            }
        }
Example #7
0
 /**
  * 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(STBuildTarget Target, ref Dictionary<string, STBuildBinary> Binaries, STBuildBinary ExecutableBinary)
 {
 }
Example #8
0
        public override void RecursivelyProcessUnboundModules(STBuildTarget Target, ref Dictionary<string, STBuildBinary> Binaries, STBuildBinary ExecutableBinary)
        {
            try
            {
                // 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))
                        {
                            STBuildBinary BinaryToBindTo;
                            if (Target.ShouldCompileMonolithic())
                            {
                                // When linking monolithically, any unbound modules will be linked into the main executable
                                BinaryToBindTo = ExecutableBinary;
                            }
                            else
                            {
                                // Is this a plugin module?
                                var PluginInfo = Plugins.GetPluginInfoForModule(DependencyName);

                                string[] OutputFilePaths = Target.MakeBinaryPaths(DependencyModule.Name, Target.GetAppName() + "-" + DependencyModule.Name, STBuildBinaryType.DynamicLinkLibrary, Target.TargetType, PluginInfo, "");

                                // If it's an engine module, output intermediates to the engine intermediates directory.
                                string IntermediateDirectory = Binary.Config.IntermediateDirectory;
                                if (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
                                STBuildBinaryConfiguration Config = new STBuildBinaryConfiguration(InType: STBuildBinaryType.DynamicLinkLibrary,
                                                                                                    InOutputFilePaths: OutputFilePaths,
                                                                                                    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
                                for (int Index = 0; Index < Config.OutputFilePaths.Length; Index++)
                                {
                                    Config.OutputFilePaths[Index] = DependencyModule.FixupOutputPath(Config.OutputFilePaths[Index]);
                                }

                                BinaryToBindTo = new STBuildBinaryCPP(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);
            }
            catch (System.Exception ex)
            {
                throw new ModuleProcessingException(this, ex);
            }
        }
Example #9
0
 public override void AddFilesToManifest(BuildManifest Manifest, STBuildBinary Binary)
 {
     if (BuildConfiguration.bCreateStubIPA)
     {
         string StubFile = Path.Combine (Path.GetDirectoryName (Binary.Config.OutputFilePath), Path.GetFileNameWithoutExtension (Binary.Config.OutputFilePath) + ".stub");
         Manifest.AddBuildProduct(StubFile);
     }
 }
Example #10
0
        private void GenerateLinkerFixupsContents(STBuildBinary ExecutableBinary, List<string> LinkerFixupsFileContents, CPPEnvironment CompileEnvironment, string HeaderFilename, string LinkerFixupsName, List<string> PrivateDependencyModuleNames)
        {
            LinkerFixupsFileContents.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;
                }
                LinkerFixupsFileContents.Add("#ifndef " + MacroName);
                LinkerFixupsFileContents.Add(String.Format("\t#define {0} {1}", MacroName, MacroValue));
                LinkerFixupsFileContents.Add("#endif");
            }

            // Add a function that is not referenced by anything that invokes all the empty functions in the different static libraries
            LinkerFixupsFileContents.Add("void " + LinkerFixupsName + "()");
            LinkerFixupsFileContents.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<STBuildModuleCPP>().Where(CPPModule => CPPModule.AutoGenerateCppInfo != null).Select(CPPModule => CPPModule.Name).Distinct())
            {
                LinkerFixupsFileContents.Add("    extern void EmptyLinkFunctionForGeneratedCode" + ModuleName + "();");
                LinkerFixupsFileContents.Add("    EmptyLinkFunctionForGeneratedCode" + ModuleName + "();");
            }
            foreach (var DependencyModuleName in PrivateDependencyModuleNames)
            {
                LinkerFixupsFileContents.Add("    extern void EmptyLinkFunctionForStaticInitialization" + DependencyModuleName + "();");
                LinkerFixupsFileContents.Add("    EmptyLinkFunctionForStaticInitialization" + DependencyModuleName + "();");
            }

            // End the function body that was started above
            LinkerFixupsFileContents.Add("}");
        }
Example #11
0
        /// <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(STBuildModuleCPP Module, STBuildBinary 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);
        }