/// <summary> /// Builds the binary. /// </summary> /// <param name="CompileEnvironment">The environment to compile the binary in</param> /// <param name="LinkEnvironment">The environment to link the binary in</param> /// <returns></returns> public override IEnumerable <FileItem> Build(IUEToolChain TargetToolChain, CPPEnvironment CompileEnvironment, LinkEnvironment LinkEnvironment) { // Determine the type of binary we're linking. switch (Config.Type) { case UEBuildBinaryType.DynamicLinkLibrary: CompileEnvironment.Config.bIsBuildingDLL = true; CompileEnvironment.Config.bIsBuildingLibrary = false; break; case UEBuildBinaryType.StaticLibrary: CompileEnvironment.Config.bIsBuildingDLL = false; CompileEnvironment.Config.bIsBuildingLibrary = true; break; default: CompileEnvironment.Config.bIsBuildingDLL = false; CompileEnvironment.Config.bIsBuildingLibrary = false; break; } ; var OutputFiles = new List <FileItem>(); var BinaryCompileEnvironment = CompileEnvironment.DeepCopy(); var BinaryLinkEnvironment = LinkEnvironment.DeepCopy(); // Process each module that is linked into the binary. var BinaryDependencies = new List <UEBuildBinary>(); var LinkEnvironmentVisitedModules = new Dictionary <UEBuildModule, bool>(); // @Hack: This to prevent UHT from listing CoreUObject.generated.cpp as its dependency. // We flag the compile environment when we build UHT so that we don't need to check // this for each file when generating their dependencies. BinaryCompileEnvironment.bHackHeaderGenerator = (Target.GetAppName() == "UnrealHeaderTool"); // @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. var OriginalFilename = (Config.OriginalOutputFilePaths != null) ? Path.GetFileName(Config.OriginalOutputFilePaths[0]) : Path.GetFileName(Config.OutputFilePaths[0]); BinaryCompileEnvironment.Config.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\""); foreach (var ModuleName in ModuleNames) { var Module = Target.GetModuleByName(ModuleName); // Compile each module. Log.TraceVerbose("Compile module: " + ModuleName); var LinkInputFiles = Module.Compile(CompileEnvironment, BinaryCompileEnvironment, Config.bCompileMonolithic); // 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 (var LinkInputFile in LinkInputFiles) { if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile)) { BinaryLinkEnvironment.InputFiles.Add(LinkInputFile); } } // Allow the module to modify the link environment for the binary. Module.SetupPrivateLinkEnvironment(ref BinaryLinkEnvironment, ref BinaryDependencies, ref LinkEnvironmentVisitedModules); } // 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"); } // Allow the binary dependencies to modify the link environment. foreach (var BinaryDependency in BinaryDependencies) { BinaryDependency.SetupDependentLinkEnvironment(ref BinaryLinkEnvironment); } // Set the link output file. BinaryLinkEnvironment.Config.OutputFilePaths = Config.OutputFilePaths != null ? (string[])Config.OutputFilePaths.Clone() : null; // Set whether the link is allowed to have exports. BinaryLinkEnvironment.Config.bHasExports = Config.bAllowExports; // Set the output folder for intermediate files BinaryLinkEnvironment.Config.IntermediateDirectory = Config.IntermediateDirectory; // Put the non-executable output files (PDB, import library, etc) in the same directory as the production BinaryLinkEnvironment.Config.OutputDirectory = Path.GetDirectoryName(Config.OutputFilePaths[0]); // Determine the type of binary we're linking. switch (Config.Type) { case UEBuildBinaryType.DynamicLinkLibrary: BinaryLinkEnvironment.Config.bIsBuildingDLL = true; BinaryLinkEnvironment.Config.bIsBuildingLibrary = false; break; case UEBuildBinaryType.StaticLibrary: BinaryLinkEnvironment.Config.bIsBuildingDLL = false; BinaryLinkEnvironment.Config.bIsBuildingLibrary = true; break; default: BinaryLinkEnvironment.Config.bIsBuildingDLL = false; BinaryLinkEnvironment.Config.bIsBuildingLibrary = false; break; } ; if (ProjectFileGenerator.bGenerateProjectFiles) { // We're generating projects. Since we only need include paths and definitions, there is no need // to go ahead and run through the linking logic. OutputFiles = BinaryLinkEnvironment.InputFiles; } else if (BuildConfiguration.bEnableCodeAnalysis) { // We're only analyzing code, so we won't actually link any executables. Instead, our output // files will simply be the .obj files that were compiled during static analysis. OutputFiles = BinaryLinkEnvironment.InputFiles; } else { if (bCreateImportLibrarySeparately) { // Mark the link environment as cross-referenced. BinaryLinkEnvironment.Config.bIsCrossReferenced = true; if (BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Mac && BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Linux) { // Create the import library. OutputFiles.AddRange(BinaryLinkEnvironment.LinkExecutable(true)); } } BinaryLinkEnvironment.Config.bIncludeDependentLibrariesInLibrary = bIncludeDependentLibrariesInLibrary; // Link the binary. FileItem[] Executables = BinaryLinkEnvironment.LinkExecutable(false); OutputFiles.AddRange(Executables); // Produce additional console app if requested if (BinaryLinkEnvironment.Config.CanProduceAdditionalConsoleApp && UEBuildConfiguration.bBuildEditor) { // Produce additional binary but link it as a console app var ConsoleAppLinkEvironment = BinaryLinkEnvironment.DeepCopy(); ConsoleAppLinkEvironment.Config.bIsBuildingConsoleApplication = true; ConsoleAppLinkEvironment.Config.WindowsEntryPointOverride = "WinMainCRTStartup"; // For WinMain() instead of "main()" for Launch module for (int Index = 0; Index < Config.OutputFilePaths.Length; Index++) { ConsoleAppLinkEvironment.Config.OutputFilePaths[Index] = GetAdditionalConsoleAppPath(ConsoleAppLinkEvironment.Config.OutputFilePaths[Index]); } // Link the console app executable OutputFiles.AddRange(ConsoleAppLinkEvironment.LinkExecutable(false)); } foreach (var Executable in Executables) { OutputFiles.AddRange(TargetToolChain.PostBuild(Executable, BinaryLinkEnvironment)); } } return(OutputFiles); }
private List <FileItem> SetupOutputFiles(IUEToolChain TargetToolChain, ref LinkEnvironment BinaryLinkEnvironment) { // Early exits first if (ProjectFileGenerator.bGenerateProjectFiles) { // We're generating projects. Since we only need include paths and definitions, there is no need // to go ahead and run through the linking logic. return(BinaryLinkEnvironment.InputFiles); } if (BuildConfiguration.bEnableCodeAnalysis) { // We're only analyzing code, so we won't actually link any executables. Instead, our output // files will simply be the .obj files that were compiled during static analysis. return(BinaryLinkEnvironment.InputFiles); } if (BuildConfiguration.bRunUnrealCodeAnalyzer) { // // Create actions to analyze *.includes files and provide suggestions on how to modify PCH. // return(CreateOutputFilesForUCA(BinaryLinkEnvironment)); } // // Regular linking action. // var OutputFiles = new List <FileItem>(); if (bCreateImportLibrarySeparately) { // Mark the link environment as cross-referenced. BinaryLinkEnvironment.Config.bIsCrossReferenced = true; if (BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Mac && BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Linux) { // Create the import library. OutputFiles.AddRange(BinaryLinkEnvironment.LinkExecutable(true)); } } BinaryLinkEnvironment.Config.bIncludeDependentLibrariesInLibrary = bIncludeDependentLibrariesInLibrary; // Link the binary. FileItem[] Executables = BinaryLinkEnvironment.LinkExecutable(false); OutputFiles.AddRange(Executables); // Produce additional console app if requested if (Config.bBuildAdditionalConsoleApp) { // Produce additional binary but link it as a console app var ConsoleAppLinkEvironment = BinaryLinkEnvironment.DeepCopy(); ConsoleAppLinkEvironment.Config.bIsBuildingConsoleApplication = true; ConsoleAppLinkEvironment.Config.WindowsEntryPointOverride = "WinMainCRTStartup"; // For WinMain() instead of "main()" for Launch module ConsoleAppLinkEvironment.Config.OutputFilePaths = ConsoleAppLinkEvironment.Config.OutputFilePaths.Select(Path => GetAdditionalConsoleAppPath(Path)).ToList(); // Link the console app executable OutputFiles.AddRange(ConsoleAppLinkEvironment.LinkExecutable(false)); } foreach (var Executable in Executables) { OutputFiles.AddRange(TargetToolChain.PostBuild(Executable, BinaryLinkEnvironment)); } return(OutputFiles); }
private LinkEnvironment SetupBinaryLinkEnvironment(LinkEnvironment LinkEnvironment, CPPEnvironment CompileEnvironment) { var BinaryLinkEnvironment = LinkEnvironment.DeepCopy(); var LinkEnvironmentVisitedModules = new Dictionary <UEBuildModule, bool>(); var BinaryDependencies = new List <UEBuildBinary>(); CompileEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); CompileEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); var BinaryCompileEnvironment = CompileEnvironment.DeepCopy(); // @Hack: This to prevent UHT from listing CoreUObject.generated.cpp as its dependency. // We flag the compile environment when we build UHT so that we don't need to check // this for each file when generating their dependencies. BinaryCompileEnvironment.bHackHeaderGenerator = (Target.GetAppName() == "UnrealHeaderTool"); // @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. var OriginalFilename = (Config.OriginalOutputFilePaths != null) ? Path.GetFileName(Config.OriginalOutputFilePaths[0]) : Path.GetFileName(Config.OutputFilePaths[0]); BinaryCompileEnvironment.Config.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\""); foreach (var ModuleName in ModuleNames) { var Module = Target.GetModuleByName(ModuleName); List <FileItem> LinkInputFiles; if (Module.Binary == null || Module.Binary == this) { // Compile each module. Log.TraceVerbose("Compile module: " + ModuleName); LinkInputFiles = Module.Compile(CompileEnvironment, BinaryCompileEnvironment); // 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 (var LinkInputFile in LinkInputFiles) { if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile)) { BinaryLinkEnvironment.InputFiles.Add(LinkInputFile); } } } else { BinaryDependencies.Add(Module.Binary); } if (!BuildConfiguration.bRunUnrealCodeAnalyzer) { // Allow the module to modify the link environment for the binary. Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules); } } // Allow the binary dependencies to modify the link environment. foreach (var 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.Config.OutputFilePaths = Config.OutputFilePaths.ToList(); // Set whether the link is allowed to have exports. BinaryLinkEnvironment.Config.bHasExports = Config.bAllowExports; // Set the output folder for intermediate files BinaryLinkEnvironment.Config.IntermediateDirectory = Config.IntermediateDirectory; // Put the non-executable output files (PDB, import library, etc) in the same directory as the production BinaryLinkEnvironment.Config.OutputDirectory = Path.GetDirectoryName(Config.OutputFilePaths[0]); // Setup link output type BinaryLinkEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); BinaryLinkEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); return(BinaryLinkEnvironment); }
private List<FileItem> SetupOutputFiles(IUEToolChain TargetToolChain, ref LinkEnvironment BinaryLinkEnvironment) { // Early exits first if (ProjectFileGenerator.bGenerateProjectFiles) { // We're generating projects. Since we only need include paths and definitions, there is no need // to go ahead and run through the linking logic. return BinaryLinkEnvironment.InputFiles; } if (BuildConfiguration.bEnableCodeAnalysis) { // We're only analyzing code, so we won't actually link any executables. Instead, our output // files will simply be the .obj files that were compiled during static analysis. return BinaryLinkEnvironment.InputFiles; } if (BuildConfiguration.bRunUnrealCodeAnalyzer) { // // Create actions to analyze *.includes files and provide suggestions on how to modify PCH. // return CreateOutputFilesForUCA(BinaryLinkEnvironment); } // // Regular linking action. // var OutputFiles = new List<FileItem>(); if (bCreateImportLibrarySeparately) { // Mark the link environment as cross-referenced. BinaryLinkEnvironment.Config.bIsCrossReferenced = true; if (BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Mac && BinaryLinkEnvironment.Config.Target.Platform != CPPTargetPlatform.Linux) { // Create the import library. OutputFiles.AddRange(BinaryLinkEnvironment.LinkExecutable(true)); } } BinaryLinkEnvironment.Config.bIncludeDependentLibrariesInLibrary = bIncludeDependentLibrariesInLibrary; // Link the binary. FileItem[] Executables = BinaryLinkEnvironment.LinkExecutable(false); OutputFiles.AddRange(Executables); // Produce additional console app if requested if (Config.bBuildAdditionalConsoleApp) { // Produce additional binary but link it as a console app var ConsoleAppLinkEvironment = BinaryLinkEnvironment.DeepCopy(); ConsoleAppLinkEvironment.Config.bIsBuildingConsoleApplication = true; ConsoleAppLinkEvironment.Config.WindowsEntryPointOverride = "WinMainCRTStartup"; // For WinMain() instead of "main()" for Launch module for (int Index = 0; Index < Config.OutputFilePaths.Length; Index++) { ConsoleAppLinkEvironment.Config.OutputFilePaths[Index] = GetAdditionalConsoleAppPath(ConsoleAppLinkEvironment.Config.OutputFilePaths[Index]); } // Link the console app executable OutputFiles.AddRange(ConsoleAppLinkEvironment.LinkExecutable(false)); } foreach (var Executable in Executables) { OutputFiles.AddRange(TargetToolChain.PostBuild(Executable, BinaryLinkEnvironment)); } return OutputFiles; }
private LinkEnvironment SetupBinaryLinkEnvironment(LinkEnvironment LinkEnvironment, CPPEnvironment CompileEnvironment) { var BinaryLinkEnvironment = LinkEnvironment.DeepCopy(); var LinkEnvironmentVisitedModules = new Dictionary<UEBuildModule, bool>(); var BinaryDependencies = new List<UEBuildBinary>(); CompileEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); CompileEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); var BinaryCompileEnvironment = CompileEnvironment.DeepCopy(); // @Hack: This to prevent UHT from listing CoreUObject.generated.cpp as its dependency. // We flag the compile environment when we build UHT so that we don't need to check // this for each file when generating their dependencies. BinaryCompileEnvironment.bHackHeaderGenerator = (Target.GetAppName() == "UnrealHeaderTool"); // @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. var OriginalFilename = (Config.OriginalOutputFilePaths != null) ? Path.GetFileName(Config.OriginalOutputFilePaths[0]) : Path.GetFileName(Config.OutputFilePaths[0]); BinaryCompileEnvironment.Config.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\""); foreach (var ModuleName in ModuleNames) { var Module = Target.GetModuleByName(ModuleName); List<FileItem> LinkInputFiles; if(Module.Binary == null || Module.Binary == this) { // Compile each module. Log.TraceVerbose("Compile module: " + ModuleName); LinkInputFiles = Module.Compile(CompileEnvironment, BinaryCompileEnvironment); // 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 (var LinkInputFile in LinkInputFiles) { if (!BinaryLinkEnvironment.InputFiles.Contains(LinkInputFile)) { BinaryLinkEnvironment.InputFiles.Add(LinkInputFile); } } } else { BinaryDependencies.Add(Module.Binary); } if (!BuildConfiguration.bRunUnrealCodeAnalyzer) { // Allow the module to modify the link environment for the binary. Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules); } } // Allow the binary dependencies to modify the link environment. foreach (var 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.Config.OutputFilePaths = Config.OutputFilePaths != null ? (string[])Config.OutputFilePaths.Clone() : null; // Set whether the link is allowed to have exports. BinaryLinkEnvironment.Config.bHasExports = Config.bAllowExports; // Set the output folder for intermediate files BinaryLinkEnvironment.Config.IntermediateDirectory = Config.IntermediateDirectory; // Put the non-executable output files (PDB, import library, etc) in the same directory as the production BinaryLinkEnvironment.Config.OutputDirectory = Path.GetDirectoryName(Config.OutputFilePaths[0]); // Setup link output type BinaryLinkEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); BinaryLinkEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); return BinaryLinkEnvironment; }
private LinkEnvironment SetupBinaryLinkEnvironment(UEBuildTarget Target, UEToolChain ToolChain, LinkEnvironment LinkEnvironment, CPPEnvironment CompileEnvironment, List <PrecompiledHeaderTemplate> SharedPCHs, ActionGraph ActionGraph) { LinkEnvironment BinaryLinkEnvironment = LinkEnvironment.DeepCopy(); HashSet <UEBuildModule> LinkEnvironmentVisitedModules = new HashSet <UEBuildModule>(); List <UEBuildBinary> BinaryDependencies = new List <UEBuildBinary>(); CompileEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); CompileEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); CPPEnvironment BinaryCompileEnvironment = CompileEnvironment.DeepCopy(); // @Hack: This to prevent UHT from listing CoreUObject.generated.cpp as its dependency. // We flag the compile environment when we build UHT so that we don't need to check // this for each file when generating their dependencies. BinaryCompileEnvironment.bHackHeaderGenerator = (Target.GetAppName() == "UnrealHeaderTool"); // @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 = (Config.OriginalOutputFilePaths != null) ? Config.OriginalOutputFilePaths[0].GetFileName() : Config.OutputFilePaths[0].GetFileName(); BinaryCompileEnvironment.Config.Definitions.Add("ORIGINAL_FILE_NAME=\"" + OriginalFilename + "\""); 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, 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); } if (!BuildConfiguration.bRunUnrealCodeAnalyzer) { // Allow the module to modify the link environment for the binary. Module.SetupPrivateLinkEnvironment(this, BinaryLinkEnvironment, BinaryDependencies, LinkEnvironmentVisitedModules); } } // 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.Config.OutputFilePaths = Config.OutputFilePaths.ToList(); // Set whether the link is allowed to have exports. BinaryLinkEnvironment.Config.bHasExports = Config.bAllowExports; // Set the output folder for intermediate files BinaryLinkEnvironment.Config.IntermediateDirectory = Config.IntermediateDirectory; // Put the non-executable output files (PDB, import library, etc) in the same directory as the production BinaryLinkEnvironment.Config.OutputDirectory = Config.OutputFilePaths[0].Directory; // Setup link output type BinaryLinkEnvironment.Config.bIsBuildingDLL = IsBuildingDll(Config.Type); BinaryLinkEnvironment.Config.bIsBuildingLibrary = IsBuildingLibrary(Config.Type); BinaryLinkEnvironment.Config.ProjectFile = Target.ProjectFile; // Add the default resources for dlls if (Config.Type == UEBuildBinaryType.DynamicLinkLibrary) { // Check if there's already a custom resource file if (!BinaryLinkEnvironment.InputFiles.Any(x => x.Reference.HasExtension(".res"))) { if (UEBuildConfiguration.bFormalBuild) { // For formal builds, compile the default resource file per-binary, so that it gets the correct ORIGINAL_FILE_NAME macro. CPPEnvironment BinaryResourceCompileEnvironment = BinaryCompileEnvironment.DeepCopy(); BinaryResourceCompileEnvironment.Config.OutputDirectory = DirectoryReference.Combine(BinaryResourceCompileEnvironment.Config.OutputDirectory, Modules.First().Name); FileItem DefaultResourceFile = FileItem.GetItemByFileReference(FileReference.Combine(UnrealBuildTool.EngineSourceDirectory, "Runtime", "Launch", "Resources", "Windows", "PCLaunch.rc")); CPPOutput DefaultResourceOutput = ToolChain.CompileRCFiles(BinaryResourceCompileEnvironment, new List <FileItem> { DefaultResourceFile }, ActionGraph); BinaryLinkEnvironment.InputFiles.AddRange(DefaultResourceOutput.ObjectFiles); } else { // For non-formal builds, we just want to share the default resource file between modules BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.DefaultResourceFiles); } } // Add all the common resource files BinaryLinkEnvironment.InputFiles.AddRange(BinaryLinkEnvironment.CommonResourceFiles); } return(BinaryLinkEnvironment); }