/// <summary> /// Handle a response from the server, reporting messages and returning /// the appropriate exit code. /// </summary> private int HandleResponse(BuildResponse response, string pathToTool, string responseFileCommands, string commandLineCommands) { if (response.Type != BuildResponse.ResponseType.Completed) { ValidateBootstrapUtil.AddFailedServerConnection(response.Type, OutputAssembly?.ItemSpec); } switch (response.Type) { case BuildResponse.ResponseType.Completed: var completedResponse = (CompletedBuildResponse)response; LogMessages(completedResponse.Output, StandardOutputImportanceToUse); if (LogStandardErrorAsError) { LogErrorMultiline(completedResponse.ErrorOutput); } else { LogMessages(completedResponse.ErrorOutput, StandardErrorImportanceToUse); } return(completedResponse.ReturnCode); case BuildResponse.ResponseType.MismatchedVersion: LogError("Roslyn compiler server reports different protocol version than build task."); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); case BuildResponse.ResponseType.IncorrectHash: LogError("Roslyn compiler server reports different hash version than build task."); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); case BuildResponse.ResponseType.Rejected: case BuildResponse.ResponseType.AnalyzerInconsistency: CompilerServerLogger.LogError($"Server rejected request {response.Type}"); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); default: LogError($"Received an unrecognized response from the server: {response.Type}"); return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } }
protected override int ExecuteTool(string pathToTool, string responseFileCommands, string commandLineCommands) { if (ProvideCommandLineArgs) { CommandLineArgs = GetArguments(commandLineCommands, responseFileCommands) .Select(arg => new TaskItem(arg)).ToArray(); } if (SkipCompilerExecution) { return(0); } try { string workingDir = CurrentDirectoryToUse(); string?tempDir = BuildServerConnection.GetTempPath(workingDir); if (!UseSharedCompilation || HasToolBeenOverridden || !BuildServerConnection.IsCompilerServerSupported) { return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } using var logger = new CompilerServerLogger(); using (_sharedCompileCts = new CancellationTokenSource()) { logger.Log($"CommandLine = '{commandLineCommands}'"); logger.Log($"BuildResponseFile = '{responseFileCommands}'"); var clientDir = Path.GetDirectoryName(PathToManagedTool); if (clientDir is null || tempDir is null) { return(base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands)); } // Note: we can't change the "tool path" printed to the console when we run // the Csc/Vbc task since MSBuild logs it for us before we get here. Instead, // we'll just print our own message that contains the real client location Log.LogMessage(ErrorString.UsingSharedCompilation, clientDir); var buildPaths = new BuildPathsAlt( clientDir: clientDir, workingDir: workingDir, // MSBuild doesn't need the .NET SDK directory sdkDir: null, tempDir: tempDir); // Note: using ToolArguments here (the property) since // commandLineCommands (the parameter) may have been mucked with // (to support using the dotnet cli) var responseTask = BuildServerConnection.RunServerCompilationAsync( Language, RoslynString.IsNullOrEmpty(SharedCompilationId) ? null : SharedCompilationId, GetArguments(ToolArguments, responseFileCommands).ToList(), buildPaths, keepAlive: null, libEnvVariable: LibDirectoryToUse(), logger: logger, cancellationToken: _sharedCompileCts.Token); responseTask.Wait(_sharedCompileCts.Token); var response = responseTask.Result; if (response != null) { ExitCode = HandleResponse(response, pathToTool, responseFileCommands, commandLineCommands, logger); } else { logger.LogError($"Server compilation failed, falling back to {pathToTool}"); Log.LogMessage(ErrorString.SharedCompilationFallback, pathToTool); ExitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); } } } catch (OperationCanceledException) { ExitCode = 0; } catch (Exception e) { var util = new TaskLoggingHelper(this); util.LogErrorWithCodeFromResources("Compiler_UnexpectedException"); util.LogErrorFromException(e, showStackTrace: true, showDetail: true, file: null); ExitCode = -1; } return(ExitCode); }
internal void LogError(string message) { CompilerServerLogger.LogError(message); Log.LogError(message); }