diff options
Diffstat (limited to 'modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs')
-rw-r--r-- | modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs | 425 |
1 files changed, 0 insertions, 425 deletions
diff --git a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs b/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs deleted file mode 100644 index e5044feb75..0000000000 --- a/modules/mono/editor/GodotSharpTools/Build/BuildSystem.cs +++ /dev/null @@ -1,425 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Diagnostics; -using System.IO; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Security; -using Microsoft.Build.Framework; - -namespace GodotSharpTools.Build -{ - public class BuildInstance : IDisposable - { - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static void godot_icall_BuildInstance_ExitCallback(string solution, string config, int exitCode); - - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static string godot_icall_BuildInstance_get_MSBuildPath(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static string godot_icall_BuildInstance_get_MonoWindowsBinDir(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static bool godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); - [MethodImpl(MethodImplOptions.InternalCall)] - private extern static bool godot_icall_BuildInstance_get_PrintBuildOutput(); - - private static string GetMSBuildPath() - { - string msbuildPath = godot_icall_BuildInstance_get_MSBuildPath(); - - if (msbuildPath == null) - throw new FileNotFoundException("Cannot find the MSBuild executable."); - - return msbuildPath; - } - - private static string MonoWindowsBinDir - { - get - { - string monoWinBinDir = godot_icall_BuildInstance_get_MonoWindowsBinDir(); - - if (monoWinBinDir == null) - throw new FileNotFoundException("Cannot find the Windows Mono binaries directory."); - - return monoWinBinDir; - } - } - - private static bool UsingMonoMSBuildOnWindows - { - get - { - return godot_icall_BuildInstance_get_UsingMonoMSBuildOnWindows(); - } - } - - private static bool PrintBuildOutput - { - get - { - return godot_icall_BuildInstance_get_PrintBuildOutput(); - } - } - - private string solution; - private string config; - - private Process process; - - private int exitCode; - public int ExitCode { get { return exitCode; } } - - public bool IsRunning { get { return process != null && !process.HasExited; } } - - public BuildInstance(string solution, string config) - { - this.solution = solution; - this.config = config; - } - - public bool Build(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) - { - List<string> customPropertiesList = new List<string>(); - - if (customProperties != null) - customPropertiesList.AddRange(customProperties); - - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - - ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - - bool redirectOutput = !IsDebugMSBuildRequested() && !PrintBuildOutput; - - if (!redirectOutput) // TODO: or if stdout verbose - Console.WriteLine($"Running: \"{startInfo.FileName}\" {startInfo.Arguments}"); - - startInfo.RedirectStandardOutput = redirectOutput; - startInfo.RedirectStandardError = redirectOutput; - startInfo.UseShellExecute = false; - - if (UsingMonoMSBuildOnWindows) - { - // These environment variables are required for Mono's MSBuild to find the compilers. - // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. - string monoWinBinDir = MonoWindowsBinDir; - startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); - startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); - startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); - } - - // Needed when running from Developer Command Prompt for VS - RemovePlatformVariable(startInfo.EnvironmentVariables); - - using (Process process = new Process()) - { - process.StartInfo = startInfo; - - process.Start(); - - if (redirectOutput) - { - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - } - - process.WaitForExit(); - - exitCode = process.ExitCode; - } - - return true; - } - - public bool BuildAsync(string loggerAssemblyPath, string loggerOutputDir, string[] customProperties = null) - { - if (process != null) - throw new InvalidOperationException("Already in use"); - - List<string> customPropertiesList = new List<string>(); - - if (customProperties != null) - customPropertiesList.AddRange(customProperties); - - string compilerArgs = BuildArguments(loggerAssemblyPath, loggerOutputDir, customPropertiesList); - - ProcessStartInfo startInfo = new ProcessStartInfo(GetMSBuildPath(), compilerArgs); - - bool redirectOutput = !IsDebugMSBuildRequested() && !PrintBuildOutput; - - if (!redirectOutput) // TODO: or if stdout verbose - Console.WriteLine($"Running: \"{startInfo.FileName}\" {startInfo.Arguments}"); - - startInfo.RedirectStandardOutput = redirectOutput; - startInfo.RedirectStandardError = redirectOutput; - startInfo.UseShellExecute = false; - - if (UsingMonoMSBuildOnWindows) - { - // These environment variables are required for Mono's MSBuild to find the compilers. - // We use the batch files in Mono's bin directory to make sure the compilers are executed with mono. - string monoWinBinDir = MonoWindowsBinDir; - startInfo.EnvironmentVariables.Add("CscToolExe", Path.Combine(monoWinBinDir, "csc.bat")); - startInfo.EnvironmentVariables.Add("VbcToolExe", Path.Combine(monoWinBinDir, "vbc.bat")); - startInfo.EnvironmentVariables.Add("FscToolExe", Path.Combine(monoWinBinDir, "fsharpc.bat")); - } - - // Needed when running from Developer Command Prompt for VS - RemovePlatformVariable(startInfo.EnvironmentVariables); - - process = new Process(); - process.StartInfo = startInfo; - process.EnableRaisingEvents = true; - process.Exited += new EventHandler(BuildProcess_Exited); - - process.Start(); - - if (redirectOutput) - { - process.BeginOutputReadLine(); - process.BeginErrorReadLine(); - } - - return true; - } - - private string BuildArguments(string loggerAssemblyPath, string loggerOutputDir, List<string> customProperties) - { - string arguments = string.Format(@"""{0}"" /v:normal /t:Rebuild ""/p:{1}"" ""/l:{2},{3};{4}""", - solution, - "Configuration=" + config, - typeof(GodotBuildLogger).FullName, - loggerAssemblyPath, - loggerOutputDir - ); - - foreach (string customProperty in customProperties) - { - arguments += " /p:" + customProperty; - } - - return arguments; - } - - private void RemovePlatformVariable(StringDictionary environmentVariables) - { - // EnvironmentVariables is case sensitive? Seriously? - - List<string> platformEnvironmentVariables = new List<string>(); - - foreach (string env in environmentVariables.Keys) - { - if (env.ToUpper() == "PLATFORM") - platformEnvironmentVariables.Add(env); - } - - foreach (string env in platformEnvironmentVariables) - environmentVariables.Remove(env); - } - - private void BuildProcess_Exited(object sender, System.EventArgs e) - { - exitCode = process.ExitCode; - - godot_icall_BuildInstance_ExitCallback(solution, config, exitCode); - - Dispose(); - } - - private static bool IsDebugMSBuildRequested() - { - return Environment.GetEnvironmentVariable("GODOT_DEBUG_MSBUILD")?.Trim() == "1"; - } - - public void Dispose() - { - if (process != null) - { - process.Dispose(); - process = null; - } - } - } - - public class GodotBuildLogger : ILogger - { - public string Parameters { get; set; } - public LoggerVerbosity Verbosity { get; set; } - - public void Initialize(IEventSource eventSource) - { - if (null == Parameters) - throw new LoggerException("Log directory was not set."); - - string[] parameters = Parameters.Split(new[] { ';' }); - - string logDir = parameters[0]; - - if (String.IsNullOrEmpty(logDir)) - throw new LoggerException("Log directory was not set."); - - if (parameters.Length > 1) - throw new LoggerException("Too many parameters passed."); - - string logFile = Path.Combine(logDir, "msbuild_log.txt"); - string issuesFile = Path.Combine(logDir, "msbuild_issues.csv"); - - try - { - if (!Directory.Exists(logDir)) - Directory.CreateDirectory(logDir); - - this.logStreamWriter = new StreamWriter(logFile); - this.issuesStreamWriter = new StreamWriter(issuesFile); - } - catch (Exception ex) - { - if - ( - ex is UnauthorizedAccessException - || ex is ArgumentNullException - || ex is PathTooLongException - || ex is DirectoryNotFoundException - || ex is NotSupportedException - || ex is ArgumentException - || ex is SecurityException - || ex is IOException - ) - { - throw new LoggerException("Failed to create log file: " + ex.Message); - } - else - { - // Unexpected failure - throw; - } - } - - eventSource.ProjectStarted += new ProjectStartedEventHandler(eventSource_ProjectStarted); - eventSource.TaskStarted += new TaskStartedEventHandler(eventSource_TaskStarted); - eventSource.MessageRaised += new BuildMessageEventHandler(eventSource_MessageRaised); - eventSource.WarningRaised += new BuildWarningEventHandler(eventSource_WarningRaised); - eventSource.ErrorRaised += new BuildErrorEventHandler(eventSource_ErrorRaised); - eventSource.ProjectFinished += new ProjectFinishedEventHandler(eventSource_ProjectFinished); - } - - void eventSource_ErrorRaised(object sender, BuildErrorEventArgs e) - { - string line = String.Format("{0}({1},{2}): error {3}: {4}", e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message); - - if (e.ProjectFile.Length > 0) - line += string.Format(" [{0}]", e.ProjectFile); - - WriteLine(line); - - string errorLine = String.Format(@"error,{0},{1},{2},{3},{4},{5}", - e.File.CsvEscape(), e.LineNumber, e.ColumnNumber, - e.Code.CsvEscape(), e.Message.CsvEscape(), e.ProjectFile.CsvEscape()); - issuesStreamWriter.WriteLine(errorLine); - } - - void eventSource_WarningRaised(object sender, BuildWarningEventArgs e) - { - string line = String.Format("{0}({1},{2}): warning {3}: {4}", e.File, e.LineNumber, e.ColumnNumber, e.Code, e.Message, e.ProjectFile); - - if (e.ProjectFile != null && e.ProjectFile.Length > 0) - line += string.Format(" [{0}]", e.ProjectFile); - - WriteLine(line); - - string warningLine = String.Format(@"warning,{0},{1},{2},{3},{4},{5}", - e.File.CsvEscape(), e.LineNumber, e.ColumnNumber, - e.Code.CsvEscape(), e.Message.CsvEscape(), e.ProjectFile != null ? e.ProjectFile.CsvEscape() : string.Empty); - issuesStreamWriter.WriteLine(warningLine); - } - - void eventSource_MessageRaised(object sender, BuildMessageEventArgs e) - { - // BuildMessageEventArgs adds Importance to BuildEventArgs - // Let's take account of the verbosity setting we've been passed in deciding whether to log the message - if ((e.Importance == MessageImportance.High && IsVerbosityAtLeast(LoggerVerbosity.Minimal)) - || (e.Importance == MessageImportance.Normal && IsVerbosityAtLeast(LoggerVerbosity.Normal)) - || (e.Importance == MessageImportance.Low && IsVerbosityAtLeast(LoggerVerbosity.Detailed)) - ) - { - WriteLineWithSenderAndMessage(String.Empty, e); - } - } - - void eventSource_TaskStarted(object sender, TaskStartedEventArgs e) - { - // TaskStartedEventArgs adds ProjectFile, TaskFile, TaskName - // To keep this log clean, this logger will ignore these events. - } - - void eventSource_ProjectStarted(object sender, ProjectStartedEventArgs e) - { - WriteLine(e.Message); - indent++; - } - - void eventSource_ProjectFinished(object sender, ProjectFinishedEventArgs e) - { - indent--; - WriteLine(e.Message); - } - - /// <summary> - /// Write a line to the log, adding the SenderName - /// </summary> - private void WriteLineWithSender(string line, BuildEventArgs e) - { - if (0 == String.Compare(e.SenderName, "MSBuild", true /*ignore case*/)) - { - // Well, if the sender name is MSBuild, let's leave it out for prettiness - WriteLine(line); - } - else - { - WriteLine(e.SenderName + ": " + line); - } - } - - /// <summary> - /// Write a line to the log, adding the SenderName and Message - /// (these parameters are on all MSBuild event argument objects) - /// </summary> - private void WriteLineWithSenderAndMessage(string line, BuildEventArgs e) - { - if (0 == String.Compare(e.SenderName, "MSBuild", true /*ignore case*/)) - { - // Well, if the sender name is MSBuild, let's leave it out for prettiness - WriteLine(line + e.Message); - } - else - { - WriteLine(e.SenderName + ": " + line + e.Message); - } - } - - private void WriteLine(string line) - { - for (int i = indent; i > 0; i--) - { - logStreamWriter.Write("\t"); - } - logStreamWriter.WriteLine(line); - } - - public void Shutdown() - { - logStreamWriter.Close(); - issuesStreamWriter.Close(); - } - - public bool IsVerbosityAtLeast(LoggerVerbosity checkVerbosity) - { - return this.Verbosity >= checkVerbosity; - } - - private StreamWriter logStreamWriter; - private StreamWriter issuesStreamWriter; - private int indent; - } -} |