void StageBootstrapExecutable(DeploymentContext SC, string ExeName, string TargetFile, string StagedRelativeTargetPath, string StagedArguments) { // create a temp script file location DirectoryReference IntermediateDir = DirectoryReference.Combine(SC.ProjectRoot, "Intermediate", "Staging"); FileReference IntermediateFile = FileReference.Combine(IntermediateDir, ExeName); DirectoryReference.CreateDirectory(IntermediateDir); // make sure slashes are good StagedRelativeTargetPath = StagedRelativeTargetPath.Replace("\\", "/"); // make contents StringBuilder Script = new StringBuilder(); string EOL = "\n"; Script.Append("#!/bin/sh" + EOL); // allow running from symlinks Script.AppendFormat("UE4_TRUE_SCRIPT_NAME=$(echo \\\"$0\\\" | xargs readlink -f)" + EOL); Script.AppendFormat("UE4_PROJECT_ROOT=$(dirname \"$UE4_TRUE_SCRIPT_NAME\")" + EOL); Script.AppendFormat("chmod +x \"$UE4_PROJECT_ROOT/{0}\"" + EOL, StagedRelativeTargetPath); Script.AppendFormat("\"$UE4_PROJECT_ROOT/{0}\" {1} $@ " + EOL, StagedRelativeTargetPath, StagedArguments); // write out the FileReference.WriteAllText(IntermediateFile, Script.ToString()); if (Utils.IsRunningOnMono) { var Result = CommandUtils.Run("sh", string.Format("-c 'chmod +x \\\"{0}\\\"'", IntermediateFile)); if (Result.ExitCode != 0) { throw new AutomationException(string.Format("Failed to chmod \"{0}\"", IntermediateFile)); } } SC.StageFile(StagedFileType.NonUFS, IntermediateFile, new StagedFileReference(ExeName)); }
/// <summary> /// Execute the task. /// </summary> /// <param name="Job">Information about the current job.</param> /// <param name="BuildProducts">Set of build products produced by this node.</param> /// <param name="TagNameToFileSet">Mapping from tag names to the set of files they include.</param> public override void Execute(JobContext Job, HashSet <FileReference> BuildProducts, Dictionary <string, HashSet <FileReference> > TagNameToFileSet) { string FileText = Parameters.Text; // If any files or tagsets are provided, add them to the text output. if (!String.IsNullOrEmpty(Parameters.Files)) { if (!string.IsNullOrWhiteSpace(FileText)) { FileText += Environment.NewLine; } HashSet <FileReference> Files = ResolveFilespec(CommandUtils.RootDirectory, Parameters.Files, TagNameToFileSet); if (Files.Any()) { FileText += string.Join(Environment.NewLine, Files.Select(f => f.FullName)); } } // Make sure output folder exists. if (!DirectoryReference.Exists(Parameters.File.Directory)) { DirectoryReference.CreateDirectory(Parameters.File.Directory); } if (Parameters.Append) { CommandUtils.LogInformation(string.Format("Appending text to file '{0}': {1}", Parameters.File, FileText)); FileReference.AppendAllText(Parameters.File, Environment.NewLine + FileText); } else { CommandUtils.LogInformation(string.Format("Writing text to file '{0}': {1}", Parameters.File, FileText)); FileReference.WriteAllText(Parameters.File, FileText); } }
public override void ExecuteBuild() { string RootDirParam = ParseParamValue("RootDir", null); if (RootDirParam == null) { throw new AutomationException("Missing -BaseDir=... parameter"); } string EngineAssociation = ParseParamValue("EngineAssociation", null); bool bForce = ParseParam("Force"); List <FileReference> ProjectFiles = new List <FileReference>(); FindProjects(new DirectoryReference(RootDirParam), ProjectFiles); foreach (FileReference ProjectFile in ProjectFiles) { Log("Reading {0}", ProjectFile); string InputText = File.ReadAllText(ProjectFile.FullName); // Parse the descriptor ProjectDescriptor Descriptor; try { Descriptor = new ProjectDescriptor(JsonObject.Parse(InputText)); } catch (JsonParseException Ex) { LogError("Unable to parse {0}: {1}", ProjectFile, Ex.ToString()); continue; } // Update any metadata for the project if (EngineAssociation != null) { Descriptor.EngineAssociation = EngineAssociation; } // Find all the plugins for this project, and update all the plugin references in the descriptor if (Descriptor.Plugins != null) { Dictionary <string, PluginInfo> NameToPluginInfo = new Dictionary <string, PluginInfo>(StringComparer.InvariantCultureIgnoreCase); foreach (PluginInfo Plugin in Plugins.ReadEnginePlugins(EngineDirectory)) { NameToPluginInfo[Plugin.Name] = Plugin; } foreach (PluginInfo Plugin in Plugins.ReadProjectPlugins(ProjectFile.Directory)) { NameToPluginInfo[Plugin.Name] = Plugin; } foreach (PluginReferenceDescriptor Reference in Descriptor.Plugins) { if (Reference.bEnabled) { PluginInfo Info; if (NameToPluginInfo.TryGetValue(Reference.Name, out Info)) { Reference.SupportedTargetPlatforms = Info.Descriptor.SupportedTargetPlatforms; } } else { Reference.SupportedTargetPlatforms = null; } } } // Format the output text StringBuilder Output = new StringBuilder(); using (JsonWriter Writer = new JsonWriter(new StringWriter(Output))) { Writer.WriteObjectStart(); Descriptor.Write(Writer); Writer.WriteObjectEnd(); } // Compare the output and input; write it if it differs string OutputText = Output.ToString(); if (InputText != OutputText) { if (CommandUtils.IsReadOnly(ProjectFile.FullName)) { if (!bForce) { LogWarning("File is read only; skipping write."); continue; } CommandUtils.SetFileAttributes(ProjectFile.FullName, ReadOnly: false); } Log(" Writing updated file.", ProjectFile); FileReference.WriteAllText(ProjectFile, OutputText); } } }
public override void ExecuteBuild() { string RootDirParam = ParseParamValue("RootDir", null); if (RootDirParam == null) { throw new AutomationException("Missing -BaseDir=... parameter"); } string CreatedBy = ParseParamValue("CreatedBy", null); string CreatedByUrl = ParseParamValue("CreatedByUrl", null); bool bForce = ParseParam("Force"); foreach (FileReference PluginFile in DirectoryReference.EnumerateFiles(new DirectoryReference(RootDirParam), "*.uplugin", System.IO.SearchOption.AllDirectories)) { Log("Reading {0}", PluginFile); string InputText = File.ReadAllText(PluginFile.FullName); // Parse the descriptor PluginDescriptor Descriptor; try { Descriptor = new PluginDescriptor(JsonObject.Parse(InputText)); } catch (JsonParseException Ex) { LogError("Unable to parse {0}: {1}", PluginFile, Ex.ToString()); continue; } // Update the fields if (CreatedBy != null && Descriptor.CreatedBy != CreatedBy) { Log(" Updating 'CreatedBy' field from '{0}' to '{1}'", Descriptor.CreatedBy ?? "<empty>", CreatedBy); Descriptor.CreatedBy = CreatedBy; } if (CreatedByUrl != null) { Log(" Updating 'CreatedByURL' field from '{0}' to '{1}'", Descriptor.CreatedByURL ?? "<empty>", CreatedByUrl); Descriptor.CreatedByURL = CreatedByUrl; } // Format the output text StringBuilder Output = new StringBuilder(); using (JsonWriter Writer = new JsonWriter(new StringWriter(Output))) { Writer.WriteObjectStart(); Descriptor.Write(Writer); Writer.WriteObjectEnd(); } // Compare the output and input; write it if it differs string OutputText = Output.ToString(); if (InputText != OutputText) { if (CommandUtils.IsReadOnly(PluginFile.FullName)) { if (!bForce) { LogWarning("File is read only; skipping write."); continue; } CommandUtils.SetFileAttributes(PluginFile.FullName, ReadOnly: false); } Log(" Writing updated file.", PluginFile); FileReference.WriteAllText(PluginFile, OutputText); } } }
//#nv begin #Blast Linux build void StageBootstrapExecutable(DeploymentContext SC, StageTarget Target, string ExeName, string TargetFile, string StagedRelativeTargetPath, string StagedArguments) //@third party code - NVSTUDIOS Set LD_LIBRARY_PATH //nv end { // create a temp script file location DirectoryReference IntermediateDir = DirectoryReference.Combine(SC.ProjectRoot, "Intermediate", "Staging"); FileReference IntermediateFile = FileReference.Combine(IntermediateDir, ExeName); DirectoryReference.CreateDirectory(IntermediateDir); // make sure slashes are good StagedRelativeTargetPath = StagedRelativeTargetPath.Replace("\\", "/"); // make contents StringBuilder Script = new StringBuilder(); string EOL = "\n"; Script.Append("#!/bin/sh" + EOL); // allow running from symlinks Script.AppendFormat("UE4_TRUE_SCRIPT_NAME=$(echo \\\"$0\\\" | xargs readlink -f)" + EOL); Script.AppendFormat("UE4_PROJECT_ROOT=$(dirname \"$UE4_TRUE_SCRIPT_NAME\")" + EOL); Script.AppendFormat("chmod +x \"$UE4_PROJECT_ROOT/{0}\"" + EOL, StagedRelativeTargetPath); //#nv begin #Blast Linux build //The Blast .so files are not loaded by dlopen so we we need to setup the search paths //Really UE should be doing this for all dependent libraries, but they usually statically link HashSet <string> LDLibraryPaths = new HashSet <string>(); DirectoryReference TargetFileDir = (new FileReference(TargetFile)).Directory; DirectoryReference SourceEngineDir = SC.LocalRoot; DirectoryReference SourceProjectDir = SC.ProjectRoot; foreach (var RuntimeDependency in Target.Receipt.RuntimeDependencies) { foreach (FileReference File in CommandUtils.ResolveFilespec(CommandUtils.RootDirectory, RuntimeDependency.Path.FullName, new string[] { })) { if (FileReference.Exists(File) && File.GetExtension().Equals(".so", StringComparison.OrdinalIgnoreCase)) { string FileRelativePath = null; DirectoryReference SharedLibFolder = File.Directory; if (SharedLibFolder.IsUnderDirectory(SourceProjectDir)) { FileRelativePath = Path.Combine(SharedLibFolder.MakeRelativeTo(SourceProjectDir), SC.RelativeProjectRootForStage.ToString()); } else if (SharedLibFolder.IsUnderDirectory(SourceEngineDir)) { FileRelativePath = SharedLibFolder.MakeRelativeTo(SourceEngineDir); } if (FileRelativePath != null) { FileRelativePath = Path.Combine("$UE4_PROJECT_ROOT", FileRelativePath); FileRelativePath = FileRelativePath.Replace("\\", "/"); //Escape spaces FileRelativePath = FileRelativePath.Replace(" ", @"\ "); LDLibraryPaths.Add(FileRelativePath); } } } } if (LDLibraryPaths.Count > 0) { Script.AppendFormat("export LD_LIBRARY_PATH={0}" + EOL, string.Join(":", LDLibraryPaths)); } //nv end Script.AppendFormat("\"$UE4_PROJECT_ROOT/{0}\" {1} $@ " + EOL, StagedRelativeTargetPath, StagedArguments); // write out the FileReference.WriteAllText(IntermediateFile, Script.ToString()); if (Utils.IsRunningOnMono) { var Result = CommandUtils.Run("sh", string.Format("-c 'chmod +x \\\"{0}\\\"'", IntermediateFile)); if (Result.ExitCode != 0) { throw new AutomationException(string.Format("Failed to chmod \"{0}\"", IntermediateFile)); } } SC.StageFile(StagedFileType.NonUFS, IntermediateFile, new StagedFileReference(ExeName)); }
public override bool PublishSymbols(DirectoryReference SymbolStoreDirectory, List <FileReference> Files, string Product, string BuildVersion = null) { // Get the SYMSTORE.EXE path, using the latest SDK version we can find. FileReference SymStoreExe = GetSymStoreExe(); List <FileReference> FilesToAdd = Files.Where(x => x.HasExtension(".pdb") || x.HasExtension(".exe") || x.HasExtension(".dll")).ToList(); if (FilesToAdd.Count > 0) { DateTime Start = DateTime.Now; DirectoryReference TempSymStoreDir = DirectoryReference.Combine(RootDirectory, "Saved", "SymStore"); DirectoryReference.CreateDirectory(TempSymStoreDir); DeleteDirectoryContents(TempSymStoreDir); string TempFileName = Path.GetTempFileName(); try { File.WriteAllLines(TempFileName, FilesToAdd.Select(x => x.FullName), Encoding.ASCII); // Copy everything to the temp symstore ProcessStartInfo StartInfo = new ProcessStartInfo(); StartInfo.FileName = SymStoreExe.FullName; StartInfo.Arguments = string.Format("add /f \"@{0}\" /s \"{1}\" /t \"{2}\" /compress", TempFileName, TempSymStoreDir, Product); StartInfo.UseShellExecute = false; StartInfo.CreateNoWindow = true; if (Utils.RunLocalProcessAndLogOutput(StartInfo) != 0) { return(false); } } finally { File.Delete(TempFileName); } DateTime CompressDone = DateTime.Now; LogInformation("Took {0}s to compress the symbol files", (CompressDone - Start).TotalSeconds); // Take each new compressed file made and try and copy it to the real symstore. Exclude any symstore admin files foreach (FileReference File in DirectoryReference.EnumerateFiles(TempSymStoreDir, "*.*", SearchOption.AllDirectories).Where(File => File.HasExtension(".dl_") || File.HasExtension(".ex_") || File.HasExtension(".pd_"))) { string RelativePath = File.MakeRelativeTo(DirectoryReference.Combine(TempSymStoreDir)); FileReference ActualDestinationFile = FileReference.Combine(SymbolStoreDirectory, RelativePath); // Try and add a version file. Do this before checking to see if the symbol is there already in the case of exact matches (multiple builds could use the same pdb, for example) if (!string.IsNullOrWhiteSpace(BuildVersion)) { FileReference BuildVersionFile = FileReference.Combine(ActualDestinationFile.Directory, string.Format("{0}.version", BuildVersion)); // Attempt to create the file. Just continue if it fails. try { DirectoryReference.CreateDirectory(BuildVersionFile.Directory); FileReference.WriteAllText(BuildVersionFile, string.Empty); } catch (Exception Ex) { LogWarning("Failed to write the version file, reason {0}", Ex.ToString()); } } // Don't bother copying the temp file if the destination file is there already. if (FileReference.Exists(ActualDestinationFile)) { LogInformation("Destination file {0} already exists, skipping", ActualDestinationFile.FullName); continue; } FileReference TempDestinationFile = new FileReference(ActualDestinationFile.FullName + Guid.NewGuid().ToString()); try { CommandUtils.CopyFile(File.FullName, TempDestinationFile.FullName); } catch (Exception Ex) { throw new AutomationException("Couldn't copy the symbol file to the temp store! Reason: {0}", Ex.ToString()); } // Move the file in the temp store over. try { FileReference.Move(TempDestinationFile, ActualDestinationFile); } catch (Exception Ex) { // If the file is there already, it was likely either copied elsewhere (and this is an ioexception) or it had a file handle open already. // Either way, it's fine to just continue on. if (FileReference.Exists(ActualDestinationFile)) { LogInformation("Destination file {0} already exists or was in use, skipping.", ActualDestinationFile.FullName); continue; } // If it doesn't exist, we actually failed to copy it entirely. else { LogWarning("Couldn't move temp file {0} to the symbol store at location {1}! Reason: {2}", TempDestinationFile.FullName, ActualDestinationFile.FullName, Ex.ToString()); } } // Delete the temp one no matter what, don't want them hanging around in the symstore finally { FileReference.Delete(TempDestinationFile); } } LogInformation("Took {0}s to copy the symbol files to the store", (DateTime.Now - CompressDone).TotalSeconds); } return(true); }