public static Task<BuildResponse> RunServerCompilation( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) => Task.FromResult<BuildResponse>(null);
public bool TryCreateCompiler(RunRequest request, out CommonCompiler compiler) { var buildPaths = new BuildPaths(ClientDirectory, request.CurrentDirectory, SdkDirectory, request.TempDirectory); switch (request.Language) { case LanguageNames.CSharp: compiler = new CSharpCompilerServer( AssemblyReferenceProvider, args: request.Arguments, buildPaths: buildPaths, libDirectory: request.LibDirectory, analyzerLoader: AnalyzerAssemblyLoader); return true; case LanguageNames.VisualBasic: compiler = new VisualBasicCompilerServer( AssemblyReferenceProvider, args: request.Arguments, buildPaths: buildPaths, libDirectory: request.LibDirectory, analyzerLoader: AnalyzerAssemblyLoader); return true; default: compiler = null; return false; } }
internal static int Run(string[] args, BuildPaths buildPaths, TextWriter textWriter, IAnalyzerAssemblyLoader analyzerLoader) { FatalError.Handler = FailFast.OnFatalException; var responseFile = Path.Combine(buildPaths.ClientDirectory, CSharpCompiler.ResponseFileName); var compiler = new Csc(responseFile, buildPaths, args, analyzerLoader); return ConsoleUtil.RunWithUtf8Output(compiler.Arguments.Utf8Output, textWriter, tw => compiler.Run(tw)); }
protected override Task<BuildResponse> RunServerCompilation(List<string> arguments, BuildPaths buildPaths, string sessionKey, string keepAlive, string libDirectory, CancellationToken cancellationToken) { if (_runServerCompilationFunc != null) { return _runServerCompilationFunc(); } return base.RunServerCompilation(arguments, buildPaths, sessionKey, keepAlive, libDirectory, cancellationToken); }
protected override async Task<BuildResponse> RunServerCompilation(List<string> arguments, BuildPaths buildPaths, string keepAlive, string libDirectory, CancellationToken cancellationToken) { var client = new TcpClient(); await client.ConnectAsync("127.0.0.1", port: 12000).ConfigureAwait(true); var request = BuildRequest.Create(_language, buildPaths.WorkingDirectory, arguments, keepAlive, libDirectory); await request.WriteAsync(client.GetStream(), cancellationToken).ConfigureAwait(true); return await BuildResponse.ReadAsync(client.GetStream(), cancellationToken).ConfigureAwait(true); }
internal static int Run(IEnumerable<string> arguments, IEnumerable<string> extraArguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { var client = new DesktopBuildClient(language, compileFunc, analyzerAssemblyLoader); var clientDir = AppDomain.CurrentDomain.BaseDirectory; var sdkDir = RuntimeEnvironment.GetRuntimeDirectory(); var workingDir = Directory.GetCurrentDirectory(); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir); var originalArguments = BuildClient.GetCommandLineArgs(arguments).Concat(extraArguments).ToArray(); return client.RunCompilation(originalArguments, buildPaths).ExitCode; }
protected override Task<BuildResponse> RunServerCompilation( List<string> arguments, BuildPaths buildPaths, string sessionKey, string keepAlive, string libDirectory, CancellationToken cancellationToken) { return RunServerCompilationCore(_language, arguments, buildPaths, sessionKey, keepAlive, libDirectory, TimeoutOverride, TryCreateServer, cancellationToken); }
protected override Task<BuildResponse> RunServerCompilation( List<string> arguments, BuildPaths buildPaths, string keepAlive, string libDirectory, CancellationToken cancellationToken) { var pipeName = GetPipeName(buildPaths.ClientDirectory); return RunServerCompilationCore(_language, arguments, buildPaths, pipeName, keepAlive, libDirectory, TryCreateServer, cancellationToken); }
public static Task<BuildResponse> RunServerCompilation( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) { throw new NotSupportedException(); }
internal static int Run(IEnumerable<string> arguments, RequestLanguage language, CompileFunc compileFunc) { // BTODO: Should be using BuildClient.GetCommandLineArgs(arguments) here. But the native invoke // ends up giving us both CoreRun and the exe file. Need to find a good way to remove the host // as well as the EXE argument. var client = new CoreClrBuildClient(language, compileFunc); var clientDir = AppContext.BaseDirectory; var workingDir = Directory.GetCurrentDirectory(); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: null); return client.RunCompilation(arguments, buildPaths); }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable<string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List<string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { Console.Out.WriteLine(errorMessage); return RunCompilationResult.Failed; } if (hasShared) { var libDirectory = Environment.GetEnvironmentVariable("LIB"); try { sessionKey = sessionKey ?? GetSessionKey(buildPaths); var buildResponseTask = RunServerCompilation( parsedArgs, buildPaths, sessionKey, keepAlive, libDirectory, CancellationToken.None); var buildResponse = buildResponseTask.Result; if (buildResponse != null) { return HandleResponse(buildResponse, parsedArgs.ToArray(), buildPaths, textWriter); } } catch (OperationCanceledException) { // #7866 tracks cleaning up this code. return RunCompilationResult.Succeeded; } } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return new RunCompilationResult(exitCode); }
internal static int Run(IEnumerable<string> arguments, RequestLanguage language, CompileFunc compileFunc) { // Should be using BuildClient.GetCommandLineArgs(arguments) here. But the native invoke // ends up giving us both CoreRun and the exe file. Need to find a good way to remove the host // as well as the EXE argument. // https://github.com/dotnet/roslyn/issues/6677 var client = new CoreClrBuildClient(language, compileFunc); var clientDir = AppContext.BaseDirectory; var workingDir = Directory.GetCurrentDirectory(); var tempDir = Path.GetTempPath(); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: null, tempDir: tempDir); return client.RunCompilation(arguments, buildPaths).ExitCode; }
public static Task<BuildResponse> RunServerCompilation( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) => DesktopBuildClient.RunServerCompilation( language, arguments, buildPaths, keepAlive, libEnvVariable, cancellationToken);
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal int RunCompilation(IEnumerable<string> originalArguments, BuildPaths buildPaths) { var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List<string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { Console.Out.WriteLine(errorMessage); return CommonCompiler.Failed; } if (hasShared) { var libDirectory = Environment.GetEnvironmentVariable("LIB"); try { sessionKey = sessionKey ?? GetSessionKey(buildPaths); var buildResponseTask = RunServerCompilation( parsedArgs, buildPaths, sessionKey, keepAlive, libDirectory, CancellationToken.None); var buildResponse = buildResponseTask.Result; if (buildResponse != null) { return HandleResponse(buildResponse, parsedArgs, buildPaths); } } catch { // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. } } return RunLocalCompilation(parsedArgs, buildPaths.ClientDirectory, buildPaths.SdkDirectory); }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal int RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths) { var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; List <string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out errorMessage)) { Console.Out.WriteLine(errorMessage); return(CommonCompiler.Failed); } if (hasShared) { var libDirectory = Environment.GetEnvironmentVariable("LIB"); try { var buildResponseTask = RunServerCompilation( parsedArgs, buildPaths, keepAlive, libDirectory, CancellationToken.None); var buildResponse = buildResponseTask.Result; if (buildResponse != null) { return(HandleResponse(buildResponse, parsedArgs, buildPaths)); } } catch { // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. } } return(RunLocalCompilation(parsedArgs, buildPaths.ClientDirectory, buildPaths.SdkDirectory)); }
public static Task <BuildResponse> RunServerCompilation( RequestLanguage language, List <string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) { return(RunServerCompilationCore( language, arguments, buildPaths, GetPipeNameFromFileInfo(buildPaths.ClientDirectory), keepAlive, libEnvVariable, TryCreateServerCore, cancellationToken)); }
internal static int Run(IEnumerable <string> arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { // Register encodings for console // https://github.com/dotnet/roslyn/issues/10785 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); // Should be using BuildClient.GetCommandLineArgs(arguments) here. But the native invoke // ends up giving us both CoreRun and the exe file. Need to find a good way to remove the host // as well as the EXE argument. // https://github.com/dotnet/roslyn/issues/6677 var client = new CoreClrBuildClient(language, compileFunc, analyzerAssemblyLoader); var clientDir = AppContext.BaseDirectory; var workingDir = Directory.GetCurrentDirectory(); var tempDir = Path.GetTempPath(); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: null, tempDir: tempDir); return(client.RunCompilation(arguments, buildPaths).ExitCode); }
public static Task<BuildResponse> RunServerCompilation( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) { return RunServerCompilationCore( language, arguments, buildPaths, GetPipeNameFromFileInfo(buildPaths.ClientDirectory), keepAlive, libEnvVariable, TryCreateServerCore, cancellationToken); }
public static Task<BuildResponse> RunServerCompilation( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) { return RunServerCompilationCore( language, arguments, buildPaths, GetPipeNameForPath(buildPaths.ClientDirectory), keepAlive, libEnvVariable, timeoutOverride: null, tryCreateServerFunc: TryCreateServerCore, cancellationToken: cancellationToken); }
public static Task <BuildResponse> RunServerCompilation( RequestLanguage language, List <string> arguments, BuildPaths buildPaths, string keepAlive, string libEnvVariable, CancellationToken cancellationToken) { return(RunServerCompilationCore( language, arguments, buildPaths, GetPipeNameForPath(buildPaths.ClientDirectory), keepAlive, libEnvVariable, timeoutOverride: null, tryCreateServerFunc: TryCreateServerCore, cancellationToken: cancellationToken)); }
internal static int Run(IEnumerable <string> arguments, RequestLanguage language, CompileFunc compileFunc, IAnalyzerAssemblyLoader analyzerAssemblyLoader) { var sdkDir = GetSystemSdkDirectory(); if (CoreClrShim.IsRunningOnCoreClr) { // Register encodings for console // https://github.com/dotnet/roslyn/issues/10785 System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); } var client = new DesktopBuildClient(language, compileFunc, analyzerAssemblyLoader); var clientDir = AppContext.BaseDirectory; var workingDir = Directory.GetCurrentDirectory(); var tempDir = BuildServerConnection.GetTempPath(workingDir); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir, tempDir: tempDir); var originalArguments = GetCommandLineArgs(arguments); return(client.RunCompilation(originalArguments, buildPaths).ExitCode); }
internal static int Run(IEnumerable <string> arguments, RequestLanguage language, CompileFunc compileFunc, ICompilerServerLogger logger, Guid?requestId = null) { var sdkDir = GetSystemSdkDirectory(); if (RuntimeHostInfo.IsCoreClrRuntime) { // Register encodings for console // https://github.com/dotnet/roslyn/issues/10785 System.Text.Encoding.RegisterProvider(System.Text.CodePagesEncodingProvider.Instance); } var client = new BuildClient(language, compileFunc, logger); var clientDir = AppContext.BaseDirectory; var workingDir = Directory.GetCurrentDirectory(); var tempDir = BuildServerConnection.GetTempPath(workingDir); var buildPaths = new BuildPaths(clientDir: clientDir, workingDir: workingDir, sdkDir: sdkDir, tempDir: tempDir); var originalArguments = GetCommandLineArgs(arguments); return(client.RunCompilation(originalArguments, buildPaths, requestId: requestId).ExitCode); }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable<string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List<string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { Console.Out.WriteLine(errorMessage); return RunCompilationResult.Failed; } if (hasShared) { sessionKey = sessionKey ?? GetSessionKey(buildPaths); var libDirectory = Environment.GetEnvironmentVariable("LIB"); var serverResult = RunServerCompilation(textWriter, parsedArgs, buildPaths, libDirectory, sessionKey, keepAlive); if (serverResult.HasValue) { Debug.Assert(serverResult.Value.RanOnServer); return serverResult.Value; } } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return new RunCompilationResult(exitCode); }
public DesktopBuildClientTests() { _tempDirectory = Temp.CreateDirectory(); _buildPaths = new BuildPaths(_serverInfo.ClientDirectory, _tempDirectory.Path, _serverInfo.SdkDirectory); }
protected virtual RunCompilationResult HandleResponse(BuildResponse response, string[] arguments, BuildPaths buildPaths, TextWriter textWriter) { switch (response.Type) { case BuildResponse.ResponseType.MismatchedVersion: Console.Error.WriteLine(CommandLineParser.MismatchedVersionErrorText); return(RunCompilationResult.Failed); case BuildResponse.ResponseType.Completed: var completedResponse = (CompletedBuildResponse)response; return(ConsoleUtil.RunWithUtf8Output(completedResponse.Utf8Output, textWriter, tw => { tw.Write(completedResponse.Output); return new RunCompilationResult(completedResponse.ReturnCode, ranOnServer: true); })); case BuildResponse.ResponseType.Rejected: case BuildResponse.ResponseType.AnalyzerInconsistency: var exitCode = RunLocalCompilation(arguments, buildPaths, textWriter); return(new RunCompilationResult(exitCode)); default: throw new InvalidOperationException("Encountered unknown response type"); } }
protected override async Task <BuildResponse> RunServerCompilation(List <string> arguments, BuildPaths buildPaths, string pipeName, string keepAlive, string libDirectory, CancellationToken cancellationToken) { var client = new TcpClient(); var port = int.Parse(pipeName); await client.ConnectAsync("127.0.0.1", port : port).ConfigureAwait(true); var request = BuildRequest.Create(_language, buildPaths.WorkingDirectory, arguments, keepAlive, libDirectory); await request.WriteAsync(client.GetStream(), cancellationToken).ConfigureAwait(true); var ret = await BuildResponse.ReadAsync(client.GetStream(), cancellationToken).ConfigureAwait(true); return(ret); }
internal RunCompilationResult RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null, string pipeName = null, Guid?requestId = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); List <string> parsedArgs; bool hasShared; string keepAliveOpt; string errorMessageOpt; if (CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAliveOpt, out string commandLinePipeName, out errorMessageOpt)) { pipeName ??= commandLinePipeName; }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List <string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { Console.Out.WriteLine(errorMessage); return(RunCompilationResult.Failed); } if (hasShared) { var libDirectory = Environment.GetEnvironmentVariable("LIB"); try { sessionKey = sessionKey ?? GetSessionKey(buildPaths); var buildResponseTask = RunServerCompilation( parsedArgs, buildPaths, sessionKey, keepAlive, libDirectory, CancellationToken.None); var buildResponse = buildResponseTask.Result; if (buildResponse != null) { return(HandleResponse(buildResponse, parsedArgs.ToArray(), buildPaths, textWriter)); } } catch (OperationCanceledException) { // #7866 tracks cleaning up this code. return(RunCompilationResult.Succeeded); } } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return(new RunCompilationResult(exitCode)); }
protected virtual int HandleResponse(BuildResponse response, List <string> arguments, BuildPaths buildPaths) { switch (response.Type) { case BuildResponse.ResponseType.MismatchedVersion: Console.Error.WriteLine(CommandLineParser.MismatchedVersionErrorText); return(CommonCompiler.Failed); case BuildResponse.ResponseType.Completed: var completedResponse = (CompletedBuildResponse)response; return(ConsoleUtil.RunWithOutput( completedResponse.Utf8Output, (outWriter, errorWriter) => { outWriter.Write(completedResponse.Output); errorWriter.Write(completedResponse.ErrorOutput); return completedResponse.ReturnCode; })); case BuildResponse.ResponseType.AnalyzerInconsistency: return(RunLocalCompilation(arguments, buildPaths.ClientDirectory, buildPaths.SdkDirectory)); default: throw new InvalidOperationException("Encountered unknown response type"); } }
protected abstract Task <BuildResponse> RunServerCompilation(List <string> arguments, BuildPaths buildPaths, string sessionName, string keepAlive, string libDirectory, CancellationToken cancellationToken);
private static Task <BuildResponse> RunServerCompilationCore( RequestLanguage language, List <string> arguments, BuildPaths buildPaths, string pipeName, string keepAlive, string libEnvVariable, Func <string, string, bool> tryCreateServerFunc, CancellationToken cancellationToken) { var clientDir = buildPaths.ClientDirectory; var clientMutexName = $"{pipeName}.client"; bool holdsMutex; using (var clientMutex = new Mutex(initiallyOwned: true, name: clientMutexName, createdNew: out holdsMutex)) { try { if (!holdsMutex) { try { holdsMutex = clientMutex.WaitOne(TimeOutMsNewProcess); if (!holdsMutex) { return(Task.FromResult <BuildResponse>(null)); } } catch (AbandonedMutexException) { holdsMutex = true; } } // Check for an already running server var serverMutexName = $"{pipeName}.server"; Mutex mutexIgnore; bool wasServerRunning = Mutex.TryOpenExisting(serverMutexName, out mutexIgnore); var timeout = wasServerRunning ? TimeOutMsExistingProcess : TimeOutMsNewProcess; NamedPipeClientStream pipe = null; if (wasServerRunning || tryCreateServerFunc(clientDir, pipeName)) { pipe = TryConnectToServer(pipeName, timeout, cancellationToken); } if (pipe != null) { var request = BuildRequest.Create(language, buildPaths.WorkingDirectory, arguments, keepAlive, libEnvVariable); return(TryCompile(pipe, request, cancellationToken)); } } finally { if (holdsMutex) { clientMutex.ReleaseMutex(); } } } return(null); }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List <string> parsedArgs; if (!ReflCommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { Console.Out.WriteLine(errorMessage); return(RunCompilationResult.Failed); } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return(new RunCompilationResult(exitCode)); }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); bool hasShared; string keepAlive; string errorMessage; string sessionKey; List <string> parsedArgs; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAlive, out sessionKey, out errorMessage)) { textWriter.WriteLine(errorMessage); return(RunCompilationResult.Failed); } if (hasShared) { sessionKey = sessionKey ?? GetSessionKey(buildPaths); var libDirectory = Environment.GetEnvironmentVariable("LIB"); var serverResult = RunServerCompilation(textWriter, parsedArgs, buildPaths, libDirectory, sessionKey, keepAlive); if (serverResult.HasValue) { Debug.Assert(serverResult.Value.RanOnServer); return(serverResult.Value); } } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return(new RunCompilationResult(exitCode)); }
protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter) { return(_compileFunc(arguments, buildPaths, textWriter, CoreClrAnalyzerAssemblyLoader.CreateAndSetDefault())); }
private static Task<BuildResponse> RunServerCompilationCore( RequestLanguage language, List<string> arguments, BuildPaths buildPaths, string pipeName, string keepAlive, string libEnvVariable, int? timeoutOverride, Func<string, string, bool> tryCreateServerFunc, CancellationToken cancellationToken) { var clientDir = buildPaths.ClientDirectory; var timeoutNewProcess = timeoutOverride ?? TimeOutMsNewProcess; var timeoutExistingProcess = timeoutOverride ?? TimeOutMsExistingProcess; var clientMutexName = GetClientMutexName(pipeName); bool holdsMutex; using (var clientMutex = new Mutex(initiallyOwned: true, name: clientMutexName, createdNew: out holdsMutex)) { try { if (!holdsMutex) { try { holdsMutex = clientMutex.WaitOne(timeoutNewProcess); if (!holdsMutex) { return Task.FromResult<BuildResponse>(new RejectedBuildResponse()); } } catch (AbandonedMutexException) { holdsMutex = true; } } // Check for an already running server var serverMutexName = GetServerMutexName(pipeName); bool wasServerRunning = WasServerMutexOpen(serverMutexName); var timeout = wasServerRunning ? timeoutExistingProcess : timeoutNewProcess; NamedPipeClientStream pipe = null; if (wasServerRunning || tryCreateServerFunc(clientDir, pipeName)) { pipe = TryConnectToServer(pipeName, timeout, cancellationToken); } if (pipe != null) { var request = BuildRequest.Create(language, buildPaths.WorkingDirectory, arguments, keepAlive, libEnvVariable); return TryCompile(pipe, request, cancellationToken); } } finally { if (holdsMutex) { clientMutex.ReleaseMutex(); } } } return Task.FromResult<BuildResponse>(new RejectedBuildResponse()); }
/// <summary> /// Given the full path to the directory containing the compiler exes, /// retrieves the name of the pipe for client/server communication on /// that instance of the compiler. /// </summary> protected override string GetSessionKey(BuildPaths buildPaths) { return(GetPipeNameFromFileInfo(buildPaths.ClientDirectory)); }
protected override string GetSessionKey(BuildPaths buildPaths) { return(string.Empty); }
/// <summary> /// Given the full path to the directory containing the compiler exes, /// retrieves the name of the pipe for client/server communication on /// that instance of the compiler. /// </summary> protected override string GetSessionKey(BuildPaths buildPaths) { return GetPipeNameForPath(buildPaths.ClientDirectory); }
public ServerTests() { _tempDirectory = Temp.CreateDirectory(); _buildPaths = ServerUtil.CreateBuildPaths(workingDir: _tempDirectory.Path); }
protected abstract string GetSessionKey(BuildPaths buildPaths);
private async Task RunCompilationAsync(RequestLanguage language, string pipeName, int i) { var compilationDir = Temp.CreateDirectory(); TempFile sourceFile; string exeFileName; string prefix; string sourceText; if (language == RequestLanguage.CSharpCompile) { exeFileName = $"hellocs{i}.exe"; prefix = "CS"; sourceFile = compilationDir.CreateFile($"hello{i}.cs"); sourceText = $@"using System; class Hello {{ public static void Main() {{ Console.WriteLine(""CS Hello number {i}""); }} }}"; } else { exeFileName = $"hellovb{i}.exe"; prefix = "VB"; sourceFile = compilationDir.CreateFile($"hello{i}.vb"); sourceText = $@"Imports System Module Hello Sub Main() Console.WriteLine(""VB Hello number {i}"") End Sub End Module"; } await sourceFile.WriteAllTextAsync(sourceText); // Create a client to run the build. Infinite timeout is used to account for the // case where these tests are run under extreme load. In high load scenarios the // client will correctly drop down to a local compilation if the server doesn't respond // fast enough. var client = ServerUtil.CreateBuildClient(language); client.TimeoutOverride = Timeout.Infinite; // Compile the code. Use var buildPaths = new BuildPaths( clientDir: CompilerDirectory, workingDir: compilationDir.Path, sdkDir: RuntimeEnvironment.GetRuntimeDirectory()); var result = await client.RunCompilationAsync(new[] { $"/shared:{pipeName}", "/nologo", Path.GetFileName(sourceFile.Path), $"/out:{exeFileName}" }, buildPaths); Assert.Equal(0, result.ExitCode); Assert.True(result.RanOnServer); // Run the EXE and verify it prints the desired output. var exeFile = Temp.AddFile(GetResultFile(compilationDir, exeFileName)); var exeResult = RunCompilerOutput(exeFile); Assert.Equal($"{prefix} Hello number {i}\r\n", exeResult.Output); }
internal Csc(string responseFile, BuildPaths buildPaths, string[] args, IAnalyzerAssemblyLoader analyzerLoader) : base(CSharpCommandLineParser.Default, responseFile, args, buildPaths.ClientDirectory, buildPaths.WorkingDirectory, buildPaths.SdkDirectory, Environment.GetEnvironmentVariable("LIB"), analyzerLoader) { }
protected abstract int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter);
/// <summary> /// Given the full path to the directory containing the compiler exes, /// retrieves the name of the pipe for client/server communication on /// that instance of the compiler. /// </summary> protected override string GetSessionKey(BuildPaths buildPaths) { return(BuildServerConnection.GetPipeNameForPathOpt(buildPaths.ClientDirectory)); }
/// <summary> /// Runs the provided compilation on the server. If the compilation cannot be completed on the server then null /// will be returned. /// </summary> internal RunCompilationResult?RunServerCompilation(TextWriter textWriter, List <string> arguments, BuildPaths buildPaths, string libDirectory, string sessionName, string keepAlive) { BuildResponse buildResponse; try { var buildResponseTask = RunServerCompilation( arguments, buildPaths, sessionName, keepAlive, libDirectory, CancellationToken.None); buildResponse = buildResponseTask.Result; Debug.Assert(buildResponse != null); if (buildResponse == null) { return(null); } } catch (Exception) { return(null); } switch (buildResponse.Type) { case BuildResponse.ResponseType.Completed: { var completedResponse = (CompletedBuildResponse)buildResponse; return(ConsoleUtil.RunWithUtf8Output(completedResponse.Utf8Output, textWriter, tw => { tw.Write(completedResponse.Output); return new RunCompilationResult(completedResponse.ReturnCode, ranOnServer: true); })); } case BuildResponse.ResponseType.MismatchedVersion: case BuildResponse.ResponseType.Rejected: case BuildResponse.ResponseType.AnalyzerInconsistency: // Build could not be completed on the server. return(null); default: // Will not happen with our server but hypothetically could be sent by a rogue server. Should // not let that block compilation. Debug.Assert(false); return(null); } }
protected override string GetSessionKey(BuildPaths buildPaths) { return string.Empty; }
public Task <RunCompilationResult> RunCompilationAsync(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { var tcs = new TaskCompletionSource <RunCompilationResult>(); ThreadStart action = () => { try { var result = RunCompilation(originalArguments, buildPaths, textWriter); tcs.SetResult(result); } catch (Exception ex) { tcs.SetException(ex); } }; var thread = new Thread(action); thread.Start(); return(tcs.Task); }
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; } if (!UseSharedCompilation || !string.IsNullOrEmpty(ToolPath)) { return base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); } using (_sharedCompileCts = new CancellationTokenSource()) { try { CompilerServerLogger.Log($"CommandLine = '{commandLineCommands}'"); CompilerServerLogger.Log($"BuildResponseFile = '{responseFileCommands}'"); // Try to get the location of the user-provided build client and server, // which should be located next to the build task. If not, fall back to // "pathToTool", which is the compiler in the MSBuild default bin directory. var clientDir = TryGetClientDir() ?? Path.GetDirectoryName(pathToTool); pathToTool = Path.Combine(clientDir, ToolExe); // 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 BuildPaths( clientDir: clientDir, // MSBuild doesn't need the .NET SDK directory sdkDir: null, workingDir: CurrentDirectoryToUse()); var responseTask = BuildClientShim.RunServerCompilation( Language, GetArguments(commandLineCommands, responseFileCommands).ToList(), buildPaths, keepAlive: null, libEnvVariable: LibDirectoryToUse(), cancellationToken: _sharedCompileCts.Token); responseTask.Wait(_sharedCompileCts.Token); var response = responseTask.Result; if (response != null) { ExitCode = HandleResponse(response, pathToTool, responseFileCommands, commandLineCommands); } else { Log.LogMessage(ErrorString.SharedCompilationFallback, pathToTool); ExitCode = base.ExecuteTool(pathToTool, responseFileCommands, commandLineCommands); } } catch (OperationCanceledException) { ExitCode = 0; } catch (Exception e) { Log.LogErrorWithCodeFromResources("Compiler_UnexpectedException"); LogErrorOutput(e.ToString()); ExitCode = -1; } } return ExitCode; }
protected override string GetSessionKey(BuildPaths buildPaths) { return _pipeName; }
protected override int HandleResponse(BuildResponse response, List<string> arguments, BuildPaths buildPaths) { // Override the base so we don't print the compilation output to Console.Out return 0; }
/// <summary> /// Run a compilation through the compiler server and print the output /// to the console. If the compiler server fails, run the fallback /// compiler. /// </summary> internal RunCompilationResult RunCompilation(IEnumerable <string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { textWriter = textWriter ?? Console.Out; var args = originalArguments.Select(arg => arg.Trim()).ToArray(); List <string> parsedArgs; bool hasShared; string keepAliveOpt; string sessionKeyOpt; string errorMessageOpt; if (!CommandLineParser.TryParseClientArgs( args, out parsedArgs, out hasShared, out keepAliveOpt, out sessionKeyOpt, out errorMessageOpt)) { textWriter.WriteLine(errorMessageOpt); return(RunCompilationResult.Failed); } if (hasShared) { sessionKeyOpt = sessionKeyOpt ?? GetSessionKey(buildPaths); var libDirectory = Environment.GetEnvironmentVariable("LIB"); #if XSHARP var paths = LanguageService.CodeAnalysis.CSharp.CommandLine.Xsc.GetPaths(); if (libDirectory == null) { libDirectory = string.Empty; } libDirectory = libDirectory + ":::" + paths[0] + ":::" + paths[1] + ":::" + paths[2]; #endif var serverResult = RunServerCompilation(textWriter, parsedArgs, buildPaths, libDirectory, sessionKeyOpt, keepAliveOpt); if (serverResult.HasValue) { Debug.Assert(serverResult.Value.RanOnServer); return(serverResult.Value); } } // It's okay, and expected, for the server compilation to fail. In that case just fall // back to normal compilation. var exitCode = RunLocalCompilation(parsedArgs.ToArray(), buildPaths, textWriter); return(new RunCompilationResult(exitCode)); }
protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter) { return(_compileFunc(arguments, buildPaths, textWriter, _analyzerAssemblyLoader)); }
public ServerTests() { _buildPaths = ServerUtil.CreateBuildPaths( workingDir: Temp.CreateDirectory().Path, tempDir: Temp.CreateDirectory().Path); }
protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter) { return _compileFunc(arguments, buildPaths, textWriter, new CoreClrAnalyzerAssemblyLoader()); }
public Task<RunCompilationResult> RunCompilationAsync(IEnumerable<string> originalArguments, BuildPaths buildPaths, TextWriter textWriter = null) { var tcs = new TaskCompletionSource<RunCompilationResult>(); ThreadStart action = () => { try { var result = RunCompilation(originalArguments, buildPaths, textWriter); tcs.SetResult(result); } catch (Exception ex) { tcs.SetException(ex); } }; var thread = new Thread(action); thread.Start(); return tcs.Task; }