// NOTE: If we're building a monolithic binary, then the game and engine code are linked together into one // program executable, so we want the application name to be the game name. In the case of a modular // binary, we use 'UnrealEngine' for our application name public STBuildEditor( string InGameName, STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) : base(InAppName: STBuildTarget.GetBinaryBaseName( InGameName, InRulesObject, InPlatform, InConfiguration, (InRulesObject.Type == TargetRules.TargetType.Editor) ? "Editor" : "" ), InGameName: InGameName, InPlatform: InPlatform, InConfiguration: InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions: InAdditionalDefinitions, InRemoteRoot: InRemoteRoot, InOnlyModules: InOnlyModules, bInEditorRecompile: bInEditorRecompile) { }
/// <summary> /// Allow various platform project generators to generate any special project properties if required /// </summary> /// <param name="InPlatform"></param> /// <returns></returns> public static bool GenerateGamePlatformSpecificProperties(STTargetPlatform InPlatform, STTargetConfiguration Configuration, TargetRules.TargetType TargetType, StringBuilder VCProjectFileContent, string RootDirectory, string TargetFilePath) { if (ProjectGeneratorDictionary.ContainsKey(InPlatform) == true) { ProjectGeneratorDictionary[InPlatform].GenerateGameProperties(Configuration, VCProjectFileContent, TargetType, RootDirectory, TargetFilePath); ; } return true; }
// NOTE: If we're building a monolithic binary, then the game and engine code are linked together into one // program executable, so we want the application name to be the game name. In the case of a modular // binary, we use 'UnrealEngine' for our application name public STBuildClient( string InGameName, STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) : base(InAppName: STBuildTarget.GetBinaryBaseName(InGameName, InRulesObject, InPlatform, InConfiguration, "Client"), InGameName: InGameName, InPlatform: InPlatform, InConfiguration: InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions: InAdditionalDefinitions, InRemoteRoot: InRemoteRoot, InOnlyModules: InOnlyModules, bInEditorRecompile: bInEditorRecompile) { if (ShouldCompileMonolithic()) { if ((STBuildTool.IsDesktopPlatform(Platform) == false) || (Platform == STTargetPlatform.WinRT) || (Platform == STTargetPlatform.WinRT_ARM)) { // We are compiling for a console... // We want the output to go into the <GAME>\Binaries folder if (InRulesObject.bOutputToEngineBinaries == false) { for (int Index = 0; Index < OutputPaths.Length; Index++) { OutputPaths[Index] = OutputPaths[Index].Replace("Engine\\Binaries", InGameName + "\\Binaries"); } } } } }
/** * Gives the platform a chance to 'override' the configuration settings * that are overridden on calls to RunUBT. * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return bool true if debug info should be generated, false if not */ public virtual void ResetBuildConfiguration(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { }
/// <summary> /// The configuration class for a binary build. /// </summary> /// <param name="InType"></param> /// <param name="InOutputFilePath"></param> /// <param name="bInAllowExports"></param> /// <param name="bInCreateImportLibrarySeparately"></param> /// <param name="bInIsCrossTarget">For most binaries, this is false. If this is a cross-platform binary build for a specific platform (for example XB1 DLL for a windows editor) this will be true.</param> /// <param name="InProjectFilePath"></param> /// <param name="InModuleNames"></param> public STBuildBinaryConfiguration( STBuildBinaryType InType, string[] InOutputFilePaths = null, string InIntermediateDirectory = null, bool bInAllowExports = false, bool bInCreateImportLibrarySeparately = false, bool bInIncludeDependentLibrariesInLibrary = false, bool bInAllowCompilation = true, bool bInHasModuleRules = true, bool bInIsCrossTarget = false, bool bInCompileMonolithic = false, STTargetConfiguration InTargetConfiguration = STTargetConfiguration.Development, string InTargetName = "", string InProjectFilePath = "", List<string> InModuleNames = null ) { Type = InType; OutputFilePaths = InOutputFilePaths != null ? (string[])InOutputFilePaths.Clone() : null; IntermediateDirectory = InIntermediateDirectory; bAllowExports = bInAllowExports; bCreateImportLibrarySeparately = bInCreateImportLibrarySeparately; bIncludeDependentLibrariesInLibrary = bInIncludeDependentLibrariesInLibrary; bAllowCompilation = bInAllowCompilation; bHasModuleRules = bInHasModuleRules; bIsCrossTarget = bInIsCrossTarget; bCompileMonolithic = bInCompileMonolithic; TargetConfiguration = InTargetConfiguration; TargetName = InTargetName; ProjectFilePath = InProjectFilePath; ModuleNames = InModuleNames; }
/// /// VisualStudio project generation functions /// /** * Whether this build platform has native support for VisualStudio * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return bool true if native VisualStudio support (or custom VSI) is available */ public virtual bool HasVisualStudioSupport(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { // By default, we assume this is true return true; }
/** * Return the platform toolset string to write into the project configuration * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return string The custom configuration section for the project file; Empty string if it doesn't require one */ public virtual string GetVisualStudioPlatformToolsetString(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, VCProjectFile InProjectFile) { return ""; }
/** * Return any custom layout directory sections * * @param InPlatform The STTargetPlatform being built * @param TargetType The type of target (game or program) * * @return string The custom property import lines for the project file; Empty string if it doesn't require one */ public virtual string GetVisualStudioLayoutDirSection(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, string InConditionString, TargetRules.TargetType TargetType, string TargetRulesPath, string ProjectFilePath) { return ""; }
public virtual void GenerateGameProperties(STTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetRules.TargetType TargetType, string RootDirectory, string TargetFilePath) { // Do nothing }
/** * Whether the editor should be built for this platform or not * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * @return bool true if the editor should be built, false if not */ public override bool ShouldNotBuildEditor(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { return false; }
/** * Whether this platform should create debug information or not * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return bool true if debug info should be generated, false if not */ public override bool ShouldCreateDebugInfo(STTargetPlatform Platform, STTargetConfiguration Configuration) { switch (Configuration) { case STTargetConfiguration.Development: case STTargetConfiguration.Shipping: case STTargetConfiguration.Test: return !BuildConfiguration.bOmitPCDebugInfoInDevelopment; case STTargetConfiguration.DebugGame: case STTargetConfiguration.Debug: default: return true; }; }
public override void ResetBuildConfiguration(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { STBuildConfiguration.bCompileICU = true; // Should we enable Windows XP support { // If it wasnt set as an XML flag, check if it is requested from the commandline. if (!SupportWindowsXPIfAvailable) { string[] CmdLine = Environment.GetCommandLineArgs(); SupportWindowsXPIfAvailable = CmdLine.Contains("-winxp", StringComparer.InvariantCultureIgnoreCase); // ...check if it was supported from a config. if (!SupportWindowsXPIfAvailable) { ConfigCacheIni Ini = new ConfigCacheIni(STTargetPlatform.Win64, "Engine", STBuildTool.GetUProjectPath()); string MinimumOS; if (Ini.GetString("/Script/WindowsTargetPlatform.WindowsTargetSettings", "MinimumOSVersion", out MinimumOS)) { if (string.IsNullOrEmpty(MinimumOS) == false) { SupportWindowsXPIfAvailable = MinimumOS == "MSOS_XP"; } } } } // Win32 XP is only supported at this time. SupportWindowsXP = SupportWindowsXPIfAvailable && (GetCPPTargetPlatform(InPlatform) == CPPTargetPlatform.Win32); } }
public override bool BuildRequiresCookedData(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { return false; }
/** * Whether this platform should create debug information or not * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return bool true if debug info should be generated, false if not */ public abstract bool ShouldCreateDebugInfo(STTargetPlatform Platform, STTargetConfiguration Configuration);
public ProjectConfigAndTargetCombination(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, string InProjectPlatformName, string InProjectConfigurationName, ProjectTarget InProjectTarget) { Platform = InPlatform; Configuration = InConfiguration; ProjectPlatformName = InProjectPlatformName; ProjectConfigurationName = InProjectConfigurationName; ProjectTarget = InProjectTarget; }
/** Constructor */ public STBuildConfig(string InName, STTargetPlatform InPlatform, STTargetConfiguration InConfig) { Name = InName; Platform = InPlatform; Config = InConfig; }
/// <summary> /// Given a target platform and configuration, generates a platform and configuration name string to use in Visual Studio projects. /// Unlike with solution configurations, Visual Studio project configurations only support certain types of platforms, so we'll /// generate a configuration name that has the platform "built in", and use a default platform type /// </summary> /// <param name="Platform">Actual platform</param> /// <param name="Configuration">Actual configuration</param> /// <param name="TargetConfigurationName">The configuration name from the target rules, or null if we don't have one</param> /// <param name="ProjectPlatformName">Name of platform string to use for Visual Studio project</param> /// <param name="ProjectConfigurationName">Name of configuration string to use for Visual Studio project</param> public void MakeProjectPlatformAndConfigurationNames(STTargetPlatform Platform, STTargetConfiguration Configuration, string TargetConfigurationName, out string ProjectPlatformName, out string ProjectConfigurationName) { if (IsStubProject) { if (Platform != STTargetPlatform.Unknown || Configuration != STTargetConfiguration.Unknown) { throw new BuildException("Stub project was expecting platform and configuration type to be set to Unknown"); } ProjectPlatformName = StubProjectPlatformName; ProjectConfigurationName = StubProjectConfigurationName; } else { // If this is a C# project, then the project platform name must always be "Any CPU" if (this is VCSharpProjectFile) { ProjectConfigurationName = Configuration.ToString(); ProjectPlatformName = VCProjectFileGenerator.DotNetPlatformName; } else { var PlatformProjectGenerator = STPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, bInAllowFailure: true); // Check to see if this platform is supported directly by Visual Studio projects. bool HasActualVSPlatform = (PlatformProjectGenerator != null) ? PlatformProjectGenerator.HasVisualStudioSupport(Platform, Configuration) : false; if (HasActualVSPlatform) { // Great! Visual Studio supports this platform natively, so we don't need to make up // a fake project configuration name. // Allow the platform to specify the name used in VisualStudio. // Note that the actual name of the platform on the Visual Studio side may be different than what // STBuildTool calls it (e.g. "Win64" -> "x64".) GetVisualStudioPlatformName() will figure this out. ProjectConfigurationName = Configuration.ToString(); ProjectPlatformName = PlatformProjectGenerator.GetVisualStudioPlatformName(Platform, Configuration); } else { // Visual Studio doesn't natively support this platform, so we fake it by mapping it to // a project configuration that has the platform name in that configuration as a suffix, // and then using "Win32" as the actual VS platform name ProjectConfigurationName = ProjectConfigurationNameOverride == "" ? Platform.ToString() + "_" + Configuration.ToString() : ProjectConfigurationNameOverride; ProjectPlatformName = ProjectPlatformNameOverride == "" ? VCProjectFileGenerator.DefaultPlatformName : ProjectPlatformNameOverride; } if (!String.IsNullOrEmpty(TargetConfigurationName)) { ProjectConfigurationName += "_" + TargetConfigurationName; } } } }
/** * @param InAppName - The name of the application being built, which is used to scope all intermediate and output file names. * @param InGameName - The name of the game being build - can be empty * @param InPlatform - The platform the target is being built for. * @param InConfiguration - The configuration the target is being built for. * @param InAdditionalDefinitions - Additional definitions provided on the UBT command-line for the target. * @param InRemoteRoot - The remote path that the build output is synced to. */ public STBuildTarget( string InAppName, string InGameName, STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) { AppName = InAppName; GameName = InGameName; Platform = InPlatform; Configuration = InConfiguration; Rules = InRulesObject; bEditorRecompile = bInEditorRecompile; { bCompileMonolithic = (Rules != null) ? Rules.ShouldCompileMonolithic(InPlatform, InConfiguration) : false; // Platforms may *require* monolithic compilation... bCompileMonolithic |= STBuildPlatform.PlatformRequiresMonolithicBuilds(InPlatform, InConfiguration); // Force monolithic or modular mode if we were asked to if (STBuildTool.CommandLineContains("-Monolithic") || STBuildTool.CommandLineContains("MONOLITHIC_BUILD=1")) { bCompileMonolithic = true; } else if (STBuildTool.CommandLineContains("-Modular")) { bCompileMonolithic = false; } } // Figure out what the project directory is. If we have a uproject file, use that. Otherwise use the engine directory. if (STBuildTool.HasUProjectFile()) { ProjectDirectory = Path.GetFullPath(STBuildTool.GetUProjectPath()); } else { ProjectDirectory = Path.GetFullPath(BuildConfiguration.RelativeEnginePath); } // Build the project intermediate directory ProjectIntermediateDirectory = Path.GetFullPath(Path.Combine(ProjectDirectory, BuildConfiguration.PlatformIntermediateFolder, GetTargetName(), Configuration.ToString())); // Build the engine intermediate directory. If we're building agnostic engine binaries, we can use the engine intermediates folder. Otherwise we need to use the project intermediates directory. if (ShouldCompileMonolithic()) { EngineIntermediateDirectory = ProjectIntermediateDirectory; } else if (Configuration == STTargetConfiguration.DebugGame) { EngineIntermediateDirectory = Path.GetFullPath(Path.Combine(BuildConfiguration.RelativeEnginePath, BuildConfiguration.PlatformIntermediateFolder, AppName, STTargetConfiguration.Development.ToString())); } else { EngineIntermediateDirectory = Path.GetFullPath(Path.Combine(BuildConfiguration.RelativeEnginePath, BuildConfiguration.PlatformIntermediateFolder, AppName, Configuration.ToString())); } RemoteRoot = InRemoteRoot; OnlyModules = InOnlyModules; TargetTypeOrNull = (Rules != null) ? Rules.Type : (TargetRules.TargetType?)null; // Construct the output path based on configuration, platform, game if not specified. OutputPaths = MakeBinaryPaths("", AppName, STBuildBinaryType.Executable, TargetType, null, AppName, Configuration == STTargetConfiguration.Shipping ? Rules.ForceNameAsForDevelopment() : false, Rules.ExeBinariesSubFolder); for (int Index = 0; Index < OutputPaths.Length; Index++) { OutputPaths[Index] = Path.GetFullPath(OutputPaths[Index]); } if (bCompileMonolithic && TargetRules.IsGameType(InRulesObject.Type)) { // For Rocket, UE4Game.exe and UE4Editor.exe still go into Engine/Binaries/<PLATFORM> if (!InRulesObject.bOutputToEngineBinaries) { // We are compiling a monolithic game... // We want the output to go into the <GAME>\Binaries folder if (STBuildTool.HasUProjectFile() == false) { for (int Index = 0; Index < OutputPaths.Length; Index++) { OutputPaths[Index] = OutputPaths[Index].Replace(Path.Combine("Engine", "Binaries"), Path.Combine(InGameName, "Binaries")); } } else { string EnginePath = Path.GetFullPath(Path.Combine(ProjectFileGenerator.EngineRelativePath, "Binaries")); string UProjectPath = STBuildTool.GetUProjectPath(); if (Path.IsPathRooted(UProjectPath) == false) { string FilePath = UProjectInfo.GetProjectForTarget(InGameName); string FullPath = Path.GetFullPath(FilePath); UProjectPath = Path.GetDirectoryName(FullPath); } string ProjectPath = Path.GetFullPath(Path.Combine(UProjectPath, "Binaries")); for (int Index = 0; Index < OutputPaths.Length; Index++) { OutputPaths[Index] = OutputPaths[Index].Replace(EnginePath, ProjectPath); } } } } // handle some special case defines (so build system can pass -DEFINE as normal instead of needing // to know about special parameters) foreach (string Define in InAdditionalDefinitions) { switch (Define) { case "WITH_EDITOR=0": STBuildConfiguration.bBuildEditor = false; break; case "WITH_EDITORONLY_DATA=0": STBuildConfiguration.bBuildWithEditorOnlyData = false; break; // Memory profiler doesn't work if frame pointers are omitted case "USE_MALLOC_PROFILER=1": BuildConfiguration.bOmitFramePointers = false; break; case "WITH_LEAN_AND_MEAN_UE=1": STBuildConfiguration.bCompileLeanAndMeanUE = true; break; } } // Add the definitions specified on the command-line. GlobalCompileEnvironment.Config.Definitions.AddRange(InAdditionalDefinitions); }
/** * Get whether this platform deploys * * @return bool true if the 'Deploy' option should be enabled */ public virtual bool GetVisualStudioDeploymentEnabled(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { return false; }
/// <summary> /// /// </summary> /// <param name="InGameName"></param> /// <param name="InRulesObject"></param> /// <param name="InPlatform"></param> /// <param name="InConfiguration"></param> /// <returns></returns> public static string GetBinaryBaseName(string InGameName, TargetRules InRulesObject, STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, string InNameAppend) { //@todo. Allow failure to get build platform here? bool bPlatformRequiresMonolithic = false; var BuildPlatform = STBuildPlatform.GetBuildPlatform(InPlatform, true); if (BuildPlatform != null) { bPlatformRequiresMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(InPlatform); } if (InRulesObject.ShouldCompileMonolithic(InPlatform, InConfiguration) || bPlatformRequiresMonolithic) { return InGameName; } else { return "UE4" + InNameAppend; } }
/** * Return any custom paths for VisualStudio this platform requires * This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath. * * @param InPlatform The STTargetPlatform being built * @param TargetType The type of target (game or program) * * @return string The custom path lines for the project file; Empty string if it doesn't require one */ public virtual string GetVisualStudioPathsEntries(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, TargetRules.TargetType TargetType, string TargetRulesPath, string ProjectFilePath, string NMakeOutputPath) { // NOTE: We are intentionally overriding defaults for these paths with empty strings. We never want Visual Studio's // defaults for these fields to be propagated, since they are version-sensitive paths that may not reflect // the environment that UBT is building in. We'll set these environment variables ourselves! // NOTE: We don't touch 'ExecutablePath' because that would result in Visual Studio clobbering the system "Path" // environment variable string PathsLines = " <IncludePath />\n" + " <ReferencePath />\n" + " <LibraryPath />\n" + " <LibraryWPath />\n" + " <SourcePath />\n" + " <ExcludePath />\n"; return PathsLines; }
/** Given a UBT-built binary name (e.g. "Core"), returns a relative path to the binary for the current build configuration (e.g. "../Binaries/Win64/Core-Win64-Debug.lib") */ public static string[] MakeBinaryPaths(string ModuleName, string BinaryName, STTargetPlatform Platform, STTargetConfiguration Configuration, STBuildBinaryType BinaryType, TargetRules.TargetType? TargetType, PluginInfo PluginInfo, string AppName, bool bForceNameAsForDevelopment = false, string ExeBinariesSubFolder = null) { // Determine the binary extension for the platform and binary type. var BuildPlatform = STBuildPlatform.GetBuildPlatform(Platform); string BinaryExtension; if (!BuildConfiguration.bRunUnrealCodeAnalyzer) { BinaryExtension = BuildPlatform.GetBinaryExtension(BinaryType); } else { BinaryExtension = @"-" + BuildConfiguration.UCAModuleToAnalyze + @".analysis"; } STTargetConfiguration LocalConfig = Configuration; if (Configuration == STTargetConfiguration.DebugGame && !String.IsNullOrEmpty(ModuleName) && !RulesCompiler.IsGameModule(ModuleName)) { LocalConfig = STTargetConfiguration.Development; } string ModuleBinariesSubDir = ""; if (BinaryType == STBuildBinaryType.DynamicLinkLibrary && (string.IsNullOrEmpty(ModuleName) == false)) { // Allow for modules to specify sub-folders in the Binaries folder var RulesFilename = RulesCompiler.GetModuleFilename(ModuleName); // Plugins can be binary-only and can have no rules object if (PluginInfo == null || !String.IsNullOrEmpty(RulesFilename)) { ModuleRules ModuleRulesObj = RulesCompiler.CreateModuleRules(ModuleName, new TargetInfo(Platform, Configuration, TargetType), out RulesFilename); if (ModuleRulesObj != null) { ModuleBinariesSubDir = ModuleRulesObj.BinariesSubFolder; } } } else if (BinaryType == STBuildBinaryType.Executable && string.IsNullOrEmpty(ExeBinariesSubFolder) == false) { ModuleBinariesSubDir = ExeBinariesSubFolder; } //@todo.Rocket: This just happens to work since exp and lib files go into intermediate... // Build base directory string ("../Binaries/<Platform>/") string BinariesDirName; if (TargetType.HasValue && TargetType.Value == TargetRules.TargetType.Program && STBuildTool.HasUProjectFile() && !ProjectFileGenerator.bGenerateProjectFiles) { BinariesDirName = Path.Combine(STBuildTool.GetUProjectPath(), "Binaries"); } else if (PluginInfo != null) { BinariesDirName = Path.Combine(PluginInfo.Directory, "Binaries"); } else { BinariesDirName = Path.Combine("..", "Binaries"); } var BaseDirectory = Path.Combine(BinariesDirName, Platform.ToString()); if (ModuleBinariesSubDir.Length > 0) { BaseDirectory = Path.Combine(BaseDirectory, ModuleBinariesSubDir); } string BinarySuffix = ""; if ((PluginInfo != null) && (BinaryType != STBuildBinaryType.DynamicLinkLibrary)) { BinarySuffix = "-Static"; } // append the architecture to the end of the binary name BinarySuffix = BuildPlatform.ApplyArchitectureName(BinarySuffix); string OutBinaryPath = ""; // Append binary file name string Prefix = ""; if (Platform == STTargetPlatform.Linux && (BinaryType == STBuildBinaryType.DynamicLinkLibrary || BinaryType == STBuildBinaryType.StaticLibrary)) { Prefix = "lib"; } if (LocalConfig == STTargetConfiguration.Development || bForceNameAsForDevelopment) { OutBinaryPath = Path.Combine(BaseDirectory, String.Format("{3}{0}{1}{2}", BinaryName, BinarySuffix, BinaryExtension, Prefix)); } else { OutBinaryPath = Path.Combine(BaseDirectory, String.Format("{5}{0}-{1}-{2}{3}{4}", BinaryName, Platform.ToString(), LocalConfig.ToString(), BinarySuffix, BinaryExtension, Prefix)); } return BuildPlatform.FinalizeBinaryPaths(OutBinaryPath); }
/** * Return the VisualStudio platform name for this build platform * * @param InPlatform The STTargetPlatform being built * @param InConfiguration The STTargetConfiguration being built * * @return string The name of the platform that VisualStudio recognizes */ public virtual string GetVisualStudioPlatformName(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { // By default, return the platform string return InPlatform.ToString(); }
/// Parses only the target platform and configuration from the specified command-line argument list public static void ParsePlatformAndConfiguration(string[] SourceArguments, out STTargetPlatform Platform, out STTargetConfiguration Configuration, bool bThrowExceptionOnFailure = true) { Platform = STTargetPlatform.Unknown; Configuration = STTargetConfiguration.Unknown; foreach (var CurArgument in SourceArguments) { STTargetPlatform ParsedPlatform = STBuildPlatform.ConvertStringToPlatform(CurArgument); if (ParsedPlatform != STTargetPlatform.Unknown) { Platform = ParsedPlatform; } else { switch (CurArgument.ToUpperInvariant()) { // Configuration names: case "DEBUG": Configuration = STTargetConfiguration.Debug; break; case "DEBUGGAME": Configuration = STTargetConfiguration.DebugGame; break; case "DEVELOPMENT": Configuration = STTargetConfiguration.Development; break; case "SHIPPING": Configuration = STTargetConfiguration.Shipping; break; case "TEST": Configuration = STTargetConfiguration.Test; break; case "-PROJECTFILES": // Force platform to Win64 and configuration to Development for building IntelliSense files Platform = STTargetPlatform.Win64; Configuration = STTargetConfiguration.Development; break; case "-XCODEPROJECTFILE": // @todo Mac: Don't want to force a platform/config for generated projects, in case they affect defines/includes (each project's individual configuration should be generated with correct settings) // Force platform to Mac and configuration to Development for building IntelliSense files Platform = STTargetPlatform.Mac; Configuration = STTargetConfiguration.Development; break; case "-MAKEFILE": // Force platform to Linux and configuration to Development for building IntelliSense files Platform = STTargetPlatform.Linux; Configuration = STTargetConfiguration.Development; break; case "-CMAKEFILE": // Force platform to Linux and configuration to Development for building IntelliSense files Platform = STTargetPlatform.Linux; Configuration = STTargetConfiguration.Development; break; case "-QMAKEFILE": // Force platform to Linux and configuration to Development for building IntelliSense files Platform = STTargetPlatform.Linux; Configuration = STTargetConfiguration.Development; break; } } } if (bThrowExceptionOnFailure == true) { if (Platform == STTargetPlatform.Unknown) { throw new BuildException("Couldn't find platform name."); } if (Configuration == STTargetConfiguration.Unknown) { throw new BuildException("Couldn't determine configuration name."); } } }
/// <summary> /// Get the text to insert into the user file for the given platform/configuration/target /// </summary> /// <param name="InPlatform">The platform being added</param> /// <param name="InConfiguration">The configuration being added</param> /// <param name="InConditionString">The condition string </param> /// <param name="InTargetRules">The target rules </param> /// <param name="TargetRulesPath">The target rules path</param> /// <param name="ProjectFilePath">The project file path</param> /// <returns>The string to append to the user file</returns> public virtual string GetVisualStudioUserFileStrings(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration, string InConditionString, TargetRules InTargetRules, string TargetRulesPath, string ProjectFilePath) { return ""; }
public static List<TargetDescriptor> ParseTargetCommandLine(string[] SourceArguments) { var Targets = new List<TargetDescriptor>(); string TargetName = null; var AdditionalDefinitions = new List<string>(); var Platform = STTargetPlatform.Unknown; var Configuration = STTargetConfiguration.Unknown; string RemoteRoot = null; var OnlyModules = new List<OnlyModule>(); // If true, the recompile was launched by the editor. bool bIsEditorRecompile = false; // Combine the two arrays of arguments List<string> Arguments = new List<string>(SourceArguments.Length); Arguments.AddRange(SourceArguments); List<string> PossibleTargetNames = new List<string>(); for (int ArgumentIndex = 0; ArgumentIndex < Arguments.Count; ArgumentIndex++) { STTargetPlatform ParsedPlatform = STBuildPlatform.ConvertStringToPlatform(Arguments[ArgumentIndex]); if (ParsedPlatform != STTargetPlatform.Unknown) { Platform = ParsedPlatform; } else { switch (Arguments[ArgumentIndex].ToUpperInvariant()) { // @todo ubtmake: How does this work with UBTMake? Do we even need to support it anymore? case "-MODULE": // Specifies a module to recompile. Can be specified more than once on the command-line to compile multiple specific modules. { if (ArgumentIndex + 1 >= Arguments.Count) { throw new BuildException("Expected module name after -Module argument, but found nothing."); } var OnlyModuleName = Arguments[++ArgumentIndex]; OnlyModules.Add(new OnlyModule(OnlyModuleName)); } break; case "-MODULEWITHSUFFIX": { // Specifies a module name to compile along with a suffix to append to the DLL file name. Can be specified more than once on the command-line to compile multiple specific modules. if (ArgumentIndex + 2 >= Arguments.Count) { throw new BuildException("Expected module name and module suffix -ModuleWithSuffix argument"); } var OnlyModuleName = Arguments[++ArgumentIndex]; var OnlyModuleSuffix = Arguments[++ArgumentIndex]; OnlyModules.Add(new OnlyModule(OnlyModuleName, OnlyModuleSuffix)); } break; // Configuration names: case "DEBUG": Configuration = STTargetConfiguration.Debug; break; case "DEBUGGAME": Configuration = STTargetConfiguration.DebugGame; break; case "DEVELOPMENT": Configuration = STTargetConfiguration.Development; break; case "SHIPPING": Configuration = STTargetConfiguration.Shipping; break; case "TEST": Configuration = STTargetConfiguration.Test; break; // -Define <definition> adds a definition to the global C++ compilation environment. case "-DEFINE": if (ArgumentIndex + 1 >= Arguments.Count) { throw new BuildException("Expected path after -define argument, but found nothing."); } ArgumentIndex++; AdditionalDefinitions.Add(Arguments[ArgumentIndex]); break; // -RemoteRoot <RemoteRoot> sets where the generated binaries are CookerSynced. case "-REMOTEROOT": if (ArgumentIndex + 1 >= Arguments.Count) { throw new BuildException("Expected path after -RemoteRoot argument, but found nothing."); } ArgumentIndex++; if (Arguments[ArgumentIndex].StartsWith("xe:\\") == true) { RemoteRoot = Arguments[ArgumentIndex].Substring("xe:\\".Length); } else if (Arguments[ArgumentIndex].StartsWith("devkit:\\") == true) { RemoteRoot = Arguments[ArgumentIndex].Substring("devkit:\\".Length); } break; // Disable editor support case "-NOEDITOR": STBuildConfiguration.bBuildEditor = false; break; case "-NOEDITORONLYDATA": STBuildConfiguration.bBuildWithEditorOnlyData = false; break; case "-DEPLOY": // Does nothing at the moment... break; case "-PROJECTFILES": { // Force platform to Win64 for building IntelliSense files Platform = STTargetPlatform.Win64; // Force configuration to Development for IntelliSense Configuration = STTargetConfiguration.Development; } break; case "-XCODEPROJECTFILE": { // @todo Mac: Don't want to force a platform/config for generated projects, in case they affect defines/includes (each project's individual configuration should be generated with correct settings) // Force platform to Mac for building IntelliSense files Platform = STTargetPlatform.Mac; // Force configuration to Development for IntelliSense Configuration = STTargetConfiguration.Development; } break; case "-MAKEFILE": { // Force platform to Linux for building IntelliSense files Platform = STTargetPlatform.Linux; // Force configuration to Development for IntelliSense Configuration = STTargetConfiguration.Development; } break; case "-CMAKEFILE": { // Force platform to Linux for building IntelliSense files Platform = STTargetPlatform.Linux; // Force configuration to Development for IntelliSense Configuration = STTargetConfiguration.Development; } break; case "-QMAKEFILE": { // Force platform to Linux for building IntelliSense files Platform = STTargetPlatform.Linux; // Force configuration to Development for IntelliSense Configuration = STTargetConfiguration.Development; } break; case "-EDITORRECOMPILE": { bIsEditorRecompile = true; } break; default: PossibleTargetNames.Add(Arguments[ArgumentIndex]); break; } } } if (Platform == STTargetPlatform.Unknown) { throw new BuildException("Couldn't find platform name."); } if (Configuration == STTargetConfiguration.Unknown) { throw new BuildException("Couldn't determine configuration name."); } if (PossibleTargetNames.Count > 0) { // We have possible targets! foreach (string PossibleTargetName in PossibleTargetNames) { // If running Rocket, the PossibleTargetName could contain a path TargetName = PossibleTargetName; // If a project file was not specified see if we can find one string CheckProjectFile = UProjectInfo.GetProjectForTarget(TargetName); if (string.IsNullOrEmpty(CheckProjectFile) == false) { Log.TraceVerbose("Found project file for {0} - {1}", TargetName, CheckProjectFile); if (STBuildTool.HasUProjectFile() == false) { string NewProjectFilename = CheckProjectFile; if (Path.IsPathRooted(NewProjectFilename) == false) { NewProjectFilename = Path.GetFullPath(NewProjectFilename); } NewProjectFilename = NewProjectFilename.Replace("\\", "/"); STBuildTool.SetProjectFile(NewProjectFilename); } } if (STBuildTool.HasUProjectFile()) { if (TargetName.Contains("/") || TargetName.Contains("\\")) { // Parse off the path TargetName = Path.GetFileNameWithoutExtension(TargetName); } } Targets.Add(new TargetDescriptor() { TargetName = TargetName, Platform = Platform, Configuration = Configuration, AdditionalDefinitions = AdditionalDefinitions, bIsEditorRecompile = bIsEditorRecompile, RemoteRoot = RemoteRoot, OnlyModules = OnlyModules }); break; } } if (Targets.Count == 0) { throw new BuildException("No target name was specified on the command-line."); } return Targets; }
/** * Find all third party and private header includes in public engine headers. **/ public static void FindThirdPartyIncludes(STTargetPlatform Platform, STTargetConfiguration Configuration) { Log.TraceInformation("Looking for third party header includes in public engine header files (this may take a few minutes)..."); TargetInfo Target = new TargetInfo(Platform, Configuration); List<string> UncheckedModules = new List<string>(); EngineHeaders = new List<Header>(); ThirdPartyHeaders = new List<Header>(); // Find all modules referenced by the current target List<string> ModuleFileNames = RulesCompiler.FindAllRulesSourceFiles(RulesCompiler.RulesFileType.Module, AdditionalSearchPaths: null); foreach (string ModuleFileName in ModuleFileNames) { string ModuleName = Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(ModuleFileName)); try { string UnusedModuleFilename; ModuleRules RulesObject = RulesCompiler.CreateModuleRules(ModuleName, Target, out UnusedModuleFilename); bool bEngineHeaders = RulesObject.Type != ModuleRules.ModuleType.External; foreach (string SystemIncludePath in RulesObject.PublicSystemIncludePaths) { FindHeaders(SystemIncludePath, bEngineHeaders ? EngineHeaders : ThirdPartyHeaders, bEngineHeaders); } foreach (string PublicIncludePath in RulesObject.PublicIncludePaths) { FindHeaders(PublicIncludePath, bEngineHeaders ? EngineHeaders : ThirdPartyHeaders, bEngineHeaders); } } catch (Exception) { // Ignore, some modules may fail here. UncheckedModules.Add(ModuleName); } } // Search for illegal includes. List<IncludePath> ThirdPartyIncludes = new List<IncludePath>(); List<IncludePath> PrivateIncludes = new List<IncludePath>(); CheckIfThirdPartyHeadersAreIncluded(ThirdPartyIncludes, PrivateIncludes); // List all of the included 3rd party headers unless their name matches with any of the engine header. if (ThirdPartyIncludes.Count > 0) { // Remove ambiguous headers for (int IncludeIndex = ThirdPartyIncludes.Count - 1; IncludeIndex >= 0; --IncludeIndex) { if (FindHeader(EngineHeaders, ThirdPartyIncludes[IncludeIndex].OtherHeader.Name) != null) { ThirdPartyIncludes.RemoveAt(IncludeIndex); } } if (ThirdPartyIncludes.Count > 0) { Log.TraceInformation("Warning: Found {0} third party header includes in public engine headers. Third party headers should only be included in private engine headers.", ThirdPartyIncludes.Count); foreach (IncludePath HeaderPath in ThirdPartyIncludes) { if (FindHeader(EngineHeaders, HeaderPath.OtherHeader.Name) == null) { Log.TraceInformation("{0} includes {1}.", HeaderPath.PublicHeaderPath, HeaderPath.OtherHeader.Path); } } } } // List all private engine headers included from public engine headers if (PrivateIncludes.Count > 0) { Log.TraceInformation("Warning: Found {0} private engine header includes in public engine headers. Private engine headers should not be included in public engine headers.", PrivateIncludes.Count); } foreach (IncludePath HeaderPath in PrivateIncludes) { Log.TraceInformation("{0} includes {1}.", HeaderPath.PublicHeaderPath, HeaderPath.OtherHeader.Path); } if (PrivateIncludes.Count == 0 && ThirdPartyIncludes.Count == 0) { Log.TraceInformation("Finished looking for third party includes. Nothing found."); } if (UncheckedModules.Count > 0) { Log.TraceInformation("Warning: The following modules could not be checked (exception while trying to create ModuleRules object):"); for (int ModuleIndex = 0; ModuleIndex < UncheckedModules.Count; ++ModuleIndex) { Log.TraceInformation(" {0}", UncheckedModules[ModuleIndex]); } } }
/// <summary> /// Checks to see if the specified solution platform and configuration is able to map to this project /// </summary> /// <param name="ProjectTarget">The target that we're checking for a valid platform/config combination</param> /// <param name="Platform">Platform</param> /// <param name="Configuration">Configuration</param> /// <returns>True if this is a valid combination for this project, otherwise false</returns> public static bool IsValidProjectPlatformAndConfiguration(ProjectTarget ProjectTarget, STTargetPlatform Platform, STTargetConfiguration Configuration) { var PlatformProjectGenerator = STPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true); if (PlatformProjectGenerator == null) { return false; } var BuildPlatform = STBuildPlatform.GetBuildPlatform(Platform, true); if (BuildPlatform == null) { return false; } if (BuildPlatform.HasRequiredSDKsInstalled() != SDKStatus.Valid) { return false; } var SupportedConfigurations = new List<STTargetConfiguration>(); var SupportedPlatforms = new List<STTargetPlatform>(); if (!ProjectFileGenerator.bCreateDummyConfigsForUnsupportedPlatforms || ProjectFileGenerator.bGeneratingRocketProjectFiles) { if (ProjectTarget.TargetRules != null) { ProjectTarget.TargetRules.GetSupportedPlatforms(ref SupportedPlatforms); } } else { STBuildTool.GetAllPlatforms(ref SupportedPlatforms); } bool bIncludeTestAndShippingConfigs = ProjectFileGenerator.bIncludeTestAndShippingConfigs || ProjectFileGenerator.bGeneratingRocketProjectFiles; if (ProjectTarget.TargetRules != null) { // Rocket projects always get shipping configs ProjectTarget.TargetRules.GetSupportedConfigurations(ref SupportedConfigurations, bIncludeTestAndShippingConfigs: bIncludeTestAndShippingConfigs); } // Add all of the extra platforms/configurations for this target { foreach (var ExtraPlatform in ProjectTarget.ExtraSupportedPlatforms) { if (!SupportedPlatforms.Contains(ExtraPlatform)) { SupportedPlatforms.Add(ExtraPlatform); } } foreach (var ExtraConfig in ProjectTarget.ExtraSupportedConfigurations) { if (bIncludeTestAndShippingConfigs || (ExtraConfig != STTargetConfiguration.Shipping && ExtraConfig != STTargetConfiguration.Test)) { if (!SupportedConfigurations.Contains(ExtraConfig)) { SupportedConfigurations.Add(ExtraConfig); } } } } // Only build for supported platforms if (SupportedPlatforms.Contains(Platform) == false) { return false; } // Only build for supported configurations if (SupportedConfigurations.Contains(Configuration) == false) { return false; } // For Rocket projects, we currently only allow 64-bit versions of Debug and Development binaries to be compiled // and only 32-bit versions of Shipping binaries to be compiled. This has to do with our choice of which build // configurations we want to ship with that product. So to simplify things, we're merging Win32 and Win64 // configurations together in the IDE under "Windows". In order for this to work properly, we need to make // sure that Rocket projects only report the respective Windows platform that is valid for each configuration if (STBuildTool.RunningRocket() && ProjectTarget.TargetRules != null) { if (Platform == STTargetPlatform.Win32 || Platform == STTargetPlatform.Win64) { // In Rocket, shipping game targets are always 32-bit if (Configuration == STTargetConfiguration.Shipping && ProjectTarget.TargetRules.Type == TargetRules.TargetType.Game) { if (Platform != STTargetPlatform.Win32) { return false; } } else { // Everything else is expecting to be 64-bit if (Platform != STTargetPlatform.Win64) { return false; } } } } return true; }
/// <summary> /// Is this a valid configuration /// Used primarily for Rocket vs non-Rocket /// </summary> /// <param name="InConfiguration"></param> /// <returns>true if valid, false if not</returns> public static bool IsValidConfiguration(STTargetConfiguration InConfiguration) { if (RunningRocket()) { if ( (InConfiguration != STTargetConfiguration.Development) && (InConfiguration != STTargetConfiguration.DebugGame) && (InConfiguration != STTargetConfiguration.Shipping) ) { return false; } } return true; }
/// <summary> /// Return whether the given platform requires a monolithic build /// </summary> /// <param name="InPlatform">The platform of interest</param> /// <param name="InConfiguration">The configuration of interest</param> /// <returns></returns> public static bool PlatformRequiresMonolithicBuilds(STTargetPlatform InPlatform, STTargetConfiguration InConfiguration) { // Some platforms require monolithic builds... var BuildPlatform = GetBuildPlatform(InPlatform, true); if (BuildPlatform != null) { return BuildPlatform.ShouldCompileMonolithicBinary(InPlatform); } // We assume it does not return false; }