예제 #1
0
        /// <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);
		}
예제 #3
0
        /// <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);
                }
            }
        }
예제 #4
0
        /// <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);
        }
예제 #5
0
        /// <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);
        }
예제 #6
0
        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);
        }
예제 #8
0
        /// <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);
        }