singrdk/base/Windows/BuildAll/BuildAll.cs

246 lines
8.2 KiB
C#

// ----------------------------------------------------------------------------
//
// 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;
}
}
}