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); }
int RealInvokeCompiler(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 = ArgumentUtils.JoinAguments(ArgumentUtils.FixupArgs(args)); var runExe = compilerExe; if (showIncludes) { foundIncludes.Add(SingleSourceFile); if (TrackerEnabled) { runExe = "tracker.exe"; var trackerargs = new List <string> { "/if", Path.Combine(WorkingDirectory, TrackerFolder), "/k", "/t" }; var tcla = ArgumentUtils.JoinAguments(trackerargs); cla = String.Format("{0} /c \"{1}\" {2}", tcla, compilerExe, cla); } else { cla += " /showIncludes"; } } var psi = new ProcessStartInfo(runExe, 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(); while (!File.Exists(ObjectTarget) && (sw.ElapsedMilliseconds < WaitForSlowObject)) { System.Threading.Thread.Sleep(500); } sw.Stop(); if (!File.Exists(ObjectTarget)) { retry = true; if (sw.ElapsedMilliseconds > 2000) { Logging.Emit("compiler didn't write expected object! {0} after {1}ms", ObjectTarget, (int)sw.Elapsed.TotalMilliseconds); retry = false; } string logmsg = string.Format("cl exited with zero but failed to create the expected object file! {0}", ObjectTarget); // let the retry system have a go with this if (retry) { Logging.Warning("{0}, re-running!", logmsg); } } else { Logging.Emit("output: {0} seen", ObjectTarget); } } } } if (rv != 0) { Logging.Emit("non-zero exit"); } } while (retry); return(rv); }