コード例 #1
0
        /// <summary>
        /// Compiles the fragment and adds the compile time to the list
        /// </summary>
        public void Compile(DirectoryReference IntermediateDir, int SampleIdx)
        {
            FileReference LogFile = FileReference.Combine(IntermediateDir, String.Format("{0}.sample{1}.txt", UniqueName, SampleIdx + 1));

            using (StreamWriter LogWriter = new StreamWriter(LogFile.FullName, true))
            {
                FileReference ResponseFile = FileReference.Combine(IntermediateDir, String.Format("{0}.sample{1}.response", UniqueName, SampleIdx + 1));

                // Write the response file
                CompileEnvironment WorkerCompileEnvironment = new CompileEnvironment(CompileEnvironment);
                if (WorkerCompileEnvironment.CompilerType == CompilerType.Clang)
                {
                    WorkerCompileEnvironment.Options.Add(new CompileOption("-o", FileReference.Combine(IntermediateDir, UniqueName + ".o").FullName));
                }
                else if (WorkerCompileEnvironment.CompilerType == CompilerType.VisualC)
                {
                    WorkerCompileEnvironment.Options.RemoveAll(x => x.Name == "/Z7" || x.Name == "/Zi" || x.Name == "/ZI");
                    WorkerCompileEnvironment.Options.Add(new CompileOption("/Fo", IntermediateFile.FullName + ".obj"));
                    WorkerCompileEnvironment.Options.Add(new CompileOption("/WX", null));
                    WorkerCompileEnvironment.Options.Add(new CompileOption("/Bt", null));
                }
                else
                {
                    throw new NotImplementedException();
                }
                WorkerCompileEnvironment.WriteResponseFile(ResponseFile, IntermediateFile);

                // Spawn the compiler
                using (Process NewProcess = new Process())
                {
                    List <string>            LogLines      = new List <string>();
                    DataReceivedEventHandler OutputHandler = (x, y) => { if (!String.IsNullOrEmpty(y.Data))
                                                                         {
                                                                             LogWriter.WriteLine(y.Data); LogLines.Add(y.Data);
                                                                         }
                    };

                    NewProcess.StartInfo.FileName               = CompileEnvironment.Compiler.FullName;
                    NewProcess.StartInfo.Arguments              = String.Format("\"@{0}\"", ResponseFile);
                    NewProcess.StartInfo.UseShellExecute        = false;
                    NewProcess.StartInfo.RedirectStandardOutput = true;
                    NewProcess.StartInfo.RedirectStandardError  = true;
                    NewProcess.OutputDataReceived              += OutputHandler;
                    NewProcess.ErrorDataReceived += OutputHandler;

                    Stopwatch Timer = Stopwatch.StartNew();
                    NewProcess.Start();
                    NewProcess.BeginOutputReadLine();
                    NewProcess.BeginErrorReadLine();

                    if (NewProcess.WaitForExit(10 * 60 * 1000))
                    {
                        // WaitForExit with a timeout does not wait for output data to be flushed, so issue a normal WaitForExit call here too
                        NewProcess.WaitForExit();
                        Timer.Stop();

                        FragmentTimingSample Sample = new FragmentTimingSample();
                        Sample.TotalTime = Timer.Elapsed.TotalSeconds;
                        if (WorkerCompileEnvironment.CompilerType == CompilerType.VisualC)
                        {
                            foreach (string LogLine in LogLines)
                            {
                                if (TryParseCompileTime(LogLine, "c1xx.dll", out Sample.FrontendTime))
                                {
                                    break;
                                }
                            }
                            foreach (string LogLine in LogLines)
                            {
                                if (TryParseCompileTime(LogLine, "c2.dll", out Sample.BackendTime))
                                {
                                    break;
                                }
                            }
                        }
                        Samples.Add(Sample);

                        LogWriter.WriteLine("Compile finished in {0}s", Timer.Elapsed.TotalSeconds);
                    }
                    else
                    {
                        NewProcess.Kill();
                        NewProcess.WaitForExit();
                        Timer.Stop();
                        Samples.Add(new FragmentTimingSample());
                        LogWriter.WriteLine("Timeout; terminating process after {0}s", Timer.Elapsed.TotalSeconds);
                    }

                    LogWriter.WriteLine();
                }
            }
        }