// ---------------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // ---------------------------------------------------------------------------- // This program builds all permutations of build variables. using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Diagnostics; namespace BuildAll { class BuildVariable { public readonly string PropertyName; public readonly string[] Values; public BuildVariable(string propname, string[] values) { this.PropertyName = propname; this.Values = values; } } static class BuildAll { static string ProjectPath; static string MSBuildPath; static readonly BuildVariable[] Variables = { new BuildVariable("Configuration", new string[] { "Prototype", "Debug", "Release" }), new BuildVariable("Platform", new string[] { "ApicPC", "ApicMP", "Apic64" }), new BuildVariable("Paging", new string[] { "On", "Off" }), new BuildVariable("COLLECTOR_APP", new string[] { "MarkSweep", "Concurrent" }), new BuildVariable("COLLECTOR_KERNEL", new string[] { "MarkSweep", "Concurrent" }), }; static void AppendWithPadding(StringBuilder buffer, string value, int total_width) { buffer.Append(value); int padding = total_width - value.Length; if (padding > 0) buffer.Append(' ', padding); } static int Main(string[] args) { ProjectPath = "Distro\\Tiny.proj"; if (String.IsNullOrEmpty(Environment.GetEnvironmentVariable("SINGULARITY_ROOT"))) { Console.Error.WriteLine("Error: The environment variable 'SINGULARITY_ROOT' must be defined, but is not."); return 1; } MSBuildPath = Environment.ExpandEnvironmentVariables(@"%SystemRoot%\Microsoft.Net\Framework\v2.0.50727\msbuild.exe"); if (!File.Exists(MSBuildPath)) { Console.WriteLine("ERROR: Could not find MSBuild.exe"); return -1; } int var_count = Variables.Length; // 'indexes' is an array of cycle counters, for each variable that we vary over. // index of each array slot is an index into Variables array // value of each array slot is an index into Variables[i].PropertyValues int[] indexes = new int[var_count]; for (int i = 0; i < indexes.Length; i++) indexes[i] = 0; // redundant, of course, but i'm being explicit int total_combinations = 1; for (int i = 0; i < Variables.Length; i++) total_combinations *= Variables[i].Values.Length; Console.WriteLine("Total combinations: " + total_combinations); Console.WriteLine("Project: " + ProjectPath); int[] column_widths = new int[var_count]; for (int i = 0; i < indexes.Length; i++) { column_widths[i] = Variables[i].PropertyName.Length; string[] values = Variables[i].Values; for (int j = 0; j < values.Length; j++) if (column_widths[i] < values[j].Length) column_widths[i] = values[j].Length; } StringBuilder line = new StringBuilder(); // Write table header Console.WriteLine(); line.Length = 0; for (int i = 0; i < indexes.Length; i++) { AppendWithPadding(line, Variables[i].PropertyName, column_widths[i]); line.Append(' '); } Console.WriteLine(line.ToString()); line.Length = 0; for (int i = 0; i < indexes.Length; i++) { line.Append('-', column_widths[i]); line.Append(' '); } Console.WriteLine(line.ToString()); string[] names = new string[Variables.Length]; for (int i = 0; i < Variables.Length; i++) { names[i] = Variables[i].PropertyName; } for (;;) { bool done; for (int i = 0;; i++) { if (i == Variables.Length) { done = true; break; } if (indexes[i] < Variables[i].Values.Length) { done = false; break; } } if (done) { Console.WriteLine("All variations have been tried."); break; } line.Length = 0; for (int i = 0; i < var_count; i++) { AppendWithPadding(line, Variables[i].Values[indexes[i]], column_widths[i]); line.Append(' '); } line.Append(" running..."); Console.Write(line.ToString()); string[] values = new string[Variables.Length]; for (int i = 0; i < Variables.Length; i++) { values[i] = Variables[i].Values[indexes[i]]; } bool succeeded; TimeSpan time_elapsed; RunCombination(names, values, out succeeded, out time_elapsed); if (succeeded) { Console.WriteLine(" succeeded [{0}]", time_elapsed); } else { Console.WriteLine(" FAILED [{0}]", time_elapsed); } // increment indexes, with carry done = false; for (int i = 0;; i++) { if (i == Variables.Length) { // totally done done = true; break; } indexes[i]++; if (indexes[i] >= Variables[i].Values.Length) { indexes[i] = 0; // implicitly carry if (i == Variables.Length) { // totally done done = true; break; } continue; } else { break; } } if (done) break; } Console.WriteLine("done."); return 0; } static void RunCombination(string[] names, string[] values, out bool succeeded, out TimeSpan elapsed) { StringBuilder buffer = new StringBuilder(); buffer.Append("/nologo"); for (int i = 0; i < names.Length; i++) { buffer.Append(" /p:"); buffer.Append(names[i]); buffer.Append("="); buffer.Append(values[i]); } string log_filename = "msbuild." + String.Join(".", values) + ".log"; buffer.Append(" /noconsolelogger"); buffer.Append(" /logger:Microsoft.Build.BuildEngine.FileLogger,Microsoft.Build.Engine;PerformanceSummary;logfile=" + log_filename); string cmd = buffer.ToString(); buffer.Append(" Distro\\Small.proj"); Debug.WriteLine(cmd); ProcessStartInfo info = new ProcessStartInfo(); info.Arguments = buffer.ToString(); info.FileName = MSBuildPath; info.UseShellExecute = false; DateTime time_start = DateTime.Now; using (Process p = Process.Start(info)) { p.WaitForExit(); succeeded = (p.ExitCode == 0); } DateTime time_end = DateTime.Now; elapsed = time_end - time_start; } } }