196 lines
6.0 KiB
C#
196 lines
6.0 KiB
C#
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
//
|
||
|
// Microsoft Research Singularity
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
//
|
||
|
///////////////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Diagnostics;
|
||
|
using System.IO;
|
||
|
using System.Text;
|
||
|
|
||
|
class NMakeDirs
|
||
|
{
|
||
|
const string NMakeProgram = "nmake.exe";
|
||
|
const string RunParallelProgram = "runparallel.exe";
|
||
|
const string DrainMarker = "+DRAIN";
|
||
|
|
||
|
static int Main(string[] args)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
ArrayList dirs = new ArrayList();
|
||
|
int dir_count = 0; // this count excludes drain markers
|
||
|
|
||
|
bool parallel = false;
|
||
|
|
||
|
string nmake_args = "/nologo ";
|
||
|
|
||
|
for (int i = 0; i < args.Length; i++)
|
||
|
{
|
||
|
string arg = args[i];
|
||
|
|
||
|
if (arg.Length == 0)
|
||
|
continue;
|
||
|
|
||
|
if (arg.StartsWith("/"))
|
||
|
{
|
||
|
arg = arg.ToLower();
|
||
|
if (arg == "/nmake")
|
||
|
{
|
||
|
// The rest of the arguments are for NMAKE.
|
||
|
i++;
|
||
|
nmake_args = nmake_args + String.Join(" ", args, i, args.Length - i);
|
||
|
break;
|
||
|
}
|
||
|
else if (arg == "/p")
|
||
|
{
|
||
|
parallel = true;
|
||
|
}
|
||
|
else if (arg == "/?")
|
||
|
{
|
||
|
Usage();
|
||
|
return 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteLine("WARNING: Unrecognized switch: " + arg);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
dirs.Add(arg);
|
||
|
if (String.Compare(arg, DrainMarker, true) != 0)
|
||
|
dir_count++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (dir_count == 0)
|
||
|
{
|
||
|
Usage();
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
if (parallel)
|
||
|
{
|
||
|
WriteLine("Building {0} dirs in parallel.", dir_count);
|
||
|
|
||
|
using (Process process = new Process())
|
||
|
{
|
||
|
process.StartInfo.UseShellExecute = false;
|
||
|
process.StartInfo.RedirectStandardInput = true;
|
||
|
process.StartInfo.FileName = RunParallelProgram;
|
||
|
process.StartInfo.Arguments = "/stdin";
|
||
|
|
||
|
process.Start();
|
||
|
|
||
|
TextWriter pipe = process.StandardInput;
|
||
|
|
||
|
foreach (string dir in dirs)
|
||
|
{
|
||
|
if (String.Compare(dir, DrainMarker, true) == 0)
|
||
|
{
|
||
|
pipe.WriteLine(dir);
|
||
|
continue;
|
||
|
}
|
||
|
string line = String.Format("cd \"{0}\" && " + NMakeProgram + " {1}", dir, nmake_args);
|
||
|
// WriteLine(" cmd - " + line);
|
||
|
pipe.WriteLine(line);
|
||
|
}
|
||
|
|
||
|
pipe.Close();
|
||
|
|
||
|
process.WaitForExit();
|
||
|
|
||
|
if (process.ExitCode != 0)
|
||
|
{
|
||
|
WriteLine("RUNPARALLEL failed: " + process.ExitCode);
|
||
|
return process.ExitCode;
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
WriteLine("Building {0} dirs serially.", dir_count);
|
||
|
|
||
|
string initial_directory = Environment.CurrentDirectory;
|
||
|
|
||
|
foreach (string dir in dirs)
|
||
|
{
|
||
|
if (String.Compare(dir, DrainMarker, true) == 0)
|
||
|
continue;
|
||
|
|
||
|
string path = Path.Combine(initial_directory, dir);
|
||
|
WriteLine("building dir - " + path);
|
||
|
|
||
|
using (Process process = new Process())
|
||
|
{
|
||
|
process.StartInfo.UseShellExecute = false;
|
||
|
process.StartInfo.FileName = NMakeProgram;
|
||
|
process.StartInfo.Arguments = nmake_args;
|
||
|
process.StartInfo.WorkingDirectory = dir;
|
||
|
|
||
|
process.Start();
|
||
|
process.WaitForExit();
|
||
|
|
||
|
if (process.ExitCode != 0)
|
||
|
{
|
||
|
WriteLine("[{0} NMAKE failed: {1}", dir, process.ExitCode);
|
||
|
return process.ExitCode;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
catch (Exception ex)
|
||
|
{
|
||
|
ShowException(ex);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void WriteLine(string line)
|
||
|
{
|
||
|
Console.WriteLine(Prefix + line);
|
||
|
}
|
||
|
|
||
|
static void WriteLine(string format, params object[] args)
|
||
|
{
|
||
|
WriteLine(String.Format(format, args));
|
||
|
}
|
||
|
|
||
|
const string Prefix = "NMAKE_DIRS: ";
|
||
|
|
||
|
static void Usage()
|
||
|
{
|
||
|
Console.WriteLine("Usage: nmake_dirs [/p] dir1 dir2 ... dirN [/nmake args to nmake.exe]");
|
||
|
Console.WriteLine();
|
||
|
Console.WriteLine(" /p Enables parallel builds of subdirectories.");
|
||
|
Console.WriteLine(" /nmake All args following /nmake are passed to nmake.exe.");
|
||
|
}
|
||
|
|
||
|
static void ShowException(Exception chain)
|
||
|
{
|
||
|
for (Exception ex = chain; ex != null; ex = ex.InnerException)
|
||
|
{
|
||
|
Console.WriteLine(ex.GetType().FullName + ": " + ex.Message);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static string RemoveQuotes(string str)
|
||
|
{
|
||
|
str = str.Trim();
|
||
|
if (str.StartsWith("\"") && str.EndsWith("\""))
|
||
|
return str.Substring(1, str.Length - 2);
|
||
|
return str;
|
||
|
}
|
||
|
|
||
|
}
|