static List <UnrealTargetPlatform> GetTargetPlatforms(BuildCommand Command, UnrealTargetPlatform HostPlatform) { List <UnrealTargetPlatform> TargetPlatforms = new List <UnrealTargetPlatform>(); if (!Command.ParseParam("NoTargetPlatforms")) { // Only interested in building for Platforms that support code projects TargetPlatforms = PlatformExports.GetRegisteredPlatforms().Where(x => InstalledPlatformInfo.IsValidPlatform(x, EProjectType.Code)).ToList(); // only build Mac on Mac if (HostPlatform != UnrealTargetPlatform.Mac && TargetPlatforms.Contains(UnrealTargetPlatform.Mac)) { TargetPlatforms.Remove(UnrealTargetPlatform.Mac); } // only build Windows on Windows if (HostPlatform != UnrealTargetPlatform.Win64 && TargetPlatforms.Contains(UnrealTargetPlatform.Win64)) { TargetPlatforms.Remove(UnrealTargetPlatform.Win64); TargetPlatforms.Remove(UnrealTargetPlatform.Win32); } // build Linux on Windows and Linux if (HostPlatform != UnrealTargetPlatform.Win64 && HostPlatform != UnrealTargetPlatform.Linux) { if (TargetPlatforms.Contains(UnrealTargetPlatform.Linux)) { TargetPlatforms.Remove(UnrealTargetPlatform.Linux); } if (TargetPlatforms.Contains(UnrealTargetPlatform.LinuxAArch64)) { TargetPlatforms.Remove(UnrealTargetPlatform.LinuxAArch64); } } // Remove any platforms that aren't enabled on the command line string TargetPlatformFilter = Command.ParseParamValue("TargetPlatforms", null); if (TargetPlatformFilter != null) { List <UnrealTargetPlatform> NewTargetPlatforms = new List <UnrealTargetPlatform>(); foreach (string TargetPlatformName in TargetPlatformFilter.Split(new char[] { '+' }, StringSplitOptions.RemoveEmptyEntries)) { UnrealTargetPlatform TargetPlatform; if (!UnrealTargetPlatform.TryParse(TargetPlatformName, out TargetPlatform)) { throw new AutomationException("Unknown target platform '{0}' specified on command line", TargetPlatformName); } if (TargetPlatforms.Contains(TargetPlatform)) { NewTargetPlatforms.Add(TargetPlatform); } } TargetPlatforms = NewTargetPlatforms; } } return(TargetPlatforms); }
/// <summary> /// NOTE: This function must mirror the functionality of TargetPlatformBase::RequiresTempTarget /// </summary> private static bool RequiresTempTarget(FileReference RawProjectPath, bool bProjectHasCode, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, TargetType TargetType, bool bRequiresAssetNativization, bool bRequiresCookedData, out string OutReason) { // check to see if we already have a Target.cs file if (bProjectHasCode) { OutReason = null; return(false); } // check if asset nativization is enabled if (bRequiresAssetNativization) { OutReason = "asset nativization is enabled"; return(true); } // Check if encryption or signing is enabled EncryptionAndSigning.CryptoSettings Settings = EncryptionAndSigning.ParseCryptoSettings(RawProjectPath.Directory, Platform); if (Settings.IsAnyEncryptionEnabled() || Settings.IsPakSigningEnabled()) { OutReason = "encryption/signing is enabled"; return(true); } // check the target platforms for any differences in build settings or additional plugins if (!CommandUtils.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, Platform)) { OutReason = "project has non-default build configuration"; return(true); } if (PlatformExports.RequiresBuild(RawProjectPath, Platform)) { OutReason = "overriden by target platform"; return(true); } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); // Enumerate all the available plugins Dictionary <string, PluginInfo> AllPlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, DirectoryReference.FromFile(RawProjectPath), new List <DirectoryReference>()).ToDictionary(x => x.Name, x => x, StringComparer.OrdinalIgnoreCase); // find if there are any plugins enabled or disabled which differ from the default string Reason; if (RequiresTempTargetForCodePlugin(Project, Platform, Configuration, TargetType, AllPlugins, out Reason)) { OutReason = Reason; return(true); } OutReason = null; return(false); }
void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ReceiptFileNames, string InAdditionalArgs) { // Find a list of modules that need to be built for this plugin List <string> ModuleNames = new List <string>(); if (Plugin.Modules != null) { foreach (ModuleDescriptor Module in Plugin.Modules) { bool bBuildDeveloperTools = (TargetType == TargetType.Editor || TargetType == TargetType.Program); bool bBuildEditor = (TargetType == TargetType.Editor); bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program); if (Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor, bBuildRequiresCookedData)) { ModuleNames.Add(Module.Name); } } } // Add these modules to the build agenda if (ModuleNames.Count > 0) { string Arguments = "-iwyu"; // String.Format("-plugin={0}", CommandUtils.MakePathSafeToUseWithCommandLine(PluginFile.FullName)); foreach (string ModuleName in ModuleNames) { Arguments += String.Format(" -module={0}", ModuleName); } string Architecture = PlatformExports.GetDefaultArchitecture(Platform, HostProjectFile); FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(HostProjectPluginFile.Directory, TargetName, Platform, Configuration, Architecture); Arguments += String.Format(" -receipt={0}", CommandUtils.MakePathSafeToUseWithCommandLine(ReceiptFileName.FullName)); ReceiptFileNames.Add(ReceiptFileName); if (!String.IsNullOrEmpty(InAdditionalArgs)) { Arguments += InAdditionalArgs; } CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2}{3} {4}", TargetName, Platform, Configuration, (HostProjectFile == null)? "" : String.Format(" -project=\"{0}\"", HostProjectFile.FullName), Arguments)); } }
void CompilePluginWithUBT(FileReference HostProjectFile, FileReference HostProjectPluginFile, PluginDescriptor Plugin, string TargetName, TargetType TargetType, UnrealTargetPlatform Platform, UnrealTargetConfiguration Configuration, List <FileReference> ReceiptFileNames, string InAdditionalArgs) { // Find a list of modules that need to be built for this plugin bool bCompilePlatform = false; if (Plugin.Modules != null) { foreach (ModuleDescriptor Module in Plugin.Modules) { bool bBuildDeveloperTools = (TargetType == TargetType.Editor || TargetType == TargetType.Program); bool bBuildEditor = (TargetType == TargetType.Editor); bool bBuildRequiresCookedData = (TargetType != TargetType.Editor && TargetType != TargetType.Program); if (Module.IsCompiledInConfiguration(Platform, TargetType, bBuildDeveloperTools, bBuildEditor, bBuildRequiresCookedData)) { bCompilePlatform = true; } } } // Add these modules to the build agenda if (bCompilePlatform) { string Architecture = PlatformExports.GetDefaultArchitecture(Platform, HostProjectFile); FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(HostProjectPluginFile.Directory, TargetName, Platform, Configuration, Architecture); ReceiptFileNames.Add(ReceiptFileName); string Arguments = String.Format("-plugin {0} -iwyu -precompile -nosharedpch -noubtmakefiles -receipt {1}", CommandUtils.MakePathSafeToUseWithCommandLine(HostProjectPluginFile.FullName), CommandUtils.MakePathSafeToUseWithCommandLine(ReceiptFileName.FullName)); if (!String.IsNullOrEmpty(InAdditionalArgs)) { Arguments += InAdditionalArgs; } CommandUtils.RunUBT(CmdEnv, UE4Build.GetUBTExecutable(), String.Format("{0} {1} {2} {3}", TargetName, Platform, Configuration, Arguments)); } }
public DeploymentContext( FileReference RawProjectPathOrName, DirectoryReference InLocalRoot, DirectoryReference BaseStageDirectory, DirectoryReference BaseArchiveDirectory, Platform InSourcePlatform, Platform InTargetPlatform, List <UnrealTargetConfiguration> InTargetConfigurations, IEnumerable <StageTarget> InStageTargets, List <String> InStageExecutables, bool InServer, bool InCooked, bool InStageCrashReporter, bool InStage, bool InCookOnTheFly, bool InArchive, bool InProgram, bool IsClientInsteadOfNoEditor, bool InForceChunkManifests, bool InSeparateDebugStageDirectory ) { bStageCrashReporter = InStageCrashReporter; RawProjectPath = RawProjectPathOrName; DedicatedServer = InServer; LocalRoot = InLocalRoot; CookSourcePlatform = InSourcePlatform; StageTargetPlatform = InTargetPlatform; StageTargetConfigurations = new List <UnrealTargetConfiguration>(InTargetConfigurations); StageTargets = new List <StageTarget>(InStageTargets); StageExecutables = InStageExecutables; IsCodeBasedProject = ProjectUtils.IsCodeBasedUProjectFile(RawProjectPath, StageTargetConfigurations); ShortProjectName = ProjectUtils.GetShortProjectName(RawProjectPath); Stage = InStage; Archive = InArchive; if (CookSourcePlatform != null && InCooked) { CookPlatform = CookSourcePlatform.GetCookPlatform(DedicatedServer, IsClientInsteadOfNoEditor); } else if (CookSourcePlatform != null && InProgram) { CookPlatform = CookSourcePlatform.GetCookPlatform(false, false); } else { CookPlatform = ""; } if (StageTargetPlatform != null && InCooked) { FinalCookPlatform = StageTargetPlatform.GetCookPlatform(DedicatedServer, IsClientInsteadOfNoEditor); } else if (StageTargetPlatform != null && InProgram) { FinalCookPlatform = StageTargetPlatform.GetCookPlatform(false, false); } else { FinalCookPlatform = ""; } PlatformDir = StageTargetPlatform.PlatformType.ToString(); if (BaseStageDirectory != null) { StageDirectory = DirectoryReference.Combine(BaseStageDirectory, FinalCookPlatform); DebugStageDirectory = InSeparateDebugStageDirectory? DirectoryReference.Combine(BaseStageDirectory, FinalCookPlatform + "Debug") : StageDirectory; } if (BaseArchiveDirectory != null) { ArchiveDirectory = DirectoryReference.Combine(BaseArchiveDirectory, FinalCookPlatform); } if (!FileReference.Exists(RawProjectPath)) { throw new AutomationException("Can't find uproject file {0}.", RawProjectPathOrName); } EngineRoot = DirectoryReference.Combine(LocalRoot, "Engine"); ProjectRoot = RawProjectPath.Directory; RelativeProjectRootForStage = new StagedDirectoryReference(ShortProjectName); ProjectArgForCommandLines = CommandUtils.MakePathSafeToUseWithCommandLine(RawProjectPath.FullName); CookSourceRuntimeRootDir = RuntimeRootDir = LocalRoot; RuntimeProjectRootDir = ProjectRoot; if (Stage) { CommandUtils.CreateDirectory(StageDirectory.FullName); RuntimeRootDir = StageDirectory; CookSourceRuntimeRootDir = DirectoryReference.Combine(BaseStageDirectory, CookPlatform); RuntimeProjectRootDir = DirectoryReference.Combine(StageDirectory, RelativeProjectRootForStage.Name); ProjectArgForCommandLines = CommandUtils.MakePathSafeToUseWithCommandLine(UProjectCommandLineArgInternalRoot + RelativeProjectRootForStage.Name + "/" + ShortProjectName + ".uproject"); } if (Archive) { CommandUtils.CreateDirectory(ArchiveDirectory.FullName); } ProjectArgForCommandLines = ProjectArgForCommandLines.Replace("\\", "/"); ProjectBinariesFolder = DirectoryReference.Combine(ProjectUtils.GetClientProjectBinariesRootPath(RawProjectPath, TargetType.Game, IsCodeBasedProject), PlatformDir); // Build a list of restricted folder names. This will comprise all other restricted platforms, plus standard restricted folder names such as NoRedist, NotForLicensees, etc... RestrictedFolderNames.UnionWith(PlatformExports.GetPlatformFolderNames()); foreach (UnrealTargetPlatform StagePlatform in StageTargetPlatform.GetStagePlatforms()) { RestrictedFolderNames.ExceptWith(PlatformExports.GetIncludedFolderNames(StagePlatform)); } RestrictedFolderNames.UnionWith(FileFilter.RestrictedFolderNames); RestrictedFolderNames.Remove(new FileSystemName(StageTargetPlatform.IniPlatformType.ToString())); // Read the game config files ConfigHierarchy GameConfig = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, ProjectRoot, InTargetPlatform.PlatformType); // Read the list of directories to remap when staging List <string> RemapDirectoriesList; if (GameConfig.GetArray("Staging", "RemapDirectories", out RemapDirectoriesList)) { foreach (string RemapDirectory in RemapDirectoriesList) { Dictionary <string, string> Properties; if (!ConfigHierarchy.TryParse(RemapDirectory, out Properties)) { throw new AutomationException("Unable to parse '{0}'", RemapDirectory); } string FromDir; if (!Properties.TryGetValue("From", out FromDir)) { throw new AutomationException("Missing 'From' property in '{0}'", RemapDirectory); } string ToDir; if (!Properties.TryGetValue("To", out ToDir)) { throw new AutomationException("Missing 'To' property in '{0}'", RemapDirectory); } RemapDirectories.Add(Tuple.Create(new StagedDirectoryReference(FromDir), new StagedDirectoryReference(ToDir))); } } // Read the list of directories to whitelist from restricted folder warnings List <string> WhitelistDirectoriesList; if (GameConfig.GetArray("Staging", "WhitelistDirectories", out WhitelistDirectoriesList)) { foreach (string WhitelistDirectory in WhitelistDirectoriesList) { WhitelistDirectories.Add(new StagedDirectoryReference(WhitelistDirectory)); } } // Read the list of files which are whitelisted to be staged ReadConfigFileList(GameConfig, "Staging", "WhitelistConfigFiles", WhitelistConfigFiles); ReadConfigFileList(GameConfig, "Staging", "BlacklistConfigFiles", BlacklistConfigFiles); // If we were configured to use manifests across the whole project, then this platform should use manifests. // Otherwise, read whether we are generating chunks from the ProjectPackagingSettings ini. if (InForceChunkManifests) { PlatformUsesChunkManifests = true; } else { ConfigHierarchy GameIni = ConfigCache.ReadHierarchy(ConfigHierarchyType.Game, ProjectRoot, InTargetPlatform.PlatformType); String IniPath = "/Script/UnrealEd.ProjectPackagingSettings"; bool bSetting = false; if (GameIni.GetBool(IniPath, "bGenerateChunks", out bSetting)) { PlatformUsesChunkManifests = bSetting; } } }
/// <summary> /// Entry point for the commandlet /// </summary> public override void ExecuteBuild() { string OutputDir = ParseParamValue("OutputDir"); string ContentOnlyPlatformsString = ParseParamValue("ContentOnlyPlatforms"); IEnumerable <UnrealTargetPlatform> ContentOnlyPlatforms = Enumerable.Empty <UnrealTargetPlatform>(); if (!String.IsNullOrWhiteSpace(ContentOnlyPlatformsString)) { ContentOnlyPlatforms = ContentOnlyPlatformsString.Split(';').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => UnrealTargetPlatform.Parse(x)); } string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride"); // Write InstalledBuild.txt to indicate Engine is installed string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile)); CommandUtils.WriteAllText(InstalledBuildFile, ""); // Write InstalledBuild.txt to indicate Engine is installed string Project = ParseParamValue("Project"); if (Project != null) { string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile)); CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir))); } string OutputEnginePath = Path.Combine(OutputDir, "Engine"); string OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini"); FileAttributes OutputAttributes = FileAttributes.ReadOnly; List <String> IniLines = new List <String>(); // Should always exist but if not, we don't need extra line if (File.Exists(OutputBaseEnginePath)) { OutputAttributes = File.GetAttributes(OutputBaseEnginePath); IniLines.Add(""); } else { CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath)); CommandUtils.WriteAllText(OutputBaseEnginePath, ""); OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes; } // Create list of platform configurations installed in a Rocket build List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>(); // Add the editor platform, otherwise we'll never be able to run UAT string EditorArchitecture = PlatformExports.GetDefaultArchitecture(HostPlatform.Current.HostEditorPlatform, null); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.Development, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false)); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(UnrealTargetConfiguration.DebugGame, HostPlatform.Current.HostEditorPlatform, TargetRules.TargetType.Editor, EditorArchitecture, "", EProjectType.Unknown, false)); foreach (UnrealTargetPlatform CodeTargetPlatform in UnrealTargetPlatform.GetValidPlatforms()) { if (PlatformExports.IsPlatformAvailable(CodeTargetPlatform)) { string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null); // Try to parse additional Architectures from the command line string Architectures = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures"); string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures"); // Build a list of pre-compiled architecture combinations for this platform if any List <string> AllArchNames; if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures)) { AllArchNames = (from Arch in Architectures.Split('+') from GPUArch in GPUArchitectures.Split('+') select "-" + Arch + "-" + GPUArch).ToList(); } else if (!String.IsNullOrWhiteSpace(Architectures)) { AllArchNames = Architectures.Split('+').ToList(); } // if there aren't any, use the default else { AllArchNames = new List <string>() { Architecture }; } // Check whether this platform should only be used for content based projects EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any; // Allow Content only platforms to be shown as options in all projects bool bCanBeDisplayed = ProjectType == EProjectType.Content; foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { Dictionary <String, TargetType> Targets = new Dictionary <string, TargetType>() { { "UE4Game", TargetType.Game }, { "UE4Client", TargetType.Client }, { "UE4Server", TargetType.Server } }; foreach (KeyValuePair <string, TargetType> Target in Targets) { string CurrentTargetName = Target.Key; TargetType CurrentTargetType = Target.Value; // Need to check for development receipt as we use that for the Engine code in DebugGame UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration; // Android has multiple architecture flavors built without receipts, so use the default arch target instead if (CodeTargetPlatform == UnrealTargetPlatform.Android) { FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Architecture); if (FileReference.Exists(ReceiptFileName)) { // Strip the output folder so that this can be used on any machine string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir)); // Blindly append all of the architecture names if (AllArchNames.Count > 0) { foreach (string Arch in AllArchNames) { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } // if for some reason we didn't specify any flavors, just add the default one. else { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Architecture, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } } // If we're not Android, check the existence of the target receipts for each architecture specified. else { foreach (string Arch in AllArchNames) { FileReference ReceiptFileName = TargetReceipt.GetDefaultPath(new DirectoryReference(OutputEnginePath), CurrentTargetName, CodeTargetPlatform, EngineConfiguration, Arch); if (FileReference.Exists(ReceiptFileName)) { string RelativeReceiptFileName = ReceiptFileName.MakeRelativeTo(new DirectoryReference(OutputDir)); InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, CurrentTargetType, Arch, RelativeReceiptFileName, ProjectType, bCanBeDisplayed)); } } } } } } } UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines); if (!String.IsNullOrEmpty(AnalyticsTypeOverride)) { // Write Custom Analytics type setting IniLines.Add(""); IniLines.Add("[Analytics]"); IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride)); } // Make sure we can write to the the config file File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly); File.AppendAllLines(OutputBaseEnginePath, IniLines); File.SetAttributes(OutputBaseEnginePath, OutputAttributes); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, bool AssetNativizationRequested) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project return(true); } if (ClientTargetPlatforms != null) { foreach (UnrealTargetPlatform ClientPlatform in ClientTargetPlatforms) { String EncryptionKey; String[] SigningKeys; EncryptionAndSigning.ParseEncryptionIni(RawProjectPath.Directory, ClientPlatform, out SigningKeys, out EncryptionKey); if (SigningKeys != null || !string.IsNullOrEmpty(EncryptionKey)) { return(true); } } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } // Change the working directory to be the Engine/Source folder. We are running from Engine/Binaries/DotNET DirectoryReference oldCWD = DirectoryReference.GetCurrentDirectory(); try { DirectoryReference EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Source"); if (!DirectoryReference.Exists(EngineSourceDirectory)) // only set the directory if it exists, this should only happen if we are launching the editor from an artist sync { EngineSourceDirectory = DirectoryReference.Combine(CommandUtils.EngineDirectory, "Binaries"); } Directory.SetCurrentDirectory(EngineSourceDirectory.FullName); // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins bool RetVal = false; foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { if (!Automation.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, TargetPlatformType)) { RetVal = true; break; } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForProject = Plugins.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetType.Game); if ((bPluginEnabledForProject != Plugin.EnabledByDefault) || (bPluginEnabledForProject && Plugin.Descriptor.bInstalled)) { // NOTE: this code was only marking plugins that compiled for the platform to upgrade to code project, however // this doesn't work in practice, because the runtime code will look for the plugin, without a .uplugin file, // and will fail. This is the safest way to make sure all platforms are acting the same. However, if you // whitelist the plugin in the .uproject file, the above UProjectInfo.IsPluginEnabledForProject check won't pass // so you won't get in here. Leaving this commented out code in there, because someone is bound to come looking // for why a non-whitelisted platform module is causing a project to convert to code-based. // As an aside, if you run the project with UE4Game (not your Project's binary) from the debugger, it will work // _in this case_ because the .uplugin file will have been staged, and there is no needed library // if(Plugin.Descriptor.Modules.Any(Module => Module.IsCompiledInConfiguration(TargetPlatformType, TargetType.Game, bBuildDeveloperTools: false, bBuildEditor: false))) { RetVal = true; break; } } } } return(RetVal); } finally { // Change back to the original directory Directory.SetCurrentDirectory(oldCWD.FullName); } }
/// <summary> /// Main method. /// </summary> /// <param name="Arguments">Command line</param> public static ExitCode Process(string[] Arguments, StartupTraceListener StartupListener) { // Initial check for local or build machine runs BEFORE we parse the command line (We need this value set // in case something throws the exception while parsing the command line) IsBuildMachine = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT")) || Arguments.Any(x => x.Equals("-BuildMachine", StringComparison.InvariantCultureIgnoreCase)); // Scan the command line for commands to execute. var CommandsToExecute = new List <CommandInfo>(); string OutScriptsForProjectFileName; var AdditionalScriptsFolders = new List <string>(); ParseCommandLine(Arguments, CommandsToExecute, out OutScriptsForProjectFileName, AdditionalScriptsFolders); // Get the path to the telemetry file, if present string TelemetryFile = CommandUtils.ParseParamValue(Arguments, "-Telemetry"); Log.TraceVerbose("IsBuildMachine={0}", IsBuildMachine); Environment.SetEnvironmentVariable("IsBuildMachine", IsBuildMachine ? "1" : "0"); // should we kill processes on exit ShouldKillProcesses = !GlobalCommandLine.NoKill; Log.TraceVerbose("ShouldKillProcesses={0}", ShouldKillProcesses); if (CommandsToExecute.Count == 0 && GlobalCommandLine.Help) { DisplayHelp(); return(ExitCode.Success); } // Disable AutoSDKs if specified on the command line if (GlobalCommandLine.NoAutoSDK) { PlatformExports.PreventAutoSDKSwitching(); } // Setup environment Log.TraceLog("Setting up command environment."); CommandUtils.InitCommandEnvironment(); // Create the log file, and flush the startup listener to it TraceListener LogTraceListener = LogUtils.AddLogFileListener(CommandUtils.CmdEnv.LogFolder, CommandUtils.CmdEnv.FinalLogFolder); StartupListener.CopyTo(LogTraceListener); Trace.Listeners.Remove(StartupListener); // Initialize UBT if (!UnrealBuildTool.PlatformExports.Initialize()) { Log.TraceInformation("Failed to initialize UBT"); return(ExitCode.Error_Unknown); } // Clean rules folders up ProjectUtils.CleanupFolders(); // Compile scripts. Compiler = new ScriptCompiler(); using (TelemetryStopwatch ScriptCompileStopwatch = new TelemetryStopwatch("ScriptCompile")) { Compiler.FindAndCompileAllScripts(OutScriptsForProjectFileName, AdditionalScriptsFolders); } if (GlobalCommandLine.CompileOnly) { Log.TraceInformation("Compilation successful, exiting (CompileOnly)"); return(ExitCode.Success); } if (GlobalCommandLine.List) { ListAvailableCommands(Compiler.Commands); return(ExitCode.Success); } if (GlobalCommandLine.Help) { DisplayHelp(CommandsToExecute, Compiler.Commands); return(ExitCode.Success); } // Enable or disable P4 support CommandUtils.InitP4Support(CommandsToExecute, Compiler.Commands); if (CommandUtils.P4Enabled) { Log.TraceLog("Setting up Perforce environment."); CommandUtils.InitP4Environment(); CommandUtils.InitDefaultP4Connection(); } // Find and execute commands. ExitCode Result = Execute(CommandsToExecute, Compiler.Commands); if (TelemetryFile != null) { Directory.CreateDirectory(Path.GetDirectoryName(TelemetryFile)); CommandUtils.Telemetry.Write(TelemetryFile); } return(Result); }
/// <summary> /// Entry point for the commandlet /// </summary> public override void ExecuteBuild() { string OutputDir = ParseParamValue("OutputDir"); string ContentOnlyPlatformsString = ParseParamValue("ContentOnlyPlatforms"); IEnumerable <UnrealTargetPlatform> ContentOnlyPlatforms = Enumerable.Empty <UnrealTargetPlatform>(); if (!String.IsNullOrWhiteSpace(ContentOnlyPlatformsString)) { ContentOnlyPlatforms = ContentOnlyPlatformsString.Split(';').Where(x => !String.IsNullOrWhiteSpace(x)).Select(x => (UnrealTargetPlatform)Enum.Parse(typeof(UnrealTargetPlatform), x)); } string AnalyticsTypeOverride = ParseParamValue("AnalyticsTypeOverride"); // Write InstalledBuild.txt to indicate Engine is installed string InstalledBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledBuildFile)); CommandUtils.WriteAllText(InstalledBuildFile, ""); // Write InstalledBuild.txt to indicate Engine is installed string Project = ParseParamValue("Project"); if (Project != null) { string InstalledProjectBuildFile = CommandUtils.CombinePaths(OutputDir, "Engine/Build/InstalledProjectBuild.txt"); CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(InstalledProjectBuildFile)); CommandUtils.WriteAllText(InstalledProjectBuildFile, new FileReference(Project).MakeRelativeTo(new DirectoryReference(OutputDir))); } string OutputEnginePath = Path.Combine(OutputDir, "Engine"); string OutputBaseEnginePath = Path.Combine(OutputEnginePath, "Config", "BaseEngine.ini"); FileAttributes OutputAttributes = FileAttributes.ReadOnly; List <String> IniLines = new List <String>(); // Should always exist but if not, we don't need extra line if (File.Exists(OutputBaseEnginePath)) { OutputAttributes = File.GetAttributes(OutputBaseEnginePath); IniLines.Add(""); } else { CommandUtils.CreateDirectory(CommandUtils.GetDirectoryName(OutputBaseEnginePath)); CommandUtils.WriteAllText(OutputBaseEnginePath, ""); OutputAttributes = File.GetAttributes(OutputBaseEnginePath) | OutputAttributes; } // Create list of platform configurations installed in a Rocket build List <InstalledPlatformInfo.InstalledPlatformConfiguration> InstalledConfigs = new List <InstalledPlatformInfo.InstalledPlatformConfiguration>(); foreach (UnrealTargetPlatform CodeTargetPlatform in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (PlatformExports.IsPlatformAvailable(CodeTargetPlatform)) { string Architecture = PlatformExports.GetDefaultArchitecture(CodeTargetPlatform, null); // Try to parse additional Architectures from the command line string Architectures = ParseParamValue(CodeTargetPlatform.ToString() + "Architectures"); string GPUArchitectures = ParseParamValue(CodeTargetPlatform.ToString() + "GPUArchitectures"); // Build a list of pre-compiled architecture combinations for this platform if any List <string> AllArchNames; if (!String.IsNullOrWhiteSpace(Architectures) && !String.IsNullOrWhiteSpace(GPUArchitectures)) { AllArchNames = (from Arch in Architectures.Split('+') from GPUArch in GPUArchitectures.Split('+') select "-" + Arch + "-" + GPUArch).ToList(); } else if (!String.IsNullOrWhiteSpace(Architectures)) { AllArchNames = Architectures.Split('+').ToList(); } else { AllArchNames = new List <string>(); } // Check whether this platform should only be used for content based projects EProjectType ProjectType = ContentOnlyPlatforms.Contains(CodeTargetPlatform) ? EProjectType.Content : EProjectType.Any; // Allow Content only platforms to be shown as options in all projects bool bCanBeDisplayed = ProjectType == EProjectType.Content; foreach (UnrealTargetConfiguration CodeTargetConfiguration in Enum.GetValues(typeof(UnrealTargetConfiguration))) { // Need to check for development receipt as we use that for the Engine code in DebugGame UnrealTargetConfiguration EngineConfiguration = (CodeTargetConfiguration == UnrealTargetConfiguration.DebugGame) ? UnrealTargetConfiguration.Development : CodeTargetConfiguration; string ReceiptFileName = TargetReceipt.GetDefaultPath(OutputEnginePath, "UE4Game", CodeTargetPlatform, EngineConfiguration, Architecture); if (File.Exists(ReceiptFileName)) { // Strip the output folder so that this can be used on any machine ReceiptFileName = new FileReference(ReceiptFileName).MakeRelativeTo(new DirectoryReference(OutputDir)); // If we have pre-compiled architectures for this platform then add an entry for each of these - // there isn't a receipt for each architecture like some other platforms if (AllArchNames.Count > 0) { foreach (string Arch in AllArchNames) { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetType.Game, Arch, ReceiptFileName, ProjectType, bCanBeDisplayed)); } } else { InstalledConfigs.Add(new InstalledPlatformInfo.InstalledPlatformConfiguration(CodeTargetConfiguration, CodeTargetPlatform, TargetType.Game, Architecture, ReceiptFileName, ProjectType, bCanBeDisplayed)); } } } } } UnrealBuildTool.InstalledPlatformInfo.WriteConfigFileEntries(InstalledConfigs, ref IniLines); if (!String.IsNullOrEmpty(AnalyticsTypeOverride)) { // Write Custom Analytics type setting IniLines.Add(""); IniLines.Add("[Analytics]"); IniLines.Add(String.Format("UE4TypeOverride=\"{0}\"", AnalyticsTypeOverride)); } // Make sure we can write to the the config file File.SetAttributes(OutputBaseEnginePath, OutputAttributes & ~FileAttributes.ReadOnly); File.AppendAllLines(OutputBaseEnginePath, IniLines); File.SetAttributes(OutputBaseEnginePath, OutputAttributes); }
/// <summary> /// Main method. /// </summary> /// <param name="Arguments">Command line</param> public static ExitCode Process(string[] Arguments) { // Initial check for local or build machine runs BEFORE we parse the command line (We need this value set // in case something throws the exception while parsing the command line) IsBuildMachine = !String.IsNullOrEmpty(Environment.GetEnvironmentVariable("uebp_LOCAL_ROOT")) || Arguments.Any(x => x.Equals("-BuildMachine", StringComparison.InvariantCultureIgnoreCase)); // Scan the command line for commands to execute. var CommandsToExecute = new List <CommandInfo>(); string OutScriptsForProjectFileName; var AdditionalScriptsFolders = new List <string>(); ParseCommandLine(Arguments, CommandsToExecute, out OutScriptsForProjectFileName, AdditionalScriptsFolders); // Get the path to the telemetry file, if present string TelemetryFile = CommandUtils.ParseParamValue(Arguments, "-Telemetry"); // Check for build machine override (force local) IsBuildMachine = GlobalCommandLine.ForceLocal ? false : IsBuildMachine; Log.TraceVerbose("IsBuildMachine={0}", IsBuildMachine); Environment.SetEnvironmentVariable("IsBuildMachine", IsBuildMachine ? "1" : "0"); // should we kill processes on exit ShouldKillProcesses = !GlobalCommandLine.NoKill; Log.TraceVerbose("ShouldKillProcesses={0}", ShouldKillProcesses); if (CommandsToExecute.Count == 0 && GlobalCommandLine.Help) { DisplayHelp(); return(ExitCode.Success); } // Disable AutoSDKs if specified on the command line if (GlobalCommandLine.NoAutoSDK) { PlatformExports.PreventAutoSDKSwitching(); } // Setup environment Log.TraceLog("Setting up command environment."); CommandUtils.InitCommandEnvironment(); // Determine if the engine is installed bIsEngineInstalled = GlobalCommandLine.Installed; string InstalledBuildFile = Path.Combine(CommandUtils.CmdEnv.LocalRoot, "Engine", "Build", "InstalledBuild.txt"); bIsEngineInstalled |= File.Exists(InstalledBuildFile); if (bIsEngineInstalled.Value) { bIsEngineInstalled = !GlobalCommandLine.NotInstalledEngine; } else { bIsEngineInstalled = GlobalCommandLine.InstalledEngine; } // Initialize UBT if (!UnrealBuildTool.PlatformExports.Initialize(bIsEngineInstalled.Value)) { Log.TraceInformation("Failed to initialize UBT"); return(ExitCode.Error_Unknown); } // Change CWD to UE4 root. Environment.CurrentDirectory = CommandUtils.CmdEnv.LocalRoot; // Fill in the project info UnrealBuildTool.UProjectInfo.FillProjectInfo(); // Clean rules folders up ProjectUtils.CleanupFolders(); // Compile scripts. ScriptCompiler Compiler = new ScriptCompiler(); using (TelemetryStopwatch ScriptCompileStopwatch = new TelemetryStopwatch("ScriptCompile")) { Compiler.FindAndCompileAllScripts(OutScriptsForProjectFileName, AdditionalScriptsFolders); } if (GlobalCommandLine.CompileOnly) { Log.TraceInformation("Compilation successful, exiting (CompileOnly)"); return(ExitCode.Success); } if (GlobalCommandLine.List) { ListAvailableCommands(Compiler.Commands); return(ExitCode.Success); } if (GlobalCommandLine.Help) { DisplayHelp(CommandsToExecute, Compiler.Commands); return(ExitCode.Success); } // Enable or disable P4 support CommandUtils.InitP4Support(CommandsToExecute, Compiler.Commands); if (CommandUtils.P4Enabled) { Log.TraceLog("Setting up Perforce environment."); CommandUtils.InitP4Environment(); CommandUtils.InitDefaultP4Connection(); } // Find and execute commands. ExitCode Result = Execute(CommandsToExecute, Compiler.Commands); if (TelemetryFile != null) { Directory.CreateDirectory(Path.GetDirectoryName(TelemetryFile)); CommandUtils.Telemetry.Write(TelemetryFile); } return(Result); }
private static bool RequiresTempTarget(FileReference RawProjectPath, List <UnrealTargetPlatform> ClientTargetPlatforms, List <UnrealTargetConfiguration> ClientTargetConfigurations, bool AssetNativizationRequested, out string Reason) { // check to see if we already have a Target.cs file if (File.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source", RawProjectPath.GetFileNameWithoutExtension() + ".Target.cs"))) { Reason = null; return(false); } else if (Directory.Exists(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source"))) { // wasn't one in the main Source directory, let's check all sub-directories //@todo: may want to read each target.cs to see if it has a target corresponding to the project name as a final check FileInfo[] Files = (new DirectoryInfo(Path.Combine(Path.GetDirectoryName(RawProjectPath.FullName), "Source")).GetFiles("*.Target.cs", SearchOption.AllDirectories)); if (Files.Length > 0) { Reason = null; return(false); } } // // once we reach this point, we can surmise that this is an asset- // only (code free) project if (AssetNativizationRequested) { // we're going to be converting some of the project's assets // into native code, so we require a distinct target (executable) // be generated for this project Reason = "asset nativization is enabled"; return(true); } if (ClientTargetPlatforms != null) { foreach (UnrealTargetPlatform ClientPlatform in ClientTargetPlatforms) { EncryptionAndSigning.CryptoSettings Settings = EncryptionAndSigning.ParseCryptoSettings(RawProjectPath.Directory, ClientPlatform); if (Settings.IsAnyEncryptionEnabled() || Settings.IsPakSigningEnabled()) { Reason = "encryption/signing is enabled"; return(true); } } } // no Target file, now check to see if build settings have changed List <UnrealTargetPlatform> TargetPlatforms = ClientTargetPlatforms; if (ClientTargetPlatforms == null || ClientTargetPlatforms.Count < 1) { // No client target platforms, add all in TargetPlatforms = new List <UnrealTargetPlatform>(); foreach (UnrealTargetPlatform TargetPlatformType in Enum.GetValues(typeof(UnrealTargetPlatform))) { if (TargetPlatformType != UnrealTargetPlatform.Unknown) { TargetPlatforms.Add(TargetPlatformType); } } } List <UnrealTargetConfiguration> TargetConfigurations = ClientTargetConfigurations; if (TargetConfigurations == null || TargetConfigurations.Count < 1) { // No client target configurations, add all in TargetConfigurations = new List <UnrealTargetConfiguration>(); foreach (UnrealTargetConfiguration TargetConfigurationType in Enum.GetValues(typeof(UnrealTargetConfiguration))) { if (TargetConfigurationType != UnrealTargetConfiguration.Unknown) { TargetConfigurations.Add(TargetConfigurationType); } } } // Read the project descriptor, and find all the plugins available to this project ProjectDescriptor Project = ProjectDescriptor.FromFile(RawProjectPath); List <PluginInfo> AvailablePlugins = Plugins.ReadAvailablePlugins(CommandUtils.EngineDirectory, RawProjectPath, Project.AdditionalPluginDirectories); // check the target platforms for any differences in build settings or additional plugins foreach (UnrealTargetPlatform TargetPlatformType in TargetPlatforms) { if (!CommandUtils.IsEngineInstalled() && !PlatformExports.HasDefaultBuildConfig(RawProjectPath, TargetPlatformType)) { Reason = "project has non-default build configuration"; return(true); } if (PlatformExports.RequiresBuild(RawProjectPath, TargetPlatformType)) { Reason = "overriden by target platform"; return(true); } // find if there are any plugins enabled or disabled which differ from the default foreach (PluginInfo Plugin in AvailablePlugins) { bool bPluginEnabledForTarget = false; foreach (UnrealTargetConfiguration TargetConfigType in TargetConfigurations) { bPluginEnabledForTarget |= Plugins.IsPluginEnabledForProject(Plugin, Project, TargetPlatformType, TargetConfigType, TargetRules.TargetType.Game); } bool bPluginEnabledForBaseTarget = false; if (!Plugin.Descriptor.bInstalled) { foreach (UnrealTargetConfiguration TargetConfigType in TargetConfigurations) { bPluginEnabledForBaseTarget |= Plugins.IsPluginEnabledForProject(Plugin, null, TargetPlatformType, TargetConfigType, TargetRules.TargetType.Game); } } if (bPluginEnabledForTarget != bPluginEnabledForBaseTarget) { if (bPluginEnabledForTarget) { Reason = String.Format("{0} plugin is enabled", Plugin.Name); return(true); } else { Reason = String.Format("{0} plugin is disabled", Plugin.Name); return(true); } } } } Reason = null; return(false); }