static void AddPluginToAgenda(UE4Build.BuildAgenda Agenda, string PluginFileName, PluginDescriptor Plugin, string TargetName, TargetRules.TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List<string> ReceiptFileNames, string InAdditionalArgs) { // Find a list of modules that need to be built for this plugin List<string> ModuleNames = new List<string>(); foreach(ModuleDescriptor Module in Plugin.Modules) { bool bBuildDeveloperTools = (TargetType == TargetRules.TargetType.Editor || TargetType == TargetRules.TargetType.Program); bool bBuildEditor = (TargetType == TargetRules.TargetType.Editor); if(Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor)) { ModuleNames.Add(Module.Name); } } // Add these modules to the build agenda if(ModuleNames.Count > 0) { string Arguments = String.Format("-plugin {0}", CommandUtils.MakePathSafeToUseWithCommandLine(PluginFileName)); foreach(string ModuleName in ModuleNames) { Arguments += String.Format(" -module {0}", ModuleName); } string ReceiptFileName = BuildReceipt.GetDefaultPath(Path.GetDirectoryName(PluginFileName), TargetName, Platform, Configuration, ""); Arguments += String.Format(" -receipt {0}", CommandUtils.MakePathSafeToUseWithCommandLine(ReceiptFileName)); ReceiptFileNames.Add(ReceiptFileName); if(!String.IsNullOrEmpty(InAdditionalArgs)) { Arguments += InAdditionalArgs; } Agenda.AddTarget(TargetName, Platform, Configuration, InAddArgs: Arguments); } }
public UEBuildServer( string InGameName, UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) // 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 : base( InAppName:UEBuildTarget.GetBinaryBaseName(InGameName, InRulesObject, InPlatform, InConfiguration, "Server"), InGameName:InGameName, InPlatform:InPlatform, InConfiguration:InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions:InAdditionalDefinitions, InRemoteRoot:InRemoteRoot, InOnlyModules:InOnlyModules, bInEditorRecompile: bInEditorRecompile ) { }
// 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 UEBuildEditor( string InGameName, UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) : base(InAppName:UEBuildTarget.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) { }
// 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 UEBuildClient( string InGameName, UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules) : base(InAppName: UEBuildTarget.GetBinaryBaseName(InGameName, InRulesObject, InPlatform, InConfiguration, "Client"), InGameName: InGameName, InPlatform: InPlatform, InConfiguration: InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions: InAdditionalDefinitions, InRemoteRoot: InRemoteRoot, InOnlyModules: InOnlyModules) { if (ShouldCompileMonolithic()) { if ((UnrealBuildTool.IsDesktopPlatform(Platform) == false) || (Platform == UnrealTargetPlatform.WinRT) || (Platform == UnrealTargetPlatform.WinRT_ARM)) { // We are compiling for a console... // We want the output to go into the <GAME>\Binaries folder if (InRulesObject.bOutputToEngineBinaries == false) { OutputPath = OutputPath.Replace("Engine\\Binaries", InGameName + "\\Binaries"); } } } }
/// <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(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration 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; }
public InstalledPlatformConfiguration(UnrealTargetConfiguration InConfiguration, UnrealTargetPlatform InPlatform, TargetRules.TargetType InPlatformType, string InArchitecture, string InRequiredFile, EProjectType InProjectType, bool bInCanBeDisplayed) { Configuration = InConfiguration; Platform = InPlatform; PlatformType = InPlatformType; Architecture = InArchitecture; RequiredFile = InRequiredFile; ProjectType = InProjectType; bCanBeDisplayed = bInCanBeDisplayed; }
/// <summary> /// Constructs a TargetInfo /// </summary> /// <param name="InitPlatform">Target platform</param> /// <param name="InitConfiguration">Target build configuration</param> public TargetInfo( UnrealTargetPlatform InitPlatform, UnrealTargetConfiguration InitConfiguration, TargetRules.TargetType? InitType = null ) { Platform = InitPlatform; Configuration = InitConfiguration; Type = InitType; // get the platform's architecture var BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform); Architecture = BuildPlatform.GetActiveArchitecture(); }
/// <summary> /// Allow various platform project generators to generate stub projects if required /// </summary> /// <param name="InTargetName"></param> /// <param name="InTargetFilepath"></param> /// <returns></returns> public static bool GenerateGameProjectStubs(ProjectFileGenerator InGenerator, string InTargetName, string InTargetFilepath, TargetRules InTargetRules, List<UnrealTargetPlatform> InPlatforms, List<UnrealTargetConfiguration> InConfigurations) { foreach (KeyValuePair<UnrealTargetPlatform, UEPlatformProjectGenerator> Entry in ProjectGeneratorDictionary) { UEPlatformProjectGenerator ProjGen = Entry.Value; ProjGen.GenerateGameProjectStub(InGenerator, InTargetName, InTargetFilepath, InTargetRules, InPlatforms, InConfigurations); } return true; }
/** * Return any custom paths for VisualStudio this platform requires * This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath. * * @param InPlatform The UnrealTargetPlatform 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 override string GetVisualStudioPathsEntries(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules.TargetType TargetType, string TargetRulesPath, string ProjectFilePath, string NMakeOutputPath) { if (!IsNsightInstalled()) { return base.GetVisualStudioPathsEntries(InPlatform, InConfiguration, TargetType, TargetRulesPath, ProjectFilePath, 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 //@todo android: clean up debug path generation string GameName = Path.GetFileNameWithoutExtension(TargetRulesPath); GameName = Path.GetFileNameWithoutExtension(GameName); // intermediate path for Engine or Game's intermediate string IntermediateDirectoryPath; IntermediateDirectoryPath = Path.GetDirectoryName(NMakeOutputPath) + "/../../Intermediate/Android/APK"; // string for <OverrideAPKPath> string APKPath = Path.Combine( Path.GetDirectoryName(NMakeOutputPath), Path.GetFileNameWithoutExtension(NMakeOutputPath) + "-armv7-es2.apk"); // string for <BuildXmlPath> and <AndroidManifestPath> string BuildXmlPath = IntermediateDirectoryPath; string AndroidManifestPath = Path.Combine(IntermediateDirectoryPath, "AndroidManifest.xml"); // string for <AdditionalLibraryDirectories> string AdditionalLibDirs = ""; AdditionalLibDirs += IntermediateDirectoryPath + @"\obj\local\armeabi-v7a"; AdditionalLibDirs += ";" + IntermediateDirectoryPath + @"\obj\local\x86"; AdditionalLibDirs += @";$(AdditionalLibraryDirectories)"; string PathsLines = " <IncludePath />" + ProjectFileGenerator.NewLine + " <ReferencePath />" + ProjectFileGenerator.NewLine + " <LibraryPath />" + ProjectFileGenerator.NewLine + " <LibraryWPath />" + ProjectFileGenerator.NewLine + " <SourcePath />" + ProjectFileGenerator.NewLine + " <ExcludePath />" + ProjectFileGenerator.NewLine + " <AndroidAttach>False</AndroidAttach>" + ProjectFileGenerator.NewLine + " <DebuggerFlavor>AndroidDebugger</DebuggerFlavor>" + ProjectFileGenerator.NewLine + " <OverrideAPKPath>" + APKPath + "</OverrideAPKPath>" + ProjectFileGenerator.NewLine + " <AdditionalLibraryDirectories>" + AdditionalLibDirs + "</AdditionalLibraryDirectories>" + ProjectFileGenerator.NewLine + " <BuildXmlPath>" + BuildXmlPath + "</BuildXmlPath>" + ProjectFileGenerator.NewLine + " <AndroidManifestPath>" + AndroidManifestPath + "</AndroidManifestPath>" + ProjectFileGenerator.NewLine; return PathsLines; }
public UEBuildClient(TargetDescriptor InDesc, TargetRules InRulesObject, string InTargetCsFilename) : base(InDesc, InRulesObject, "UE4Client", InTargetCsFilename) { if (ShouldCompileMonolithic()) { if (!UnrealBuildTool.IsDesktopPlatform(Platform) || Platform == UnrealTargetPlatform.WinRT || Platform == UnrealTargetPlatform.WinRT_ARM) { // We are compiling for a console... // We want the output to go into the <GAME>\Binaries folder if (!InRulesObject.bOutputToEngineBinaries) { OutputPaths = OutputPaths.Select(Path => Path.Replace("Engine\\Binaries", InDesc.TargetName + "\\Binaries")).ToList(); } } } }
public UEBuildClient(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Client", InTargetCsFilename) { if (ShouldCompileMonolithic()) { if (!UnrealBuildTool.IsDesktopPlatform(Platform)) { // We are compiling for a console... // We want the output to go into the <GAME>\Binaries folder if (!InRulesObject.bOutputToEngineBinaries) { OutputPaths = OutputPaths.Select(Path => new FileReference(Path.FullName.Replace("Engine\\Binaries", InDesc.TargetName + "\\Binaries"))).ToList(); } } } }
// 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 UEBuildServer( string InGameName, UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules) : base(InAppName:UEBuildTarget.GetBinaryBaseName(InGameName, InRulesObject, InPlatform, InConfiguration, "Server"), InGameName:InGameName, InPlatform:InPlatform, InConfiguration:InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions:InAdditionalDefinitions, InRemoteRoot:InRemoteRoot, InOnlyModules:InOnlyModules) { }
public UEBuildGame( string InGameName, UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules InRulesObject, List<string> InAdditionalDefinitions, string InRemoteRoot, List<OnlyModule> InOnlyModules, bool bInEditorRecompile) // 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 : base( InAppName: UEBuildTarget.GetBinaryBaseName(InGameName, InRulesObject, InPlatform, InConfiguration, ""), InGameName:InGameName, InPlatform:InPlatform, InConfiguration:InConfiguration, InRulesObject: InRulesObject, InAdditionalDefinitions:InAdditionalDefinitions, InRemoteRoot:InRemoteRoot, InOnlyModules:InOnlyModules, bInEditorRecompile: bInEditorRecompile ) { if (ShouldCompileMonolithic()) { if ((UnrealBuildTool.IsDesktopPlatform(Platform) == false) || (Platform == UnrealTargetPlatform.WinRT) || (Platform == UnrealTargetPlatform.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"); } } } } }
public static void GetTargetUWPPaths(string InTargetName, TargetRules InTargetRules, out string OutEngineSourceRelativeBinaryPath, out string OutRelativeTargetPath) { OutEngineSourceRelativeBinaryPath = ""; OutRelativeTargetPath = ""; string TargetFilename = RulesCompiler.GetTargetFilename(InTargetName); string ProjectSourceFolder = new FileInfo(TargetFilename).DirectoryName; string EnginePath = Path.Combine(ProjectFileGenerator.EngineRelativePath); string EngineSourcePath = Path.Combine(EnginePath, "Source"); string RelativeTargetFilename = Utils.MakePathRelativeTo(TargetFilename, EngineSourcePath); if ((RelativeTargetFilename.StartsWith("..") == false) && (RelativeTargetFilename.Contains(":") == false)) { // This target must be UNDER Engine/Source... RelativeTargetFilename = Path.Combine(EngineSourcePath, RelativeTargetFilename); } RelativeTargetFilename = RelativeTargetFilename.Replace("\\", "/"); EnginePath = EnginePath.Replace("\\", "/"); Int32 LastSourceIdx = RelativeTargetFilename.LastIndexOf("Source"); if (LastSourceIdx != -1) { RelativeTargetFilename = RelativeTargetFilename.Substring(0, LastSourceIdx); } else { RelativeTargetFilename = ""; } OutRelativeTargetPath = RelativeTargetFilename; if (InTargetRules.bOutputToEngineBinaries) { RelativeTargetFilename = EnginePath; } OutEngineSourceRelativeBinaryPath = Path.Combine(RelativeTargetFilename, "Binaries/UWP/"); OutEngineSourceRelativeBinaryPath = OutEngineSourceRelativeBinaryPath.Replace("\\", "/"); }
public UEBuildGame(TargetDescriptor InDesc, TargetRules InRulesObject, string InTargetCsFilename) : base(InDesc, InRulesObject, "UE4", InTargetCsFilename) { if (ShouldCompileMonolithic()) { if ((UnrealBuildTool.IsDesktopPlatform(Platform) == false) || (Platform == UnrealTargetPlatform.WinRT) || (Platform == UnrealTargetPlatform.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", InDesc.TargetName + "\\Binaries"); } } } } }
/// <summary> /// Constructs a TargetInfo /// </summary> /// <param name="InitPlatform">Target platform</param> /// <param name="InitConfiguration">Target build configuration</param> /// <param name="InitType">Target type</param> /// <param name="bInitIsMonolithic">Whether the target is monolithic</param> public TargetInfo( UnrealTargetPlatform InitPlatform, UnrealTargetConfiguration InitConfiguration, TargetRules.TargetType InitType, bool bInitIsMonolithic ) : this(InitPlatform, InitConfiguration) { Type = InitType; bIsMonolithic = bInitIsMonolithic; }
/// <summary> /// Gets the project's root binaries folder. /// </summary> /// <param name="RawProjectPath">Full project path.</param> /// <param name="TargetType">Target type.</param> /// <param name="bIsUProjectFile">True if uproject file.</param> /// <returns>Binaries path.</returns> public static string GetClientProjectBinariesRootPath(string RawProjectPath, TargetRules.TargetType TargetType, bool bIsCodeBasedProject) { var BinPath = String.Empty; switch (TargetType) { case TargetRules.TargetType.Program: BinPath = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Binaries"); break; case TargetRules.TargetType.Client: case TargetRules.TargetType.Game: if (!bIsCodeBasedProject) { BinPath = CommandUtils.CombinePaths(CommandUtils.CmdEnv.LocalRoot, "Engine", "Binaries"); } else { BinPath = CommandUtils.CombinePaths(CommandUtils.GetDirectoryName(RawProjectPath), "Binaries"); } break; } return BinPath; }
/// <summary> /// Validate a target's settings /// </summary> public override void ValidateTarget(TargetRules Target) { // Disable Simplygon support if compiling against the NULL RHI. if (Target.GlobalDefinitions.Contains("USE_NULL_RHI=1")) { Target.bCompileSimplygon = false; Target.bCompileSimplygonSSF = false; Target.bCompileCEF3 = false; } // Set the compiler version if necessary if (Target.WindowsPlatform.Compiler == WindowsCompiler.Default) { Target.WindowsPlatform.Compiler = GetDefaultCompiler(); } // Disable linking if we're using a static analyzer if (Target.WindowsPlatform.StaticAnalyzer != WindowsStaticAnalyzer.None) { Target.bDisableLinking = true; } // Disable PCHs for PVS studio if (Target.WindowsPlatform.StaticAnalyzer == WindowsStaticAnalyzer.PVSStudio) { Target.bUsePCHFiles = false; } // Override PCH settings if (bCompileWithClang) { // @todo clang: Shared PCHs don't work on clang yet because the PCH will have definitions assigned to different values // than the consuming translation unit. Unlike the warning in MSVC, this is a compile in Clang error which cannot be suppressed Target.bUseSharedPCHs = false; // @todo clang: PCH files aren't supported by "clang-cl" yet (no /Yc support, and "-x c++-header" cannot be specified) if (WindowsPlatform.bUseVCCompilerArgs) { Target.bUsePCHFiles = false; } } if (bCompileWithICL) { Target.NumIncludedBytesPerUnityCPP = Math.Min(Target.NumIncludedBytesPerUnityCPP, 256 * 1024); Target.bUseSharedPCHs = false; if (WindowsPlatform.bUseVCCompilerArgs) { Target.bUsePCHFiles = false; } } // E&C support. if (Target.bSupportEditAndContinue && Target.Configuration == UnrealTargetConfiguration.Debug) { Target.bUseIncrementalLinking = true; } // Incremental linking. if (Target.bUseIncrementalLinking && !Target.bDisableDebugInfo) { Target.bUsePDBFiles = true; } }
/// <summary> /// Determine if a plugin is enabled for a given project /// </summary> /// <param name="Project">The project to check</param> /// <param name="Plugin">Information about the plugin</param> /// <param name="Platform">The target platform</param> /// <returns>True if the plugin should be enabled for this project</returns> public static bool IsPluginDescriptorRequiredForProject(PluginInfo Plugin, ProjectDescriptor Project, UnrealTargetPlatform Platform, TargetRules.TargetType TargetType, bool bBuildDeveloperTools, bool bBuildEditor) { // Check if it's referenced by name from the project descriptor. If it is, we'll need the plugin to be included with the project regardless of whether it has // any platform-specific modules or content, just so the runtime can make the call. if (Project != null && Project.Plugins != null) { foreach (PluginReferenceDescriptor PluginReference in Project.Plugins) { if (String.Compare(PluginReference.Name, Plugin.Name, true) == 0) { return PluginReference.IsEnabledForPlatform(Platform) && PluginReference.IsEnabledForTarget(TargetType); } } } // If the plugin contains content, it should be included for all platforms if(Plugin.Descriptor.bCanContainContent) { return true; } // Check if the plugin has any modules for the given target foreach (ModuleDescriptor Module in Plugin.Descriptor.Modules) { if(Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor)) { return true; } } return false; }
/// <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(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, string InConditionString, TargetRules InTargetRules, FileReference TargetRulesPath, FileReference ProjectFilePath) { return(""); }
/// <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(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, string InConditionString, TargetRules InTargetRules, FileReference TargetRulesPath, FileReference ProjectFilePath) { return ""; }
public UEBuildEditor(TargetDescriptor InDesc, TargetRules InRulesObject, string InTargetCsFilename) : base(InDesc, InRulesObject, "UE4Editor", InTargetCsFilename) { }
public UEBuildServer(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Server", InTargetCsFilename) { }
/// <summary> /// Build a target remotely /// </summary> /// <param name="TargetDesc">Descriptor for the target to build</param> /// <param name="RemoteLogFile">Path to store the remote log file</param> /// <returns>True if the build succeeded, false otherwise</returns> public bool Build(TargetDescriptor TargetDesc, FileReference RemoteLogFile) { // Get the directory for working files DirectoryReference BaseDir = DirectoryReference.FromFile(TargetDesc.ProjectFile) ?? UnrealBuildTool.EngineDirectory; DirectoryReference TempDir = DirectoryReference.Combine(BaseDir, "Intermediate", "Remote", TargetDesc.Name, TargetDesc.Platform.ToString(), TargetDesc.Configuration.ToString()); DirectoryReference.CreateDirectory(TempDir); bool bLogIsMapped = false; foreach (RemoteMapping Mapping in Mappings) { if (RemoteLogFile.Directory.FullName.Equals(Mapping.LocalDirectory.FullName, StringComparison.InvariantCultureIgnoreCase)) { bLogIsMapped = true; break; } } if (!bLogIsMapped) { Mappings.Add(new RemoteMapping(RemoteLogFile.Directory, GetRemotePath(RemoteLogFile.Directory))); } // Compile the rules assembly RulesAssembly RulesAssembly = RulesCompiler.CreateTargetRulesAssembly(TargetDesc.ProjectFile, TargetDesc.Name, false, false, TargetDesc.ForeignPlugin); // Create the target rules TargetRules Rules = RulesAssembly.CreateTargetRules(TargetDesc.Name, TargetDesc.Platform, TargetDesc.Configuration, TargetDesc.Architecture, TargetDesc.ProjectFile, new ReadOnlyBuildVersion(BuildVersion.ReadDefault()), new string[0]); // Check if we need to enable a nativized plugin, and compile the assembly for that if we do FileReference NativizedPluginFile = Rules.GetNativizedPlugin(); if (NativizedPluginFile != null) { RulesAssembly = RulesCompiler.CreatePluginRulesAssembly(NativizedPluginFile, false, RulesAssembly, false); } // Path to the local manifest file. This has to be translated from the remote format after the build is complete. List <FileReference> LocalManifestFiles = new List <FileReference>(); // Path to the remote manifest file FileReference RemoteManifestFile = FileReference.Combine(TempDir, "Manifest.xml"); // Prepare the arguments we will pass to the remote build List <string> RemoteArguments = new List <string>(); RemoteArguments.Add(TargetDesc.Name); RemoteArguments.Add(TargetDesc.Platform.ToString()); RemoteArguments.Add(TargetDesc.Configuration.ToString()); RemoteArguments.Add("-SkipRulesCompile"); // Use the rules assembly built locally RemoteArguments.Add(String.Format("-XmlConfigCache={0}", GetRemotePath(XmlConfig.CacheFile))); // Use the XML config cache built locally, since the remote won't have it RemoteArguments.Add(String.Format("-Log={0}", GetRemotePath(RemoteLogFile))); RemoteArguments.Add(String.Format("-Manifest={0}", GetRemotePath(RemoteManifestFile))); if (TargetDesc.ProjectFile != null) { RemoteArguments.Add(String.Format("-Project={0}", GetRemotePath(TargetDesc.ProjectFile))); } foreach (string LocalArgument in TargetDesc.AdditionalArguments) { int EqualsIdx = LocalArgument.IndexOf('='); if (EqualsIdx == -1) { RemoteArguments.Add(LocalArgument); continue; } string Key = LocalArgument.Substring(0, EqualsIdx); string Value = LocalArgument.Substring(EqualsIdx + 1); if (Key.Equals("-Log", StringComparison.InvariantCultureIgnoreCase)) { // We are already writing to the local log file. The remote will produce a different log (RemoteLogFile) continue; } if (Key.Equals("-Manifest", StringComparison.InvariantCultureIgnoreCase)) { LocalManifestFiles.Add(new FileReference(Value)); continue; } string RemoteArgument = LocalArgument; foreach (RemoteMapping Mapping in Mappings) { if (Value.StartsWith(Mapping.LocalDirectory.FullName, StringComparison.InvariantCultureIgnoreCase)) { RemoteArgument = String.Format("{0}={1}", Key, GetRemotePath(Value)); break; } } RemoteArguments.Add(RemoteArgument); } // Handle any per-platform setup that is required if (TargetDesc.Platform == UnrealTargetPlatform.IOS || TargetDesc.Platform == UnrealTargetPlatform.TVOS) { // Always generate a .stub RemoteArguments.Add("-CreateStub"); // Cannot use makefiles, since we need PostBuildSync() to generate the IPA (and that requires a TargetRules instance) RemoteArguments.Add("-NoUBTMakefiles"); // Get the provisioning data for this project IOSProvisioningData ProvisioningData = ((IOSPlatform)UEBuildPlatform.GetBuildPlatform(TargetDesc.Platform)).ReadProvisioningData(TargetDesc.ProjectFile); if (ProvisioningData == null || ProvisioningData.MobileProvisionFile == null) { throw new BuildException("Unable to find mobile provision for {0}. See log for more information.", TargetDesc.Name); } // Create a local copy of the provision FileReference MobileProvisionFile = FileReference.Combine(TempDir, ProvisioningData.MobileProvisionFile.GetFileName()); if (FileReference.Exists(MobileProvisionFile)) { FileReference.SetAttributes(MobileProvisionFile, FileAttributes.Normal); } FileReference.Copy(ProvisioningData.MobileProvisionFile, MobileProvisionFile, true); Log.TraceInformation("[Remote] Uploading {0}", MobileProvisionFile); UploadFile(MobileProvisionFile); // Extract the certificate for the project. Try to avoid calling IPP if we already have it. FileReference CertificateFile = FileReference.Combine(TempDir, "Certificate.p12"); FileReference CertificateInfoFile = FileReference.Combine(TempDir, "Certificate.txt"); string CertificateInfoContents = String.Format("{0}\n{1}", ProvisioningData.MobileProvisionFile, FileReference.GetLastWriteTimeUtc(ProvisioningData.MobileProvisionFile).Ticks); if (!FileReference.Exists(CertificateFile) || !FileReference.Exists(CertificateInfoFile) || FileReference.ReadAllText(CertificateInfoFile) != CertificateInfoContents) { Log.TraceInformation("[Remote] Exporting certificate for {0}...", ProvisioningData.MobileProvisionFile); StringBuilder Arguments = new StringBuilder("ExportCertificate"); if (TargetDesc.ProjectFile == null) { Arguments.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineSourceDirectory); } else { Arguments.AppendFormat(" \"{0}\"", TargetDesc.ProjectFile.Directory); } Arguments.AppendFormat(" -provisionfile \"{0}\"", ProvisioningData.MobileProvisionFile); Arguments.AppendFormat(" -outputcertificate \"{0}\"", CertificateFile); if (TargetDesc.Platform == UnrealTargetPlatform.TVOS) { Arguments.Append(" -tvos"); } ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Binaries", "DotNET", "IOS", "IPhonePackager.exe").FullName; StartInfo.Arguments = Arguments.ToString(); if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0) { throw new BuildException("IphonePackager failed."); } FileReference.WriteAllText(CertificateInfoFile, CertificateInfoContents); } // Upload the certificate to the remote Log.TraceInformation("[Remote] Uploading {0}", CertificateFile); UploadFile(CertificateFile); // Tell the remote UBT instance to use them RemoteArguments.Add(String.Format("-ImportProvision={0}", GetRemotePath(MobileProvisionFile))); RemoteArguments.Add(String.Format("-ImportCertificate={0}", GetRemotePath(CertificateFile))); RemoteArguments.Add(String.Format("-ImportCertificatePassword=A")); } // Upload the workspace files UploadWorkspace(TempDir); // Fixup permissions on any shell scripts Execute(RemoteBaseDir, String.Format("chmod +x {0}/Build/BatchFiles/Mac/*.sh", EscapeShellArgument(GetRemotePath(UnrealBuildTool.EngineDirectory)))); // Execute the compile Log.TraceInformation("[Remote] Executing build"); StringBuilder BuildCommandLine = new StringBuilder("Engine/Build/BatchFiles/Mac/Build.sh"); foreach (string RemoteArgument in RemoteArguments) { BuildCommandLine.AppendFormat(" {0}", EscapeShellArgument(RemoteArgument)); } int Result = Execute(GetRemotePath(UnrealBuildTool.RootDirectory), BuildCommandLine.ToString()); if (Result != 0) { if (RemoteLogFile != null) { Log.TraceInformation("[Remote] Downloading {0}", RemoteLogFile); DownloadFile(RemoteLogFile); } return(false); } // Download the manifest Log.TraceInformation("[Remote] Downloading {0}", RemoteManifestFile); DownloadFile(RemoteManifestFile); // Convert the manifest to local form BuildManifest Manifest = Utils.ReadClass <BuildManifest>(RemoteManifestFile.FullName); for (int Idx = 0; Idx < Manifest.BuildProducts.Count; Idx++) { Manifest.BuildProducts[Idx] = GetLocalPath(Manifest.BuildProducts[Idx]).FullName; } // Download the files from the remote if (TargetDesc.AdditionalArguments.Any(x => x.Equals("-GenerateManifest", StringComparison.InvariantCultureIgnoreCase))) { LocalManifestFiles.Add(FileReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "Build", "Manifest.xml")); } else { Log.TraceInformation("[Remote] Downloading build products"); List <FileReference> FilesToDownload = new List <FileReference>(); FilesToDownload.Add(RemoteLogFile); FilesToDownload.AddRange(Manifest.BuildProducts.Select(x => new FileReference(x))); DownloadFiles(FilesToDownload); } // Write out all the local manifests foreach (FileReference LocalManifestFile in LocalManifestFiles) { Log.TraceInformation("[Remote] Writing {0}", LocalManifestFile); Utils.WriteClass <BuildManifest>(Manifest, LocalManifestFile.FullName, ""); } return(true); }
public override void ResetTarget(TargetRules Target) { }
/// <summary> /// Set all the platform-specific defaults for a new target /// </summary> public virtual void ResetTarget(TargetRules Target) { }
/// <summary> /// Construct an instance of the given target rules /// </summary> /// <param name="TypeName">Type name of the target rules</param> /// <param name="TargetInfo">Target configuration information to pass to the constructor</param> /// <returns>Instance of the corresponding TargetRules</returns> protected TargetRules CreateTargetRulesInstance(string TypeName, TargetInfo TargetInfo) { // The build module must define a type named '<TargetName>Target' that derives from our 'TargetRules' type. Type BaseRulesType = CompiledAssembly.GetType(TypeName); if (BaseRulesType == null) { throw new BuildException("Expecting to find a type to be declared in a target rules named '{0}'. This type must derive from the 'TargetRules' type defined by Unreal Build Tool.", TypeName); } // Look for platform/group rules that we will use instead of the base rules string PlatformRulesName = TargetInfo.Name + "_" + TargetInfo.Platform.ToString(); Type PlatformRulesType = CompiledAssembly.GetType(TypeName + "_" + TargetInfo.Platform.ToString()); if (PlatformRulesType == null) { foreach (UnrealPlatformGroup Group in UEBuildPlatform.GetPlatformGroups(TargetInfo.Platform)) { // look to see if the group has an override string GroupRulesName = TargetInfo.Name + "_" + Group.ToString(); Type GroupRulesObjectType = CompiledAssembly.GetType(TypeName + "_" + Group.ToString()); // we expect only one platform group to be found in the extensions if (GroupRulesObjectType != null && PlatformRulesType != null) { throw new BuildException("Found multiple platform group overrides ({0} and {1}) for rules {2} without a platform specific override. Create a platform override with the class hierarchy as needed.", GroupRulesObjectType.Name, PlatformRulesType.Name, TypeName); } // remember the platform group if we found it, but keep searching to verify there isn't more than one if (GroupRulesObjectType != null) { PlatformRulesName = GroupRulesName; PlatformRulesType = GroupRulesObjectType; } } } if (PlatformRulesType != null && !PlatformRulesType.IsSubclassOf(BaseRulesType)) { throw new BuildException("Expecting {0} to be a specialization of {1}", PlatformRulesType, BaseRulesType); } // Create an instance of the module's rules object, and set some defaults before calling the constructor. Type RulesType = PlatformRulesType ?? BaseRulesType; TargetRules Rules = (TargetRules)FormatterServices.GetUninitializedObject(RulesType); if (DefaultBuildSettings.HasValue) { Rules.DefaultBuildSettings = DefaultBuildSettings.Value; } // Return the base target file name to the caller. This affects where the resulting build product is created so the platform/group is not desired in this case. Rules.File = TargetNameToTargetFile[TargetInfo.Name]; // Find the constructor ConstructorInfo Constructor = RulesType.GetConstructor(new Type[] { typeof(TargetInfo) }); if (Constructor == null) { throw new BuildException("No constructor found on {0} which takes an argument of type TargetInfo.", RulesType.Name); } // Invoke the regular constructor try { Constructor.Invoke(Rules, new object[] { TargetInfo }); } catch (Exception Ex) { throw new BuildException(Ex, "Unable to instantiate instance of '{0}' object type from compiled assembly '{1}'. Unreal Build Tool creates an instance of your module's 'Rules' object in order to find out about your module's requirements. The CLR exception details may provide more information: {2}", TypeName, Path.GetFileNameWithoutExtension(CompiledAssembly.Location), Ex.ToString()); } // Set the default overriddes for the configured target type Rules.SetOverridesForTargetType(); // Set the final value for the link type in the target rules if (Rules.LinkType == TargetLinkType.Default) { throw new BuildException("TargetRules.LinkType should be inferred from TargetType"); } // Set the default value for whether to use the shared build environment if (Rules.BuildEnvironment == TargetBuildEnvironment.Unique && UnrealBuildTool.IsEngineInstalled()) { throw new BuildException("Targets with a unique build environment cannot be built an installed engine."); } // Automatically include CoreUObject if (Rules.bCompileAgainstEngine) { Rules.bCompileAgainstCoreUObject = true; } // Must have editor only data if building the editor. if (Rules.bBuildEditor) { Rules.bBuildWithEditorOnlyData = true; } // Apply the override to force debug info to be enabled if (Rules.bForceDebugInfo) { Rules.bDisableDebugInfo = false; Rules.bOmitPCDebugInfoInDevelopment = false; } // Setup the malloc profiler if (Rules.bUseMallocProfiler) { Rules.bOmitFramePointers = false; Rules.GlobalDefinitions.Add("USE_MALLOC_PROFILER=1"); } // Set a macro if we allow using generated inis if (!Rules.bAllowGeneratedIniWhenCooked) { Rules.GlobalDefinitions.Add("DISABLE_GENERATED_INI_WHEN_COOKED=1"); } if (!Rules.bAllowNonUFSIniWhenCooked) { Rules.GlobalDefinitions.Add("DISABLE_NONUFS_INI_WHEN_COOKED=1"); } if (Rules.bDisableUnverifiedCertificates) { Rules.GlobalDefinitions.Add("DISABLE_UNVERIFIED_CERTIFICATE_LOADING=1"); } // Allow the platform to finalize the settings UEBuildPlatform Platform = UEBuildPlatform.GetBuildPlatform(Rules.Platform); Platform.ValidateTarget(Rules); // Some platforms may *require* monolithic compilation... if (Rules.LinkType != TargetLinkType.Monolithic && UEBuildPlatform.PlatformRequiresMonolithicBuilds(Rules.Platform, Rules.Configuration)) { throw new BuildException(String.Format("{0}: {1} does not support modular builds", Rules.Name, Rules.Platform)); } return(Rules); }
/// <summary> /// Allow various platform project generators to generate stub projects if required /// </summary> /// <param name="InGenerator"></param> /// <param name="InTargetName"></param> /// <param name="InTargetFilepath"></param> /// <param name="InTargetRules"></param> /// <param name="InPlatforms"></param> /// <param name="InConfigurations"></param> /// <returns></returns> public static bool GenerateGameProjectStubs(ProjectFileGenerator InGenerator, string InTargetName, string InTargetFilepath, TargetRules InTargetRules, List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations) { foreach (KeyValuePair <UnrealTargetPlatform, UEPlatformProjectGenerator> Entry in ProjectGeneratorDictionary) { UEPlatformProjectGenerator ProjGen = Entry.Value; ProjGen.GenerateGameProjectStub(InGenerator, InTargetName, InTargetFilepath, InTargetRules, InPlatforms, InConfigurations); } return(true); }
public virtual void GenerateGameProperties(UnrealTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetRules.TargetType TargetType, DirectoryReference RootDirectory, FileReference TargetFilePath) { // Do nothing }
/// <summary> /// Return any custom layout directory sections /// </summary> /// <param name="InPlatform"> The UnrealTargetPlatform being built</param> /// <param name="TargetType"> The type of target (game or program)</param> /// <returns>string The custom property import lines for the project file; Empty string if it doesn't require one</returns> public virtual string GetVisualStudioLayoutDirSection(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, string InConditionString, TargetRules.TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference NMakeOutputPath) { return ""; }
public override void GenerateGameProperties(UnrealTargetConfiguration Configuration, StringBuilder VCProjectFileContent, TargetRules.TargetType TargetType, string RootDirectory, string TargetFilePath) { // @todo UWP: This used to be "WINUAP=1". Need to verify that 'UWP' is the correct define that we want here. VCProjectFileContent.Append(" <NMakePreprocessorDefinitions>$(NMakePreprocessorDefinitions);PLATFORM_UWP=1;UWP=1;</NMakePreprocessorDefinitions>" + ProjectFileGenerator.NewLine); }
public override void ResetTarget(TargetRules Target) { Target.bCompileSimplygon = false; Target.bCompileSimplygonSSF = false; }
public override void ResetTarget(TargetRules Target) { ValidateTarget(Target); Target.bDeployAfterCompile = true; }
public override void ValidateTarget(TargetRules Target) { // WindowsTargetRules are reused for HoloLens, so that build modules can keep the model that reuses "windows" configs for most cases // That means overriding those settings here that need to be adjusted for HoloLens // Compiler version and pix flags must be reloaded from the HoloLens hive // Currently BP-only projects don't load build-related settings from their remote ini when building UE4Game.exe // (see TargetRules.cs, where the possibly-null project directory is passed to ConfigCache.ReadSettings). // It's important for HoloLens that we *do* use the project-specific settings when building (VS 2017 vs 2015 and // retail Windows Store are both examples). Possibly this should be done on all platforms? But in the interest // of not changing behavior on other platforms I'm limiting the scope. DirectoryReference IniDirRef = DirectoryReference.FromFile(Target.ProjectFile); if (IniDirRef == null && !string.IsNullOrEmpty(UnrealBuildTool.GetRemoteIniPath())) { IniDirRef = new DirectoryReference(UnrealBuildTool.GetRemoteIniPath()); } // Stash the current compiler choice (accounts for command line) in case ReadSettings reverts it to default WindowsCompiler CompilerBeforeReadSettings = Target.HoloLensPlatform.Compiler; ConfigCache.ReadSettings(IniDirRef, Platform, Target.HoloLensPlatform); if (Target.HoloLensPlatform.Compiler == WindowsCompiler.Default) { if (CompilerBeforeReadSettings != WindowsCompiler.Default) { // Previous setting was more specific, use that Target.HoloLensPlatform.Compiler = CompilerBeforeReadSettings; } else { Target.HoloLensPlatform.Compiler = WindowsPlatform.GetDefaultCompiler(Target.ProjectFile); } } if (!Target.bGenerateProjectFiles) { Log.TraceInformationOnce("Using {0} architecture for deploying to HoloLens device", Target.HoloLensPlatform.Architecture); } Target.WindowsPlatform.Compiler = Target.HoloLensPlatform.Compiler; Target.WindowsPlatform.Architecture = Target.HoloLensPlatform.Architecture; Target.WindowsPlatform.bPixProfilingEnabled = Target.HoloLensPlatform.bPixProfilingEnabled; Target.WindowsPlatform.bUseWindowsSDK10 = true; Target.bDeployAfterCompile = true; Target.bCompileNvCloth = false; // requires CUDA // Disable Simplygon support if compiling against the NULL RHI. if (Target.GlobalDefinitions.Contains("USE_NULL_RHI=1")) { Target.bCompileSpeedTree = false; } // Use shipping binaries to avoid dependency on nvToolsExt which fails WACK. if (Target.Configuration == UnrealTargetConfiguration.Shipping) { Target.bUseShippingPhysXLibraries = true; } // Be resilient to SDKs being uninstalled but still referenced in the INI file VersionNumber SelectedWindowsSdkVersion; DirectoryReference SelectedWindowsSdkDir; if (!WindowsPlatform.TryGetWindowsSdkDir(Target.HoloLensPlatform.Win10SDKVersionString, out SelectedWindowsSdkVersion, out SelectedWindowsSdkDir)) { Target.HoloLensPlatform.Win10SDKVersionString = "Latest"; } // Initialize the VC environment for the target, and set all the version numbers to the concrete values we chose. VCEnvironment Environment = VCEnvironment.Create(Target.WindowsPlatform.Compiler, Platform, Target.WindowsPlatform.Architecture, Target.WindowsPlatform.CompilerVersion, Target.HoloLensPlatform.Win10SDKVersionString, null); Target.WindowsPlatform.Environment = Environment; Target.WindowsPlatform.Compiler = Environment.Compiler; Target.WindowsPlatform.CompilerVersion = Environment.CompilerVersion.ToString(); Target.WindowsPlatform.WindowsSdkVersion = Environment.WindowsSdkVersion.ToString(); // Windows 10 SDK version // Auto-detect latest compatible by default (recommended), allow for explicit override if necessary // Validate that the SDK isn't too old, and that the combination of VS and SDK is supported. Target.HoloLensPlatform.Win10SDKVersion = new Version(Environment.WindowsSdkVersion.ToString()); if (!Target.bGenerateProjectFiles) { Log.TraceInformationOnce("Building using Windows SDK version {0} for HoloLens", Target.HoloLensPlatform.Win10SDKVersion); if (Target.HoloLensPlatform.Win10SDKVersion < MinimumSDKVersionRecommended) { Log.TraceWarning("Your Windows SDK version {0} is older than the minimum recommended version ({1}) for HoloLens. Consider upgrading.", Target.HoloLensPlatform.Win10SDKVersion, MinimumSDKVersionRecommended); } else if (Target.HoloLensPlatform.Win10SDKVersion > MaximumSDKVersionTested) { Log.TraceInformationOnce("Your Windows SDK version ({0}) for HoloLens is newer than the highest tested with this version of UBT ({1}). This is probably fine, but if you encounter issues consider using an earlier SDK.", Target.HoloLensPlatform.Win10SDKVersion, MaximumSDKVersionTested); } } HoloLensExports.InitWindowsSdkToolPath(Target.HoloLensPlatform.Win10SDKVersion.ToString()); }
// Anonymous function that writes project configuration data private void WriteConfiguration(string ProjectName, UnrealTargetConfiguration Configuration, UnrealTargetPlatform Platform, string TargetFilePath, TargetRules TargetRulesObject, StringBuilder VCProjectFileContent, StringBuilder VCUserFileContent) { UEPlatformProjectGenerator ProjGenerator = UEPlatformProjectGenerator.GetPlatformProjectGenerator(Platform, true); if (((ProjGenerator == null) && (Platform != UnrealTargetPlatform.Unknown))) { return; } string UProjectPath = ""; bool bIsProjectTarget = UnrealBuildTool.HasUProjectFile() && Utils.IsFileUnderDirectory(TargetFilePath, UnrealBuildTool.GetUProjectPath()); // @todo Rocket: HACK: Only use long project names on the UBT command-line for out-of-root projects for now. We need to revisit all uses of HasUProjectFile and short names in general to fix this. if (bIsProjectTarget && !UnrealBuildTool.RunningRocket() && Utils.IsFileUnderDirectory(UnrealBuildTool.GetUProjectFile(), ProjectFileGenerator.RootRelativePath)) { bIsProjectTarget = false; } if (bIsProjectTarget) { UProjectPath = "\"$(SolutionDir)$(SolutionName).uproject\""; } string ProjectConfigName = StubProjectConfigurationName; string ProjectPlatformName = StubProjectPlatformName; MakeProjectPlatformAndConfigurationNames(Platform, Configuration, TargetRulesObject.ConfigurationName, out ProjectPlatformName, out ProjectConfigName); var ConfigAndPlatformName = ProjectConfigName + "|" + ProjectPlatformName; string ConditionString = "Condition=\"'$(Configuration)|$(Platform)'=='" + ConfigAndPlatformName + "'\""; { VCProjectFileContent.Append( " <ImportGroup " + ConditionString + " Label=\"PropertySheets\">" + ProjectFileGenerator.NewLine + " <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />" + ProjectFileGenerator.NewLine + " </ImportGroup>" + ProjectFileGenerator.NewLine); VCProjectFileContent.Append( " <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine); if (IsStubProject) { string ProjectRelativeUnusedDirectory = NormalizeProjectPath(Path.Combine(ProjectFileGenerator.EngineRelativePath, BuildConfiguration.BaseIntermediateFolder, "Unused")); VCProjectFileContent.Append( " <OutDir></OutDir>" + ProjectFileGenerator.NewLine + " <IntDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</IntDir>" + ProjectFileGenerator.NewLine + " <NMakeBuildCommandLine/>" + ProjectFileGenerator.NewLine + " <NMakeReBuildCommandLine/>" + ProjectFileGenerator.NewLine + " <NMakeCleanCommandLine/>" + ProjectFileGenerator.NewLine + " <NMakeOutput/>" + ProjectFileGenerator.NewLine); } else { string TargetName = Utils.GetFilenameWithoutAnyExtensions(TargetFilePath); var UBTPlatformName = IsStubProject ? StubProjectPlatformName : Platform.ToString(); var UBTConfigurationName = IsStubProject ? StubProjectConfigurationName : Configuration.ToString(); // Setup output path UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform); // Figure out if this is a monolithic build bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform); bShouldCompileMonolithic |= TargetRulesObject.ShouldCompileMonolithic(Platform, Configuration); // Get the output directory string RootDirectory = Path.GetFullPath(ProjectFileGenerator.EngineRelativePath); if ((TargetRules.IsAGame(TargetRulesObject.Type) || TargetRulesObject.Type == TargetRules.TargetType.Server) && bShouldCompileMonolithic && !TargetRulesObject.bOutputToEngineBinaries) { if (UnrealBuildTool.HasUProjectFile() && Utils.IsFileUnderDirectory(TargetFilePath, UnrealBuildTool.GetUProjectPath())) { RootDirectory = Path.GetFullPath(UnrealBuildTool.GetUProjectPath()); } else { string UnrealProjectPath = UProjectInfo.GetProjectFilePath(ProjectName); if (!String.IsNullOrEmpty(UnrealProjectPath)) { RootDirectory = Path.GetDirectoryName(Path.GetFullPath(UnrealProjectPath)); } } } // Get the output directory string OutputDirectory = Path.Combine(RootDirectory, "Binaries", UBTPlatformName); // Get the executable name (minus any platform or config suffixes) string BaseExeName = TargetName; if (!bShouldCompileMonolithic && TargetRulesObject.Type != TargetRules.TargetType.Program) { // Figure out what the compiled binary will be called so that we can point the IDE to the correct file string TargetConfigurationName = TargetRulesObject.ConfigurationName; if (TargetConfigurationName != TargetRules.TargetType.Game.ToString() && TargetConfigurationName != TargetRules.TargetType.RocketGame.ToString() && TargetConfigurationName != TargetRules.TargetType.Program.ToString()) { BaseExeName = "UE4" + TargetConfigurationName; } } // Make the output file path string NMakePath = Path.Combine(OutputDirectory, BaseExeName); if (Configuration != UnrealTargetConfiguration.Development && (Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic)) { NMakePath += "-" + UBTPlatformName + "-" + UBTConfigurationName; } NMakePath += BuildPlatform.GetActiveArchitecture(); NMakePath += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable); NMakePath = BuildPlatform.ModifyNMakeOutput(NMakePath); string PathStrings = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioPathsEntries(Platform, Configuration, TargetRulesObject.Type, TargetFilePath, ProjectFilePath, NMakePath) : ""; if (string.IsNullOrEmpty(PathStrings) || (PathStrings.Contains("<IntDir>") == false)) { string ProjectRelativeUnusedDirectory = "$(ProjectDir)..\\Build\\Unused"; VCProjectFileContent.Append( PathStrings + " <OutDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</OutDir>" + ProjectFileGenerator.NewLine + " <IntDir>" + ProjectRelativeUnusedDirectory + Path.DirectorySeparatorChar + "</IntDir>" + ProjectFileGenerator.NewLine); } else { VCProjectFileContent.Append(PathStrings); } // Force specification of TargetName on XboxOne so that the manifest can identify the correct executable to the debugger. if (Platform == UnrealTargetPlatform.XboxOne) { VCProjectFileContent.Append(" <TargetName>$(ProjectName)"); if (Configuration != UnrealTargetConfiguration.Development) { VCProjectFileContent.Append(UBTConfigurationName); } VCProjectFileContent.Append("</TargetName>" + ProjectFileGenerator.NewLine); } // This is the standard UE4 based project NMake build line: // ..\..\Build\BatchFiles\Build.bat <TARGETNAME> <PLATFORM> <CONFIGURATION> // ie ..\..\Build\BatchFiles\Build.bat BlankProgram Win64 Debug string ProjectPlatformConfiguration = " " + TargetName + " " + UBTPlatformName + " " + UBTConfigurationName; string BatchFilesDirectoryName = Path.Combine(ProjectFileGenerator.EngineRelativePath, "Build", "BatchFiles"); // NMake Build command line VCProjectFileContent.Append(" <NMakeBuildCommandLine>"); VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Build.bat"))) + ProjectPlatformConfiguration.ToString()); if (bIsProjectTarget) { VCProjectFileContent.Append(" " + UProjectPath + (UnrealBuildTool.RunningRocket() ? " -rocket" : "")); } VCProjectFileContent.Append("</NMakeBuildCommandLine>" + ProjectFileGenerator.NewLine); // NMake ReBuild command line VCProjectFileContent.Append(" <NMakeReBuildCommandLine>"); VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Rebuild.bat"))) + ProjectPlatformConfiguration.ToString()); if (bIsProjectTarget) { VCProjectFileContent.Append(" " + UProjectPath + (UnrealBuildTool.RunningRocket() ? " -rocket" : "")); } VCProjectFileContent.Append("</NMakeReBuildCommandLine>" + ProjectFileGenerator.NewLine); // NMake Clean command line VCProjectFileContent.Append(" <NMakeCleanCommandLine>"); VCProjectFileContent.Append(EscapePath(NormalizeProjectPath(Path.Combine(BatchFilesDirectoryName, "Clean.bat"))) + ProjectPlatformConfiguration.ToString()); if (bIsProjectTarget) { VCProjectFileContent.Append(" " + UProjectPath + (UnrealBuildTool.RunningRocket() ? " -rocket" : "")); } VCProjectFileContent.Append("</NMakeCleanCommandLine>" + ProjectFileGenerator.NewLine); VCProjectFileContent.Append(" <NMakeOutput>"); VCProjectFileContent.Append(NormalizeProjectPath(NMakePath)); VCProjectFileContent.Append("</NMakeOutput>" + ProjectFileGenerator.NewLine); } VCProjectFileContent.Append(" </PropertyGroup>" + ProjectFileGenerator.NewLine); if (VCUserFileContent != null) { if (UnrealBuildTool.HasUProjectFile()) { if ((Platform == UnrealTargetPlatform.Win32) || (Platform == UnrealTargetPlatform.Win64)) { VCUserFileContent.Append( " <PropertyGroup " + ConditionString + ">" + ProjectFileGenerator.NewLine); if ((TargetRulesObject.Type != TargetRules.TargetType.RocketGame) && (TargetRulesObject.Type != TargetRules.TargetType.Game)) { string DebugOptions = UProjectPath; if(DebugOptions.Length == 0 && TargetRulesObject.Type == TargetRules.TargetType.Editor && ProjectName != "UE4") { DebugOptions += ProjectName; } if (Configuration == UnrealTargetConfiguration.Debug || Configuration == UnrealTargetConfiguration.DebugGame) { DebugOptions += " -debug"; } else if (Configuration == UnrealTargetConfiguration.Shipping) { DebugOptions += " -shipping"; } VCUserFileContent.Append( " <LocalDebuggerCommandArguments>" + DebugOptions + "</LocalDebuggerCommandArguments>" + ProjectFileGenerator.NewLine ); } VCUserFileContent.Append( " <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>" + ProjectFileGenerator.NewLine ); VCUserFileContent.Append( " </PropertyGroup>" + ProjectFileGenerator.NewLine ); } } string PlatformUserFileStrings = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioUserFileStrings(Platform, Configuration, ConditionString, TargetRulesObject, TargetFilePath, ProjectFilePath) : ""; VCUserFileContent.Append(PlatformUserFileStrings); } } string LayoutDirString = (ProjGenerator != null) ? ProjGenerator.GetVisualStudioLayoutDirSection(Platform, Configuration, ConditionString, TargetRulesObject.Type, TargetFilePath, ProjectFilePath) : ""; VCProjectFileContent.Append(LayoutDirString); }
/// <summary> /// Determine if a plugin is enabled for a given project /// </summary> /// <param name="Project">The project to check</param> /// <param name="Plugin">Information about the plugin</param> /// <param name="Platform">The target platform</param> /// <returns>True if the plugin should be enabled for this project</returns> public static bool IsPluginEnabledForProject(PluginInfo Plugin, ProjectDescriptor Project, UnrealTargetPlatform Platform, TargetRules.TargetType Target) { bool bEnabled = Plugin.Descriptor.bEnabledByDefault; if (Project != null && Project.Plugins != null) { foreach (PluginReferenceDescriptor PluginReference in Project.Plugins) { if (String.Compare(PluginReference.Name, Plugin.Name, true) == 0) { bEnabled = PluginReference.IsEnabledForPlatform(Platform) && PluginReference.IsEnabledForTarget(Target); } } } return bEnabled; }
private void AddProjectsForAllTargets( PlatformProjectGeneratorCollection PlatformProjectGenerators, List <FileReference> AllGames, out ProjectFile EngineProject, out List <ProjectFile> GameProjects, out Dictionary <FileReference, ProjectFile> ProgramProjects) { // As we're creating project files, we'll also keep track of whether we created an "engine" project and return that if we have one EngineProject = null; GameProjects = new List <ProjectFile>(); ProgramProjects = new Dictionary <FileReference, ProjectFile>(); // Find all of the target files. This will filter out any modules or targets that don't // belong to platforms we're generating project files for. List <FileReference> AllTargetFiles = DiscoverTargets(AllGames); // Sort the targets by name. When we have multiple targets of a given type for a project, we'll use the order to determine which goes in the primary project file (so that client names with a suffix will go into their own project). AllTargetFiles = AllTargetFiles.OrderBy(x => x.FullName, StringComparer.OrdinalIgnoreCase).ToList(); foreach (FileReference TargetFilePath in AllTargetFiles) { string TargetName = TargetFilePath.GetFileNameWithoutAnyExtensions(); // Check to see if this is an Engine target. That is, the target is located under the "Engine" folder bool IsEngineTarget = false; bool IsEnterpriseTarget = false; bool WantProjectFileForTarget = true; if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EngineDirectory)) { // This is an engine target IsEngineTarget = true; if (TargetFilePath.IsUnderDirectory(EngineSourceProgramsDirectory)) { WantProjectFileForTarget = IncludeEnginePrograms; } else if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EngineSourceDirectory)) { WantProjectFileForTarget = bIncludeEngineSource; } } else if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EnterpriseSourceDirectory)) { // This is an enterprise target IsEnterpriseTarget = true; if (TargetFilePath.IsUnderDirectory(EnterpriseSourceProgramsDirectory)) { WantProjectFileForTarget = bIncludeEnterpriseSource && IncludeEnginePrograms; } else { WantProjectFileForTarget = bIncludeEnterpriseSource; } } if (WantProjectFileForTarget) { RulesAssembly RulesAssembly; FileReference CheckProjectFile = AllGames.FirstOrDefault(x => TargetFilePath.IsUnderDirectory(x.Directory)); if (CheckProjectFile == null) { if (TargetFilePath.IsUnderDirectory(UnrealBuildTool.EnterpriseDirectory)) { RulesAssembly = RulesCompiler.CreateEnterpriseRulesAssembly(false, false); } else { RulesAssembly = RulesCompiler.CreateEngineRulesAssembly(false, false); } } else { RulesAssembly = RulesCompiler.CreateProjectRulesAssembly(CheckProjectFile, false, false); } // Create target rules for all of the platforms and configuration combinations that we want to enable support for. // Just use the current platform as we only need to recover the target type and both should be supported for all targets... TargetRules TargetRulesObject = RulesAssembly.CreateTargetRules(TargetName, BuildHostPlatform.Current.Platform, UnrealTargetConfiguration.Development, "", CheckProjectFile, null); bool IsProgramTarget = false; DirectoryReference GameFolder = null; string ProjectFileNameBase; if (TargetRulesObject.Type == TargetType.Program) { IsProgramTarget = true; ProjectFileNameBase = TargetName; } else if (IsEngineTarget) { ProjectFileNameBase = EngineProjectFileNameBase; } else if (IsEnterpriseTarget) { ProjectFileNameBase = EnterpriseProjectFileNameBase; } else { // Figure out which game project this target belongs to FileReference ProjectInfo = FindGameContainingFile(AllGames, TargetFilePath); if (ProjectInfo == null) { throw new BuildException("Found a non-engine target file (" + TargetFilePath + ") that did not exist within any of the known game folders"); } GameFolder = ProjectInfo.Directory; ProjectFileNameBase = ProjectInfo.GetFileNameWithoutExtension(); } // Get the suffix to use for this project file. If we have multiple targets of the same type, we'll have to split them out into separate IDE project files. string GeneratedProjectName = TargetRulesObject.GeneratedProjectName; if (GeneratedProjectName == null) { ProjectFile ExistingProjectFile; if (ProjectFileMap.TryGetValue(GetRiderProjectLocation(ProjectFileNameBase), out ExistingProjectFile) && ExistingProjectFile.ProjectTargets.Any(x => x.TargetRules.Type == TargetRulesObject.Type)) { GeneratedProjectName = TargetRulesObject.Name; } else { GeneratedProjectName = ProjectFileNameBase; } } FileReference ProjectFilePath = GetRiderProjectLocation(GeneratedProjectName); if (TargetRulesObject.Type == TargetType.Game || TargetRulesObject.Type == TargetType.Client || TargetRulesObject.Type == TargetType.Server) { // Allow platforms to generate stub projects here... PlatformProjectGenerators.GenerateGameProjectStubs( InGenerator: this, InTargetName: TargetName, InTargetFilepath: TargetFilePath.FullName, InTargetRules: TargetRulesObject, InPlatforms: SupportedPlatforms, InConfigurations: SupportedConfigurations); } DirectoryReference BaseFolder; if (IsProgramTarget) { BaseFolder = TargetFilePath.Directory; } else if (IsEngineTarget) { BaseFolder = UnrealBuildTool.EngineDirectory; } else if (IsEnterpriseTarget) { BaseFolder = UnrealBuildTool.EnterpriseDirectory; } else { BaseFolder = GameFolder; } bool bProjectAlreadyExisted; ProjectFile ProjectFile = FindOrAddProject(ProjectFilePath, BaseFolder, true, out bProjectAlreadyExisted); ProjectFile.IsForeignProject = CheckProjectFile != null && !NativeProjects.IsNativeProject(CheckProjectFile); ProjectFile.IsGeneratedProject = true; ProjectFile.IsStubProject = UnrealBuildTool.IsProjectInstalled(); if (TargetRulesObject.bBuildInSolutionByDefault.HasValue) { ProjectFile.ShouldBuildByDefaultForSolutionTargets = TargetRulesObject.bBuildInSolutionByDefault.Value; } // Add the project to the right output list if (IsProgramTarget) { ProgramProjects[TargetFilePath] = ProjectFile; } else if (IsEngineTarget) { EngineProject = ProjectFile; if (UnrealBuildTool.IsEngineInstalled()) { // Allow engine projects to be created but not built for Installed Engine builds EngineProject.IsForeignProject = false; EngineProject.IsGeneratedProject = true; EngineProject.IsStubProject = true; } } else if (IsEnterpriseTarget) { ProjectFile EnterpriseProject = ProjectFile; if (UnrealBuildTool.IsEnterpriseInstalled()) { // Allow enterprise projects to be created but not built for Installed Engine builds EnterpriseProject.IsForeignProject = false; EnterpriseProject.IsGeneratedProject = true; EnterpriseProject.IsStubProject = true; } } else { if (!bProjectAlreadyExisted) { GameProjects.Add(ProjectFile); // Add the .uproject file for this game/template FileReference UProjectFilePath = FileReference.Combine(BaseFolder, ProjectFileNameBase + ".uproject"); if (FileReference.Exists(UProjectFilePath)) { ProjectFile.AddFileToProject(UProjectFilePath, BaseFolder); } else { throw new BuildException( "Not expecting to find a game with no .uproject file. File '{0}' doesn't exist", UProjectFilePath); } } } foreach (ProjectTarget ExistingProjectTarget in ProjectFile.ProjectTargets) { if (ExistingProjectTarget.TargetRules.Type == TargetRulesObject.Type) { throw new BuildException( "Not expecting project {0} to already have a target rules of with configuration name {1} ({2}) while trying to add: {3}", ProjectFilePath, TargetRulesObject.Type.ToString(), ExistingProjectTarget.TargetRules.ToString(), TargetRulesObject.ToString()); } // Not expecting to have both a game and a program in the same project. These would alias because we share the project and solution configuration names (just because it makes sense to) if ((ExistingProjectTarget.TargetRules.Type == TargetType.Game && TargetRulesObject.Type == TargetType.Program) || (ExistingProjectTarget.TargetRules.Type == TargetType.Program && TargetRulesObject.Type == TargetType.Game)) { throw new BuildException( "Not expecting project {0} to already have a Game/Program target ({1}) associated with it while trying to add: {2}", ProjectFilePath, ExistingProjectTarget.TargetRules.ToString(), TargetRulesObject.ToString()); } } ProjectTarget ProjectTarget = new ProjectTarget() { TargetRules = TargetRulesObject, TargetFilePath = TargetFilePath, ProjectFilePath = ProjectFilePath, UnrealProjectFilePath = CheckProjectFile, SupportedPlatforms = TargetRulesObject.GetSupportedPlatforms() .Where(x => UEBuildPlatform.GetBuildPlatform(x, true) != null).ToArray(), CreateRulesDelegate = (Platform, Configuration) => RulesAssembly.CreateTargetRules(TargetName, Platform, Configuration, "", CheckProjectFile, null) }; ProjectFile.ProjectTargets.Add(ProjectTarget); // Make sure the *.Target.cs file is in the project. ProjectFile.AddFileToProject(TargetFilePath, BaseFolder); Log.TraceVerbose("Generating target {0} for {1}", TargetRulesObject.Type.ToString(), ProjectFilePath); } } }
public UEBuildEditor(TargetDescriptor InDesc, TargetRules InRulesObject, RulesAssembly InRulesAssembly, FileReference InTargetCsFilename) : base(InDesc, InRulesObject, InRulesAssembly, "UE4Editor", InTargetCsFilename) { }
public override void ResetTarget(TargetRules Target) { ValidateTarget(Target); }
/// <summary> /// Constructor /// </summary> /// <param name="Inner">The TargetRules instance to wrap around</param> public ReadOnlyTargetRules(TargetRules Inner) { this.Inner = Inner; }
/// <summary> /// Construct an instance of the given target rules /// </summary> /// <param name="TypeName">Type name of the target rules</param> /// <param name="TargetInfo">Target configuration information to pass to the constructor</param> /// <param name="Arguments">Command line arguments for this target</param> /// <returns>Instance of the corresponding TargetRules</returns> protected TargetRules CreateTargetRulesInstance(string TypeName, TargetInfo TargetInfo, CommandLineArguments Arguments) { // The build module must define a type named '<TargetName>Target' that derives from our 'TargetRules' type. Type RulesType = CompiledAssembly.GetType(TypeName); if (RulesType == null) { throw new BuildException("Expecting to find a type to be declared in a target rules named '{0}'. This type must derive from the 'TargetRules' type defined by Unreal Build Tool.", TypeName); } // Create an instance of the module's rules object, and set some defaults before calling the constructor. TargetRules Rules = (TargetRules)FormatterServices.GetUninitializedObject(RulesType); Rules.bUseBackwardsCompatibleDefaults = bUseBackwardsCompatibleDefaults; // Find the constructor ConstructorInfo Constructor = RulesType.GetConstructor(new Type[] { typeof(TargetInfo) }); if (Constructor == null) { throw new BuildException("No constructor found on {0} which takes an argument of type TargetInfo.", RulesType.Name); } // Invoke the regular constructor try { Constructor.Invoke(Rules, new object[] { TargetInfo }); } catch (Exception Ex) { throw new BuildException(Ex, "Unable to instantiate instance of '{0}' object type from compiled assembly '{1}'. Unreal Build Tool creates an instance of your module's 'Rules' object in order to find out about your module's requirements. The CLR exception details may provide more information: {2}", TypeName, Path.GetFileNameWithoutExtension(CompiledAssembly.Location), Ex.ToString()); } // Return the target file name to the caller Rules.File = TargetNameToTargetFile[TargetInfo.Name]; // Set the default overriddes for the configured target type Rules.SetOverridesForTargetType(); // Parse any additional command-line arguments. These override default settings specified in config files or the .target.cs files. if (Arguments != null) { foreach (object ConfigurableObject in Rules.GetConfigurableObjects()) { Arguments.ApplyTo(ConfigurableObject); } } // Set the final value for the link type in the target rules if (Rules.LinkType == TargetLinkType.Default) { throw new BuildException("TargetRules.LinkType should be inferred from TargetType"); } // Set the default value for whether to use the shared build environment if (Rules.BuildEnvironment == TargetBuildEnvironment.Default) { if (Rules.Type == TargetType.Program && TargetInfo.ProjectFile != null && TargetNameToTargetFile[Rules.Name].IsUnderDirectory(TargetInfo.ProjectFile.Directory)) { Rules.BuildEnvironment = TargetBuildEnvironment.Unique; } else if (UnrealBuildTool.IsEngineInstalled() || Rules.LinkType != TargetLinkType.Monolithic) { Rules.BuildEnvironment = TargetBuildEnvironment.Shared; } else { Rules.BuildEnvironment = TargetBuildEnvironment.Unique; } } // Automatically include CoreUObject if (Rules.bCompileAgainstEngine) { Rules.bCompileAgainstCoreUObject = true; } // Must have editor only data if building the editor. if (Rules.bBuildEditor) { Rules.bBuildWithEditorOnlyData = true; } // Apply the override to force debug info to be enabled if (Rules.bForceDebugInfo) { Rules.bDisableDebugInfo = false; Rules.bOmitPCDebugInfoInDevelopment = false; } // Setup the malloc profiler if (Rules.bUseMallocProfiler) { Rules.bOmitFramePointers = false; Rules.GlobalDefinitions.Add("USE_MALLOC_PROFILER=1"); } // Set a macro if we allow using generated inis if (!Rules.bAllowGeneratedIniWhenCooked) { Rules.GlobalDefinitions.Add("DISABLE_GENERATED_INI_WHEN_COOKED=1"); } if (!Rules.bAllowNonUFSIniWhenCooked) { Rules.GlobalDefinitions.Add("DISABLE_NONUFS_INI_WHEN_COOKED=1"); } if (Rules.bDisableUnverifiedCertificates) { Rules.GlobalDefinitions.Add("DISABLE_UNVERIFIED_CERTIFICATE_LOADING=1"); } // Allow the platform to finalize the settings UEBuildPlatform Platform = UEBuildPlatform.GetBuildPlatform(Rules.Platform); Platform.ValidateTarget(Rules); // Some platforms may *require* monolithic compilation... if (Rules.LinkType != TargetLinkType.Monolithic && UEBuildPlatform.PlatformRequiresMonolithicBuilds(Rules.Platform, Rules.Configuration)) { throw new BuildException(String.Format("{0}: {1} does not support modular builds", Rules.Name, Rules.Platform)); } return(Rules); }
protected static bool GetTargetTypeAndRulesInstance(string InTargetName, TargetInfo InTarget, out System.Type OutRulesObjectType, out TargetRules OutRulesObject) { // The build module must define a type named '<TargetName>Target' that derives from our 'TargetRules' type. OutRulesObjectType = RulesAssembly.GetType(InTargetName); if (OutRulesObjectType == null) { throw new BuildException( "Expecting to find a type to be declared in a target rules named '{0}'. This type must derive from the 'TargetRules' type defined by Unreal Build Tool.", InTargetName); } // Create an instance of the module's rules object try { OutRulesObject = (TargetRules)Activator.CreateInstance(OutRulesObjectType, InTarget); } catch (Exception Ex) { var AssemblyFileName = Path.GetFileNameWithoutExtension(RulesAssembly.Location); throw new BuildException(Ex, "Unable to instantiate instance of '{0}' object type from compiled assembly '{1}'. Unreal Build Tool creates an instance of your module's 'Rules' object in order to find out about your module's requirements. The CLR exception details may provide more information: {2}", InTargetName, AssemblyFileName, Ex.ToString()); } OutRulesObject.TargetName = InTargetName; return true; }
/// <summary> /// Creates a context for the given target on the current platform. /// </summary> /// <param name="ProjectFile">The project file for the current target</param> /// <param name="Target">Rules for the target being built</param> /// <returns>New platform context object</returns> public override UEBuildPlatformContext CreateContext(FileReference ProjectFile, TargetRules Target) { return(new LinuxPlatformContext(ProjectFile)); }
public virtual void GenerateGameProjectStub(ProjectFileGenerator InGenerator, string InTargetName, string InTargetFilepath, TargetRules InTargetRules, List<UnrealTargetPlatform> InPlatforms, List<UnrealTargetConfiguration> InConfigurations) { // Do nothing }
public static void GetTargetUWPPaths(RulesAssembly InTargetRulesAssembly, string InTargetName, TargetRules InTargetRules, out string OutEngineSourceRelativeBinaryPath, out string OutRelativeTargetPath) { OutEngineSourceRelativeBinaryPath = ""; OutRelativeTargetPath = ""; string TargetFilename = InTargetRulesAssembly.GetTargetFileName(InTargetName).FullName; string ProjectSourceFolder = new FileInfo(TargetFilename).DirectoryName; string EnginePath = Path.Combine(ProjectFileGenerator.EngineRelativePath); string EngineSourcePath = Path.Combine(EnginePath, "Source"); string RelativeTargetFilename = Utils.MakePathRelativeTo(TargetFilename, EngineSourcePath); if ((RelativeTargetFilename.StartsWith("..") == false) && (RelativeTargetFilename.Contains(":") == false)) { // This target must be UNDER Engine/Source... RelativeTargetFilename = Path.Combine(EngineSourcePath, RelativeTargetFilename); } RelativeTargetFilename = RelativeTargetFilename.Replace("\\", "/"); EnginePath = EnginePath.Replace("\\", "/"); Int32 LastSourceIdx = RelativeTargetFilename.LastIndexOf("Source"); if (LastSourceIdx != -1) { RelativeTargetFilename = RelativeTargetFilename.Substring(0, LastSourceIdx); } else { RelativeTargetFilename = ""; } OutRelativeTargetPath = RelativeTargetFilename; if (InTargetRules.bOutputToEngineBinaries) { RelativeTargetFilename = EnginePath; } OutEngineSourceRelativeBinaryPath = Path.Combine(RelativeTargetFilename, "Binaries/UWP/"); OutEngineSourceRelativeBinaryPath = OutEngineSourceRelativeBinaryPath.Replace("\\", "/"); }
/// <summary> /// Return any custom paths for VisualStudio this platform requires /// This include ReferencePath, LibraryPath, LibraryWPath, IncludePath and ExecutablePath. /// </summary> /// <param name="InPlatform"> The UnrealTargetPlatform being built</param> /// <param name="TargetType"> The type of target (game or program)</param> /// <returns>string The custom path lines for the project file; Empty string if it doesn't require one</returns> public virtual string GetVisualStudioPathsEntries(UnrealTargetPlatform InPlatform, UnrealTargetConfiguration InConfiguration, TargetRules.TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath, FileReference 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; }
/** * Setup the target environment for building * * @param InBuildTarget The target being built */ public override void SetUpEnvironment(UEBuildTarget InBuildTarget) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WIN32=1"); // Win32 XP is only supported at this time. SupportWindowsXP = SupportWindowsXP && InBuildTarget.Platform == UnrealTargetPlatform.Win32; if (SupportWindowsXP) { // Windows XP SP3 or higher required InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0502"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0502"); } else { // Windows Vista or higher required InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("_WIN32_WINNT=0x0600"); InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("WINVER=0x0600"); } InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("PLATFORM_WINDOWS=1"); String MorpheusShaderPath = Path.Combine(BuildConfiguration.RelativeEnginePath, "Shaders/PS4/PostProcessHMDMorpheus.usf"); if (File.Exists(MorpheusShaderPath)) { InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Add("HAS_MORPHEUS=1"); } if (InBuildTarget.Rules != null) { // Explicitly exclude the MS C++ runtime libraries we're not using, to ensure other libraries we link with use the same // runtime library as the engine. bool bUseDebugCRT = InBuildTarget.Configuration == UnrealTargetConfiguration.Debug && BuildConfiguration.bDebugBuildsActuallyUseDebugCRT; if (!InBuildTarget.Rules.bUseStaticCRT || bUseDebugCRT) { InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCMT"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCPMT"); } if (!InBuildTarget.Rules.bUseStaticCRT || !bUseDebugCRT) { InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCMTD"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCPMTD"); } if (InBuildTarget.Rules.bUseStaticCRT || bUseDebugCRT) { InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("MSVCRT"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("MSVCPRT"); } if (InBuildTarget.Rules.bUseStaticCRT || !bUseDebugCRT) { InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("MSVCRTD"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("MSVCPRTD"); } InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBC"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCP"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCD"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("LIBCPD"); //@todo ATL: Currently, only VSAccessor requires ATL (which is only used in editor builds) // When compiling games, we do not want to include ATL - and we can't when compiling Rocket games // due to VS 2012 Express not including ATL. // If more modules end up requiring ATL, this should be refactored into a BuildTarget flag (bNeedsATL) // that is set by the modules the target includes to allow for easier tracking. // Alternatively, if VSAccessor is modified to not require ATL than we should always exclude the libraries. if (InBuildTarget.ShouldCompileMonolithic() && (InBuildTarget.Rules != null) && (TargetRules.IsGameType(InBuildTarget.TargetType)) && (TargetRules.IsEditorType(InBuildTarget.TargetType) == false)) { InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("atl"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("atls"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("atlsd"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("atlsn"); InBuildTarget.GlobalLinkEnvironment.Config.ExcludedLibraries.Add("atlsnd"); } // Add the library used for the delayed loading of DLLs. InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("delayimp.lib"); //@todo - remove once FB implementation uses Http module if (UEBuildConfiguration.bCompileAgainstEngine) { // link against wininet (used by FBX and Facebook) InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("wininet.lib"); } // Compile and link with Win32 API libraries. InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("rpcrt4.lib"); //InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("wsock32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("ws2_32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("dbghelp.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("comctl32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("Winmm.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("kernel32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("user32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("gdi32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("winspool.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("comdlg32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("advapi32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("shell32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("ole32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("oleaut32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("uuid.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("odbc32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("odbccp32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("netapi32.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("iphlpapi.lib"); InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("setupapi.lib"); // Required for access monitor device enumeration // Windows Vista/7 Desktop Windows Manager API for Slate Windows Compliance if (!SupportWindowsXP) // Windows XP does not support DWM { InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("dwmapi.lib"); } // IME InBuildTarget.GlobalLinkEnvironment.Config.AdditionalLibraries.Add("imm32.lib"); // Setup assembly path for .NET modules. This will only be used when CLR is enabled. (CPlusPlusCLR module types) InBuildTarget.GlobalCompileEnvironment.Config.SystemDotNetAssemblyPaths.Add( Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86) + "/Reference Assemblies/Microsoft/Framework/.NETFramework/v4.0"); // Setup default assemblies for .NET modules. These will only be used when CLR is enabled. (CPlusPlusCLR module types) InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.Data.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.Drawing.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.Xml.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.Management.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("System.Windows.Forms.dll"); InBuildTarget.GlobalCompileEnvironment.Config.FrameworkAssemblyDependencies.Add("WindowsBase.dll"); } // Disable Simplygon support if compiling against the NULL RHI. if (InBuildTarget.GlobalCompileEnvironment.Config.Definitions.Contains("USE_NULL_RHI=1")) { UEBuildConfiguration.bCompileSimplygon = false; } // For 64-bit builds, we'll forcibly ignore a linker warning with DirectInput. This is // Microsoft's recommended solution as they don't have a fixed .lib for us. if (InBuildTarget.Platform == UnrealTargetPlatform.Win64) { InBuildTarget.GlobalLinkEnvironment.Config.AdditionalArguments += " /ignore:4078"; } }
/// <summary> /// Get the output manifest section, if required /// </summary> /// <param name="InPlatform"> The UnrealTargetPlatform being built</param> /// <returns>string The output manifest section for the project file; Empty string if it doesn't require one</returns> public virtual string GetVisualStudioOutputManifestSection(UnrealTargetPlatform InPlatform, TargetRules.TargetType TargetType, FileReference TargetRulesPath, FileReference ProjectFilePath) { return ""; }
public virtual void GenerateGameProjectStub(ProjectFileGenerator InGenerator, string InTargetName, string InTargetFilepath, TargetRules InTargetRules, List <UnrealTargetPlatform> InPlatforms, List <UnrealTargetConfiguration> InConfigurations) { // Do nothing }
/// <summary> /// Creates a target rules object for the specified target name. /// </summary> /// <param name="TargetName">Name of the target</param> /// <param name="Platform">Platform being compiled</param> /// <param name="Configuration">Configuration being compiled</param> /// <param name="Architecture">Architecture being built</param> /// <param name="ProjectFile">Path to the project file for this target</param> /// <param name="bInEditorRecompile">Whether this is an editor recompile, where we need to guess the name of the editor target</param> /// <param name="TargetFileName">The original source file name of the Target.cs file for this target</param> /// <returns>The build target rules for the specified target</returns> public TargetRules CreateTargetRules(string TargetName, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, string Architecture, FileReference ProjectFile, bool bInEditorRecompile, out FileReference TargetFileName) { // Make sure the target file is known to us bool bFoundTargetName = TargetNameToTargetFile.ContainsKey(TargetName); if (bFoundTargetName == false) { if (Parent == null) { // throw new BuildException("Couldn't find target rules file for target '{0}' in rules assembly '{1}'.", TargetName, RulesAssembly.FullName); string ExceptionMessage = "Couldn't find target rules file for target '"; ExceptionMessage += TargetName; ExceptionMessage += "' in rules assembly '"; ExceptionMessage += CompiledAssembly.FullName; ExceptionMessage += "'." + Environment.NewLine; ExceptionMessage += "Location: " + CompiledAssembly.Location + Environment.NewLine; ExceptionMessage += "Target rules found:" + Environment.NewLine; foreach (KeyValuePair <string, FileReference> entry in TargetNameToTargetFile) { ExceptionMessage += "\t" + entry.Key + " - " + entry.Value + Environment.NewLine; } throw new BuildException(ExceptionMessage); } else { return(Parent.CreateTargetRules(TargetName, Platform, Configuration, Architecture, ProjectFile, bInEditorRecompile, out TargetFileName)); } } // Return the target file name to the caller TargetFileName = TargetNameToTargetFile[TargetName]; // Currently, we expect the user's rules object type name to be the same as the module name + 'Target' string TargetTypeName = TargetName + "Target"; // The build module must define a type named '<TargetName>Target' that derives from our 'TargetRules' type. TargetRules RulesObject = CreateTargetRulesInstance(TargetTypeName, new TargetInfo(TargetName, Platform, Configuration, Architecture, ProjectFile)); if (bInEditorRecompile) { // Make sure this is an editor module. if (RulesObject != null) { if (RulesObject.Type != TargetType.Editor) { // Not the editor... determine the editor project string TargetSourceFolderString = TargetFileName.FullName; Int32 SourceFolderIndex = -1; if (Utils.IsRunningOnMono) { TargetSourceFolderString = TargetSourceFolderString.Replace("\\", "/"); SourceFolderIndex = TargetSourceFolderString.LastIndexOf("/Source/", StringComparison.InvariantCultureIgnoreCase); } else { TargetSourceFolderString = TargetSourceFolderString.Replace("/", "\\"); SourceFolderIndex = TargetSourceFolderString.LastIndexOf("\\Source\\", StringComparison.InvariantCultureIgnoreCase); } if (SourceFolderIndex != -1) { DirectoryReference TargetSourceFolder = new DirectoryReference(TargetSourceFolderString.Substring(0, SourceFolderIndex + 7)); foreach (KeyValuePair <string, FileReference> CheckEntry in TargetNameToTargetFile) { if (CheckEntry.Value.IsUnderDirectory(TargetSourceFolder)) { if (CheckEntry.Key.Equals(TargetName, StringComparison.InvariantCultureIgnoreCase) == false) { // We have found a target in the same source folder that is not the original target found. // See if it is the editor project string CheckTargetTypeName = CheckEntry.Key + "Target"; TargetRules CheckRulesObject = CreateTargetRulesInstance(CheckTargetTypeName, new TargetInfo(CheckEntry.Key, Platform, Configuration, Architecture, ProjectFile)); if (CheckRulesObject != null) { if (CheckRulesObject.Type == TargetType.Editor) { // Found it // NOTE: This prevents multiple Editor targets from co-existing... RulesObject = CheckRulesObject; break; } } } } } } } } } return(RulesObject); }
/// <summary> /// Validate a target's settings /// </summary> public virtual void ValidateTarget(TargetRules Target) { }
/// <summary> /// Determines whether the given plugin module is part of the current build. /// </summary> /// <param name="Platform">The platform being compiled for</param> /// <param name="TargetType">The type of the target being compiled</param> /// <param name="bBuildDeveloperTools">Whether the configuration includes developer tools (typically UEBuildConfiguration.bBuildDeveloperTools for UBT callers)</param> /// <param name="bBuildEditor">Whether the configuration includes the editor (typically UEBuildConfiguration.bBuildEditor for UBT callers)</param> public bool IsCompiledInConfiguration(UnrealTargetPlatform Platform, TargetRules.TargetType TargetType, bool bBuildDeveloperTools, bool bBuildEditor) { // Check the platform is whitelisted if (WhitelistPlatforms != null && WhitelistPlatforms.Length > 0 && !WhitelistPlatforms.Contains(Platform)) { return false; } // Check the platform is not blacklisted if (BlacklistPlatforms != null && BlacklistPlatforms.Contains(Platform)) { return false; } // Check the module is compatible with this target. switch (Type) { case ModuleHostType.Runtime: case ModuleHostType.RuntimeNoCommandlet: return TargetType != TargetRules.TargetType.Program; case ModuleHostType.RuntimeAndProgram: return true; case ModuleHostType.Developer: return bBuildDeveloperTools; case ModuleHostType.Editor: case ModuleHostType.EditorNoCommandlet: return TargetType == TargetRules.TargetType.Editor || bBuildEditor; case ModuleHostType.Program: return TargetType == TargetRules.TargetType.Program; case ModuleHostType.ServerOnly: return TargetType != TargetRules.TargetType.Client; case ModuleHostType.ClientOnly: return TargetType != TargetRules.TargetType.Server; } return false; }
private FileReference GetExecutableFilename(ProjectFile Project, ProjectTarget Target, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration) { TargetRules TargetRulesObject = Target.TargetRules; FileReference TargetFilePath = Target.TargetFilePath; string TargetName = TargetFilePath == null?Project.ProjectFilePath.GetFileNameWithoutExtension() : TargetFilePath.GetFileNameWithoutAnyExtensions(); string UBTPlatformName = Platform.ToString(); string UBTConfigurationName = Configuration.ToString(); string ProjectName = Project.ProjectFilePath.GetFileNameWithoutExtension(); // Setup output path UEBuildPlatform BuildPlatform = UEBuildPlatform.GetBuildPlatform(Platform); // Figure out if this is a monolithic build bool bShouldCompileMonolithic = BuildPlatform.ShouldCompileMonolithicBinary(Platform); if (TargetRulesObject != null) { bShouldCompileMonolithic |= (Target.CreateRulesDelegate(Platform, Configuration).GetLegacyLinkType(Platform, Configuration) == TargetLinkType.Monolithic); } TargetType TargetRulesType = Target.TargetRules == null ? TargetType.Program : Target.TargetRules.Type; // Get the output directory DirectoryReference RootDirectory = UnrealBuildTool.EngineDirectory; if (TargetRulesType != TargetType.Program && (bShouldCompileMonolithic || TargetRulesObject.BuildEnvironment == TargetBuildEnvironment.Unique) && !TargetRulesObject.bOutputToEngineBinaries) { if (OnlyGameProject != null && TargetFilePath.IsUnderDirectory(OnlyGameProject.Directory)) { RootDirectory = OnlyGameProject.Directory; } else { FileReference ProjectFileName; if (UProjectInfo.TryGetProjectFileName(ProjectName, out ProjectFileName)) { RootDirectory = ProjectFileName.Directory; } } } if (TargetRulesType == TargetType.Program && (TargetRulesObject == null || !TargetRulesObject.bOutputToEngineBinaries)) { FileReference ProjectFileName; if (UProjectInfo.TryGetProjectForTarget(TargetName, out ProjectFileName)) { RootDirectory = ProjectFileName.Directory; } } // Get the output directory DirectoryReference OutputDirectory = DirectoryReference.Combine(RootDirectory, "Binaries", UBTPlatformName); // Get the executable name (minus any platform or config suffixes) string BaseExeName = TargetName; if (!bShouldCompileMonolithic && TargetRulesType != TargetType.Program) { // Figure out what the compiled binary will be called so that we can point the IDE to the correct file string TargetConfigurationName = TargetRulesType.ToString(); if (TargetConfigurationName != TargetType.Game.ToString() && TargetConfigurationName != TargetType.Program.ToString()) { BaseExeName = "UE4" + TargetConfigurationName; } } // Make the output file path string ExecutableFilename = FileReference.Combine(OutputDirectory, BaseExeName).ToString(); if ((Configuration != UnrealTargetConfiguration.DebugGame || bShouldCompileMonolithic)) { ExecutableFilename += "-" + UBTPlatformName + "-" + UBTConfigurationName; } ExecutableFilename += TargetRulesObject.Architecture; ExecutableFilename += BuildPlatform.GetBinaryExtension(UEBuildBinaryType.Executable); return(FileReference.MakeFromNormalizedFullPath(ExecutableFilename)); }