Esempio n. 1
0
        private LinkEnvironment SetupBinaryLinkEnvironment(ReadOnlyTargetRules Target, UEToolChain ToolChain, LinkEnvironment LinkEnvironment, CppCompileEnvironment CompileEnvironment, List <PrecompiledHeaderTemplate> SharedPCHs, ISourceFileWorkingSet WorkingSet, DirectoryReference ExeDir, ActionGraph ActionGraph)
        {
            LinkEnvironment         BinaryLinkEnvironment         = new LinkEnvironment(LinkEnvironment);
            HashSet <UEBuildModule> LinkEnvironmentVisitedModules = new HashSet <UEBuildModule>();
            List <UEBuildBinary>    BinaryDependencies            = new List <UEBuildBinary>();

            CppCompileEnvironment BinaryCompileEnvironment = CreateBinaryCompileEnvironment(CompileEnvironment);

            foreach (UEBuildModule Module in Modules)
            {
                List <FileItem> LinkInputFiles;
                if (Module.Binary == null || Module.Binary == this)
                {
                    // Compile each module.
                    Log.TraceVerbose("Compile module: " + Module.Name);
                    LinkInputFiles = Module.Compile(Target, ToolChain, BinaryCompileEnvironment, SharedPCHs, WorkingSet, ActionGraph);

                    // NOTE: Because of 'Shared PCHs', in monolithic builds the same PCH file may appear as a link input
                    // multiple times for a single binary.  We'll check for that here, and only add it once.  This avoids
                    // a linker warning about redundant .obj files.
                    foreach (FileItem LinkInputFile in LinkInputFiles)
                    {
                        if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile))
                        {
                            BinaryLinkEnvironment.InputFiles.Add(LinkInputFile);
                        }
                    }
                }
                else
                {
                    BinaryDependencies.Add(Module.Binary);
                }

                // Allow the module to modify the link environment for the binary.
                Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules, ExeDir);
            }


            // Allow the binary dependencies to modify the link environment.
            foreach (UEBuildBinary BinaryDependency in BinaryDependencies)
            {
                BinaryDependency.SetupDependentLinkEnvironment(BinaryLinkEnvironment);
            }

            // Remove the default resource file on Windows (PCLaunch.rc) if the user has specified their own
            if (BinaryLinkEnvironment.InputFiles.Select(Item => Path.GetFileName(Item.AbsolutePath).ToLower()).Any(Name => Name.EndsWith(".res") && !Name.EndsWith(".inl.res") && Name != "pclaunch.rc.res"))
            {
                BinaryLinkEnvironment.InputFiles.RemoveAll(x => Path.GetFileName(x.AbsolutePath).ToLower() == "pclaunch.rc.res");
            }

            // Set the link output file.
            BinaryLinkEnvironment.OutputFilePaths = OutputFilePaths.ToList();

            // Set whether the link is allowed to have exports.
            BinaryLinkEnvironment.bHasExports = bAllowExports;

            // Set the output folder for intermediate files
            BinaryLinkEnvironment.IntermediateDirectory = IntermediateDirectory;

            // Put the non-executable output files (PDB, import library, etc) in the same directory as the production
            BinaryLinkEnvironment.OutputDirectory = OutputFilePaths[0].Directory;

            // Setup link output type
            BinaryLinkEnvironment.bIsBuildingDLL     = IsBuildingDll(Type);
            BinaryLinkEnvironment.bIsBuildingLibrary = IsBuildingLibrary(Type);

            // If we don't have any resource file, use the default or compile a custom one for this module
            if (BinaryLinkEnvironment.Platform == CppPlatform.Win32 || BinaryLinkEnvironment.Platform == CppPlatform.Win64)
            {
                if (!BinaryLinkEnvironment.InputFiles.Any(x => x.Location.HasExtension(".res")))
                {
                    if (BinaryLinkEnvironment.DefaultResourceFiles.Count > 0)
                    {
                        // Use the default resource file if possible
                        BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.DefaultResourceFiles);
                    }
                    else
                    {
                        // Get the intermediate directory
                        DirectoryReference ResourceIntermediateDirectory = ((UEBuildModuleCPP)Modules.First()).IntermediateDirectory;

                        // Create a compile environment for resource files
                        CppCompileEnvironment ResourceCompileEnvironment = new CppCompileEnvironment(BinaryCompileEnvironment);
                        WindowsPlatform.SetupResourceCompileEnvironment(ResourceCompileEnvironment, ResourceIntermediateDirectory, Target);

                        // @todo: This should be in some Windows code somewhere...
                        // Set the original file name macro; used in PCLaunch.rc to set the binary metadata fields.
                        string OriginalFilename = (OriginalOutputFilePaths != null) ? OriginalOutputFilePaths[0].GetFileName() : OutputFilePaths[0].GetFileName();
                        ResourceCompileEnvironment.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\"");

                        // Set the other version fields
                        ResourceCompileEnvironment.Definitions.Add(String.Format("BUILT_FROM_CHANGELIST={0}", Target.Version.Changelist));
                        ResourceCompileEnvironment.Definitions.Add(String.Format("BUILD_VERSION={0}", Target.BuildVersion));

                        // Otherwise compile the default resource file per-binary, so that it gets the correct ORIGINAL_FILE_NAME macro.
                        FileItem  DefaultResourceFile   = FileItem.GetItemByFileReference(FileReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Runtime", "Launch", "Resources", "Windows", "PCLaunch.rc"));
                        CPPOutput DefaultResourceOutput = ToolChain.CompileRCFiles(ResourceCompileEnvironment, new List <FileItem> {
                            DefaultResourceFile
                        }, ResourceIntermediateDirectory, ActionGraph);
                        BinaryLinkEnvironment.InputFiles.AddRange(DefaultResourceOutput.ObjectFiles);
                    }
                }
            }

            // Add all the common resource files
            BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.CommonResourceFiles);

            return(BinaryLinkEnvironment);
        }