예제 #1
0
 public static Task<BuildResponse> RunServerCompilation(
     RequestLanguage language,
     List<string> arguments,
     BuildPaths buildPaths,
     string keepAlive,
     string libEnvVariable,
     CancellationToken cancellationToken) => Task.FromResult<BuildResponse>(null);
예제 #2
0
 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;
     }
 }
예제 #3
0
파일: Csc.cs 프로젝트: Rickinio/roslyn
        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));
        }
예제 #4
0
            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);
            }
예제 #5
0
        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);
        }
예제 #6
0
 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;
 }
예제 #7
0
 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);
 }
예제 #8
0
 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);
 }
예제 #9
0
 public static Task<BuildResponse> RunServerCompilation(
     RequestLanguage language,
     List<string> arguments,
     BuildPaths buildPaths,
     string keepAlive,
     string libEnvVariable,
     CancellationToken cancellationToken)
 {
     throw new NotSupportedException();
 }
예제 #10
0
 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);
 }
예제 #11
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();

            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);
        }
예제 #12
0
 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;
 }
예제 #13
0
 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);
예제 #14
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 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);
        }
예제 #15
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 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));
        }
예제 #16
0
 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));
 }
예제 #17
0
        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);
        }
예제 #18
0
 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);
 }
예제 #19
0
 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);
 }
예제 #20
0
 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));
 }
예제 #21
0
        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);
        }
예제 #22
0
        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);
        }
예제 #23
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();

            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);
        }
예제 #24
0
 public DesktopBuildClientTests()
 {
     _tempDirectory = Temp.CreateDirectory();
     _buildPaths = new BuildPaths(_serverInfo.ClientDirectory, _tempDirectory.Path, _serverInfo.SdkDirectory);
 }
예제 #25
0
        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");
            }
        }
예제 #26
0
        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);
        }
예제 #27
0
        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;
            }
예제 #28
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();

            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));
        }
예제 #29
0
        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");
            }
        }
예제 #30
0
 protected abstract Task <BuildResponse> RunServerCompilation(List <string> arguments, BuildPaths buildPaths, string sessionName, string keepAlive, string libDirectory, CancellationToken cancellationToken);
예제 #31
0
        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);
        }
예제 #32
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();

            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));
        }
예제 #33
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();

            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));
        }
예제 #34
0
 protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter)
 {
     return(_compileFunc(arguments, buildPaths, textWriter, CoreClrAnalyzerAssemblyLoader.CreateAndSetDefault()));
 }
예제 #35
0
        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());
        }
예제 #36
0
 /// <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));
 }
예제 #37
0
 protected override string GetSessionKey(BuildPaths buildPaths)
 {
     return(string.Empty);
 }
예제 #38
0
 /// <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);
 }
예제 #39
0
 public ServerTests()
 {
     _tempDirectory = Temp.CreateDirectory();
     _buildPaths = ServerUtil.CreateBuildPaths(workingDir: _tempDirectory.Path);
 }
예제 #40
0
 protected abstract string GetSessionKey(BuildPaths buildPaths);
예제 #41
0
        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);
        }
예제 #42
0
파일: Csc.cs 프로젝트: Rickinio/roslyn
 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)
 {
 }
예제 #43
0
 protected abstract int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter);
예제 #44
0
 /// <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));
 }
예제 #45
0
        /// <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);
            }
        }
예제 #46
0
 protected override string GetSessionKey(BuildPaths buildPaths)
 {
     return string.Empty;
 }
예제 #47
0
        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);
        }
예제 #48
0
        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;
        }
예제 #49
0
 protected override string GetSessionKey(BuildPaths buildPaths)
 {
     return _pipeName;
 }
예제 #50
0
 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;
 }
예제 #51
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));
        }
예제 #52
0
 protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter)
 {
     return(_compileFunc(arguments, buildPaths, textWriter, _analyzerAssemblyLoader));
 }
예제 #53
0
 public ServerTests()
 {
     _buildPaths = ServerUtil.CreateBuildPaths(
         workingDir: Temp.CreateDirectory().Path,
         tempDir: Temp.CreateDirectory().Path);
 }
예제 #54
0
 protected override int RunLocalCompilation(string[] arguments, BuildPaths buildPaths, TextWriter textWriter)
 {
     return _compileFunc(arguments, buildPaths, textWriter, new CoreClrAnalyzerAssemblyLoader());
 }
예제 #55
0
        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;
        }