/// <summary> /// Executes a list of custom build step scripts /// </summary> /// <param name="ScriptFiles">List of script files to execute</param> /// <returns>True if the steps succeeded, false otherwise</returns> public static bool ExecuteCustomBuildSteps(FileReference[] ScriptFiles) { UnrealTargetPlatform HostPlatform = BuildHostPlatform.Current.Platform; foreach (FileReference ScriptFile in ScriptFiles) { ProcessStartInfo StartInfo = new ProcessStartInfo(); if (HostPlatform == UnrealTargetPlatform.Win64) { StartInfo.FileName = "cmd.exe"; StartInfo.Arguments = String.Format("/C \"{0}\"", ScriptFile.FullName); } else { StartInfo.FileName = "/bin/sh"; StartInfo.Arguments = String.Format("\"{0}\"", ScriptFile.FullName); } int ReturnCode = Utils.RunLocalProcessAndLogOutput(StartInfo); if (ReturnCode != 0) { Log.TraceError("Custom build step terminated with exit code {0}", ReturnCode); return(false); } } return(true); }
public override void StripSymbols(string SourceFileName, string TargetFileName) { File.Copy(SourceFileName, TargetFileName, true); ProcessStartInfo StartInfo = new ProcessStartInfo(); if (SourceFileName.Contains("-armv7")) { StartInfo.FileName = ArPathArm.Replace("-ar.exe", "-strip.exe"); } else if (SourceFileName.Contains("-arm64")) { StartInfo.FileName = ArPathArm64.Replace("-ar.exe", "-strip.exe"); } else if (SourceFileName.Contains("-x86")) { StartInfo.FileName = ArPathx86.Replace("-ar.exe", "-strip.exe"); } else if (SourceFileName.Contains("-x64")) { StartInfo.FileName = ArPathx64.Replace("-ar.exe", "-strip.exe"); } else { throw new BuildException("Couldn't determine Android architecture to strip symbols from {0}", SourceFileName); } StartInfo.Arguments = "--strip-debug " + TargetFileName; StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; Utils.RunLocalProcessAndLogOutput(StartInfo); }
/// <summary> /// Executes a list of custom build step scripts /// </summary> /// <param name="ScriptFiles">List of script files to execute</param> /// <returns>True if the steps succeeded, false otherwise</returns> public static void ExecuteCustomBuildSteps(FileReference[] ScriptFiles) { UnrealTargetPlatform HostPlatform = BuildHostPlatform.Current.Platform; foreach (FileReference ScriptFile in ScriptFiles) { ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = BuildHostPlatform.Current.Shell.FullName; if (BuildHostPlatform.Current.ShellType == ShellType.Cmd) { StartInfo.Arguments = String.Format("/C \"{0}\"", ScriptFile.FullName); } else { StartInfo.Arguments = String.Format("\"{0}\"", ScriptFile.FullName); } int ReturnCode = Utils.RunLocalProcessAndLogOutput(StartInfo); if (ReturnCode != 0) { throw new BuildException("Custom build step terminated with exit code {0}", ReturnCode); } } }
/// <summary> /// Creates a debugger link in an executable referencing where the debug symbols for it are located. /// </summary> /// <param name="SourceDebugFile">An object file with the debug symbols, can be an executable or the file generated with ExtractSymbols.</param> /// <param name="TargetExeFile">The executable to reference the split debug info into.</param> public void LinkSymbols(FileReference SourceDebugFile, FileReference TargetExeFile) { ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = ObjCopyPath; StartInfo.Arguments = " --add-gnu-debuglink=\"" + SourceDebugFile.FullName + "\" \"" + TargetExeFile.FullName + "\""; StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; Utils.RunLocalProcessAndLogOutput(StartInfo); }
/// <summary> /// Creates an object file with only the symbolic debug information from an executable. /// </summary> /// <param name="SourceExeFile">The executable with debug symbol information.</param> /// <param name="TargetSymFile">The generated object file with debug symbols.</param> public void ExtractSymbols(FileReference SourceExeFile, FileReference TargetSymFile) { ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = ObjCopyPath; StartInfo.Arguments = " --only-keep-debug \"" + SourceExeFile.FullName + "\" \"" + TargetSymFile.FullName + "\""; StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; Utils.RunLocalProcessAndLogOutput(StartInfo); }
protected void StripSymbolsWithXcode(string SourceFileName, string TargetFileName, string ToolchainDir) { File.Copy(SourceFileName, TargetFileName, true); ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = Path.Combine(ToolchainDir, "strip"); StartInfo.Arguments = String.Format("\"{0}\" -S", TargetFileName); StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; Utils.RunLocalProcessAndLogOutput(StartInfo); }
protected void StripSymbolsWithXcode(FileReference SourceFile, FileReference TargetFile, string ToolchainDir) { if (SourceFile != TargetFile) { // Strip command only works in place so we need to copy original if target is different File.Copy(SourceFile.FullName, TargetFile.FullName, true); } ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = Path.Combine(ToolchainDir, "strip"); StartInfo.Arguments = String.Format("\"{0}\" -S", TargetFile.FullName); StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; Utils.RunLocalProcessAndLogOutput(StartInfo); }
/// <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); // Compile the rules assembly RulesCompiler.CreateTargetRulesAssembly(TargetDesc.ProjectFile, TargetDesc.Name, false, false, TargetDesc.ForeignPlugin); // 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("-ForceXmlConfigCache"); // 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"); // 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 FileReference CertificateFile = FileReference.Combine(TempDir, "Certificate.p12"); if (!FileReference.Exists(CertificateFile)) { StringBuilder Arguments = new StringBuilder("ExportCertificate"); if (TargetDesc.ProjectFile == null) { Arguments.AppendFormat(" \"{0}\"", UnrealBuildTool.EngineSourceDirectory); } else { Arguments.AppendFormat(" \"{0}\"", TargetDesc.ProjectFile.Directory); } Arguments.AppendFormat(" -certificate \"{0}\"", CertificateFile); 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."); } } // 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 Log.TraceInformation("[Remote] Uploading 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); }