CClash.Compiler.InvokeCompiler C# (CSharp) Method

InvokeCompiler() public method

public InvokeCompiler ( IEnumerable args, Action onStdErr, Action onStdOut, bool showIncludes, List foundIncludes ) : int
args IEnumerable
onStdErr Action
onStdOut Action
showIncludes bool
foundIncludes List
return int
        public int InvokeCompiler(IEnumerable<string> args, Action<string> onStdErr, Action<string> onStdOut, bool showIncludes, List<string> foundIncludes)
        {
            int rv = -1;
            bool retry;
            do
            {
                retry = false;
                Logging.Emit("invoking real compiler: {0} {1} [{2}]", CompilerExe, WorkingDirectory, string.Join(" ", args.ToArray()));

                if (string.IsNullOrWhiteSpace(CompilerExe) || !FileUtils.Exists(CompilerExe))
                    throw new FileNotFoundException("cant find cl.exe");

                if (string.IsNullOrWhiteSpace(compworkdir))
                    throw new InvalidOperationException("no working directory set");

                if (compenvs == null || compenvs.Count == 0)
                    throw new InvalidOperationException("no environment set");

                var cla = JoinAguments(FixupArgs(args));
                if (showIncludes) cla += " /showIncludes";
                var psi = new ProcessStartInfo(CompilerExe, cla)
                {
                    UseShellExecute = false,
                    RedirectStandardError = true,
                    RedirectStandardOutput = true,
                    WorkingDirectory = compworkdir,
                };

                psi.EnvironmentVariables.Clear();
                foreach (var row in compenvs)
                {
                    psi.EnvironmentVariables[row.Key] = row.Value;
                }
                psi.EnvironmentVariables["PATH"] = Path.GetDirectoryName(CompilerExe) + ";" + psi.EnvironmentVariables["PATH"];
                psi.ErrorDialog = true;
                var p = Process.Start(psi);

                p.OutputDataReceived += (o, a) =>
                {
                    if (a.Data != null)
                    {

                        if (showIncludes && a.Data.StartsWith("Note: including file:"))
                        {
                            var inc = a.Data.Substring("Note: including file:".Length + 1).TrimStart(' ');
                            if (inc.Contains('/'))
                            {
                                inc = inc.Replace('/', '\\');
                            }
                            foundIncludes.Add(inc);
                        }
                        else
                        {
                            if (StdOutputCallback != null) {
                                StdOutputCallback(a.Data + Environment.NewLine);
                            }
                            if (onStdOut != null) {
                                onStdOut(a.Data + Environment.NewLine);
                            }
                            //if (Settings.DebugEnabled)
                            //    Logging.Emit("stdout {0}", a.Data);
                        }
                    }

                };

                p.ErrorDataReceived += (o, a) =>
                {
                    if (a.Data != null)
                    {
                        if (StdErrorCallback != null) {
                            StdErrorCallback(a.Data + Environment.NewLine);
                        }
                        if (onStdErr != null) {
                            onStdErr(a.Data + Environment.NewLine);
                        }
                        if (Settings.DebugEnabled)
                            Logging.Emit("stderr {0}", a.Data);
                    }
                };

                p.BeginErrorReadLine();
                p.BeginOutputReadLine();

                p.WaitForExit();


                rv = p.ExitCode;
                p.Close();
                Logging.Emit("cl exit {0}", rv);
                if (rv == 0)
                {
                    if (IsSupported)
                    {
                        if (!string.IsNullOrEmpty(ObjectTarget))
                        {
                            var sw = new Stopwatch();
                            sw.Start();
                            int waited = 0;

                            while (!File.Exists(ObjectTarget) && (sw.ElapsedMilliseconds < 100000))
                            {
                                Logging.Emit("compiler slow to write object! {0} {1}ms", ObjectTarget, (int)sw.Elapsed.TotalMilliseconds);
                                waited++;
                                System.Threading.Thread.Sleep(Math.Min(1000, 100 * waited));
                            }

                            if (!File.Exists(ObjectTarget))
                            {
                                string logmsg = string.Format("cl exited with zero but failed to create the object file! {0}", ObjectTarget);
                                // let the retry system have a go with this

                                Logging.Warning("{0}, re-running!", logmsg);
                                retry = true;
                            }
                            Logging.Emit("output: {0} seen", ObjectTarget);
                        }
                    }
                }

                if (rv != 0)
                {
                    Logging.Emit("non-zero exit");
                }
            } while (retry);
            return rv;
        }

Usage Example

Beispiel #1
0
        private static int RunBuild(string[] args, DateTime start, Action <string> stdout, Action <string> stderr)
        {
            Logging.Emit("client mode = {0}", Settings.ServiceMode);
            try
            {
                if (!Settings.Disabled)
                {
                    string compiler = Compiler.Find();
                    if (compiler == null)
                    {
                        throw new System.IO.FileNotFoundException("cant find real cl compiler");
                    }

                    var cachedir = Settings.CacheDirectory;
                    Logging.Emit("compiler: {0}", compiler);
                    ICompiler comp;
                    using (ICompilerCache cc =
                               CompilerCacheFactory.Get(Settings.DirectMode, cachedir, compiler, Environment.CurrentDirectory, Compiler.GetEnvironmentDictionary(), out comp))
                    {
                        if (comp != null)
                        {
                            spawnServer = true;
                        }
                        cc.SetCaptureCallback(comp, stdout, stderr);
                        long last_hits = 0;
                        if (!Settings.ServiceMode)
                        {
                            last_hits = cc.Stats.CacheHits;
                        }

                        int res = cc.CompileOrCache(comp, args, null);

                        if (!Settings.ServiceMode)
                        {
                            if (last_hits < cc.Stats.CacheHits)
                            {
                                WasHit = true;
                            }
                        }

                        return(res);
                    }
                }
                else
                {
                    Logging.Emit("disabled by environment");
                }
            }
            catch (CClashWarningException e)
            {
                Logging.Warning(e.Message);
            }
            catch (Exception e)
            {
                Logging.Emit("{0} after {1} ms", e.GetType().Name, DateTime.Now.Subtract(start).TotalMilliseconds);
                Logging.Emit("{0} {1}", e.GetType().Name + " message: " + e.Message);
#if DEBUG
                Logging.Error("Exception from cacher {0}!!!", e);
#endif
            }

            int rv = -1;

            try
            {
                var c = new Compiler()
                {
                    CompilerExe = Compiler.Find(),
                };
                c.SetEnvironment(Compiler.GetEnvironmentDictionary());
                c.SetWorkingDirectory(Environment.CurrentDirectory);
                rv = c.InvokeCompiler(args, stderr, stdout, false, null);
                Logging.Emit("exit {0} after {1} ms", rv, DateTime.Now.Subtract(start).TotalMilliseconds);
            }
            catch (CClashErrorException e)
            {
                Logging.Error(e.Message);
                throw;
            }
            catch (CClashWarningException e)
            {
                Logging.Warning(e.Message);
            }
            return(rv);
        }
All Usage Examples Of CClash.Compiler::InvokeCompiler