/// <inheritdoc/> public FileItem CreateIntermediateTextFile(FileReference Location, string Contents) { // Write the file Utils.WriteFileIfChanged(Location, Contents, StringComparison.InvariantCultureIgnoreCase); // Reset the file info, in case it already knows about the old file FileItem Item = FileItem.GetItemByFileReference(Location); InternalDependencies.Add(Item); Item.ResetCachedInfo(); return(Item); }
public PVSToolChain(ReadOnlyTargetRules Target) { this.Target = Target; Platform = Target.Platform; InnerToolChain = new VCToolChain(Target); AnalyzerFile = FileReference.Combine(new DirectoryReference(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)), "PVS-Studio", "x64", "PVS-Studio.exe"); if (!FileReference.Exists(AnalyzerFile)) { FileReference EngineAnalyzerFile = FileReference.Combine(UnrealBuildTool.RootDirectory, "Engine", "Extras", "ThirdPartyNotUE", "NoRedist", "PVS-Studio", "PVS-Studio.exe"); if (FileReference.Exists(EngineAnalyzerFile)) { AnalyzerFile = EngineAnalyzerFile; } else { throw new BuildException("Unable to find PVS-Studio at {0} or {1}", AnalyzerFile, EngineAnalyzerFile); } } Settings = Target.WindowsPlatform.PVS; ApplicationSettings = Settings.ApplicationSettings; if (ApplicationSettings != null) { if (Settings.ModeFlags == 0) { throw new BuildException("All PVS-Studio analysis modes are disabled."); } if (!String.IsNullOrEmpty(ApplicationSettings.UserName) && !String.IsNullOrEmpty(ApplicationSettings.SerialNumber)) { LicenseFile = FileReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "PVS", "PVS-Studio.lic"); Utils.WriteFileIfChanged(LicenseFile, String.Format("{0}\n{1}\n", ApplicationSettings.UserName, ApplicationSettings.SerialNumber), StringComparison.Ordinal); } } else { FileReference DefaultLicenseFile = AnalyzerFile.ChangeExtension(".lic"); if (FileReference.Exists(DefaultLicenseFile)) { LicenseFile = DefaultLicenseFile; } } }
internal bool ExecuteActions(List <Action> InActions, Dictionary <Action, ActionThread> InActionThreadDictionary) { // Build the script file that will be executed by SN-DBS StreamWriter ScriptFile; string ScriptFilename = Path.Combine(UnrealBuildTool.EngineDirectory.FullName, "Intermediate", "Build", "SNDBS.bat"); FileStream ScriptFileStream = new FileStream(ScriptFilename, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); ScriptFile = new StreamWriter(ScriptFileStream); ScriptFile.AutoFlush = true; int NumScriptedActions = 0; List <Action> LocalActions = new List <Action>(); ActionThread DummyActionThread = new ActionThread(null, 1, 1); bool PrintDebugInfo = true; foreach (Action Action in InActions) { ActionThread ActionProcess = null; bool bFoundActionProcess = InActionThreadDictionary.TryGetValue(Action, out ActionProcess); if (bFoundActionProcess == false) { // Determine whether there are any prerequisites of the action that are outdated. bool bHasOutdatedPrerequisites = false; bool bHasFailedPrerequisites = false; foreach (Action PrerequisiteAction in Action.PrerequisiteActions) { if (InActions.Contains(PrerequisiteAction)) { ActionThread PrerequisiteProcess = null; bool bFoundPrerequisiteProcess = InActionThreadDictionary.TryGetValue(PrerequisiteAction, out PrerequisiteProcess); if (bFoundPrerequisiteProcess == true) { if (PrerequisiteProcess == null) { bHasFailedPrerequisites = true; } else if (PrerequisiteProcess.bComplete == false) { bHasOutdatedPrerequisites = true; } else if (PrerequisiteProcess.ExitCode != 0) { bHasFailedPrerequisites = true; } } else { bHasOutdatedPrerequisites = true; } } } // If there are any failed prerequisites of this action, don't execute it. if (bHasFailedPrerequisites) { // Add a null entry in the dictionary for this action. InActionThreadDictionary.Add(Action, null); } // If there aren't any outdated prerequisites of this action, execute it. else if (!bHasOutdatedPrerequisites) { if (Action.bCanExecuteRemotely == false || Action.bCanExecuteRemotelyWithSNDBS == false) { // Execute locally LocalActions.Add(Action); } else { // Create a dummy force-included file which references PCH files, so that SN-DBS knows they are dependencies. string AdditionalStubIncludes = ""; if (Action.CommandPath.GetFileName().Equals("cl.exe", StringComparison.OrdinalIgnoreCase) || Action.CommandPath.GetFileName().Equals("cl-filter.exe", StringComparison.OrdinalIgnoreCase)) { string DummyPCHIncludeFile = Action.DependencyListFile.AbsolutePath.Replace("\"", "").Replace("@", "").Trim(); DummyPCHIncludeFile = Path.ChangeExtension(DummyPCHIncludeFile, null); StringBuilder WrapperContents = new StringBuilder(); using (StringWriter Writer = new StringWriter(WrapperContents)) { Writer.WriteLine("// PCH dependencies for {0}", DummyPCHIncludeFile); Writer.WriteLine("#if 0"); foreach (FileItem Preqrequisite in Action.PrerequisiteItems) { if (Preqrequisite.AbsolutePath.EndsWith(".pch")) { Writer.WriteLine("#include \"{0}\"", Preqrequisite.AbsolutePath.Replace(".pch", ".obj")); } } Writer.WriteLine("#endif"); } FileReference DummyPCHIncludeFileDependency = new FileReference(DummyPCHIncludeFile + ".dummy.h"); Utils.WriteFileIfChanged(DummyPCHIncludeFileDependency, WrapperContents.ToString(), StringComparison.OrdinalIgnoreCase); AdditionalStubIncludes = string.Format("/FI\"{0}\"", DummyPCHIncludeFileDependency); } // Add to script for execution by SN-DBS string NewCommandArguments = "\"" + Action.CommandPath + "\"" + " " + Action.CommandArguments + " " + AdditionalStubIncludes; ScriptFile.WriteLine(NewCommandArguments); InActionThreadDictionary.Add(Action, DummyActionThread); Action.StartTime = Action.EndTime = DateTimeOffset.Now; Log.TraceInformation("[{0}/{1}] {2} {3}", JobNumber, InActions.Count, Action.CommandDescription, Action.StatusDescription); JobNumber++; NumScriptedActions++; PrintDebugInfo |= Action.bPrintDebugInfo; if (Action.DependencyListFile != null && File.Exists(Action.DependencyListFile.AbsolutePath)) { Log.TraceVerbose("Deleting dependency list file {0}", Action.DependencyListFile.AbsolutePath); File.Delete(Action.DependencyListFile.AbsolutePath); } } } } } ScriptFile.Flush(); ScriptFile.Close(); ScriptFile.Dispose(); ScriptFile = null; if (NumScriptedActions > 0) { // Create the process string SCERoot = Environment.GetEnvironmentVariable("SCE_ROOT_DIR"); string SNDBSExecutable = Path.Combine(SCERoot, "Common/SN-DBS/bin/dbsbuild.exe"); DirectoryReference TemplatesDir = DirectoryReference.Combine(UnrealBuildTool.EngineDirectory, "Programs", "UnrealBuildTool", "SndbsTemplates"); string IncludeRewriteRulesArg = String.Format("--include-rewrite-rules \"{0}\"", IncludeRewriteRulesFile.FullName); string VerbosityLevel = PrintDebugInfo ? "-v" : "-q"; ProcessStartInfo PSI = new ProcessStartInfo(SNDBSExecutable, String.Format("{0} -p UE4Code -s \"{1}\" -templates \"{2}\" {3}", VerbosityLevel, FileReference.Combine(UnrealBuildTool.EngineDirectory, "Intermediate", "Build", "sndbs.bat").FullName, TemplatesDir.FullName, IncludeRewriteRulesArg)); PSI.RedirectStandardOutput = true; PSI.RedirectStandardError = true; PSI.UseShellExecute = false; PSI.CreateNoWindow = true; PSI.WorkingDirectory = Path.GetFullPath("."); Process NewProcess = new Process(); NewProcess.StartInfo = PSI; NewProcess.OutputDataReceived += new DataReceivedEventHandler(ActionDebugOutput); NewProcess.ErrorDataReceived += new DataReceivedEventHandler(ActionDebugOutput); DateTimeOffset StartTime = DateTimeOffset.Now; NewProcess.Start(); NewProcess.BeginOutputReadLine(); NewProcess.BeginErrorReadLine(); NewProcess.WaitForExit(); //TimeSpan Duration; //DateTimeOffset EndTime = DateTimeOffset.Now; //if (EndTime == DateTimeOffset.MinValue) //{ // Duration = DateTimeOffset.Now - StartTime; //} //else //{ // Duration = EndTime - StartTime; //} DummyActionThread.bComplete = true; int ExitCode = NewProcess.ExitCode; if (ExitCode != 0) { return(false); } } // Execute local tasks if (LocalActions.Count > 0) { return(ExecuteLocalActions(LocalActions, InActionThreadDictionary, InActions.Count)); } return(true); }
/// <inheritdoc/> public virtual FileItem CreateIntermediateTextFile(FileReference Location, string Contents) { Utils.WriteFileIfChanged(Location, Contents, StringComparison.OrdinalIgnoreCase); return(FileItem.GetItemByFileReference(Location)); }