#region --- License ---
/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos
* See license.txt for license info
*/
#endregion
#region --- Using Directives ---
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Text.RegularExpressions;
using System.Reflection;
using OpenTK.Build.Properties;
#endregion
namespace OpenTK.Build
{
class Project
{
static string RootPath;
const string bindings = "Generator.Prebuild.xml";
const string opentk = "OpenTK.Prebuild.xml";
const string quickstart = "QuickStart.Prebuild.xml";
const string keyfile = "OpenTK.snk";
const string Usage = @"Usage: Build.exe target
target: one of vs, vs9, clean, distclean, help";
const string Help = Usage + @"
Available targets:
vs: Create Visual Studio 2005 project files.
vs9: Create Visual Studio 2008 project files.
clean: Delete intermediate files but leave final binaries and project
files intact.
distclean: Delete intermediate files, final binaries and project files.
help: Display this help.
Assembly signing:
To create strongly-named assemblies, place a keypair file named OpenTK.snk
to the root folder (the same folder as Build.exe). If OpenTK.snk does not
exist the resulting assemblies will not be signed.
";
static readonly Assembly Prebuild = Assembly.Load(Resources.Prebuild);
enum BuildTarget
{
VS2005,
VS2008,
Mono,
Net,
Clean,
DistClean,
}
static BuildTarget target = BuildTarget.VS2005;
static void PrintUsage()
{
Console.WriteLine(Usage);
}
static void PrintHelp()
{
Console.WriteLine(Help);
}
static void Main(string[] args)
{
if (args.Length == 0)
{
PrintUsage();
args = new string[2] { String.Empty, String.Empty };
Console.Write("Select build target: ");
args[0] = Console.ReadLine();
if (args[0] == String.Empty)
args[0] = "vs";
}
RootPath = Directory.GetCurrentDirectory();
//string sign_assembly = CheckKeyFile(keyfile) ? "SIGN_ASSEMBLY" : "";
string sign_assembly = CheckKeyFile(keyfile) ? @"../../" + keyfile + @"" : "";
File.WriteAllText(bindings, String.Format(Resources.Generator, sign_assembly));
File.WriteAllText(opentk, String.Format(Resources.OpenTK, sign_assembly));
File.WriteAllText(quickstart, String.Format(Resources.QuickStart,sign_assembly));
// Workaroung for nant on x64 windows (safe for other platforms too, as this affects only the current process).
Environment.SetEnvironmentVariable("CommonProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process);
Environment.SetEnvironmentVariable("ProgramFiles(x86)", String.Empty, EnvironmentVariableTarget.Process);
foreach (string s in args)
{
string arg = s.ToLower().Trim();
switch (arg)
{
case "":
break;
case "help":
PrintHelp();
return;
case "mono":
case "xbuild":
target = BuildTarget.Mono;
break;
case "net":
case "msbuild":
target = BuildTarget.Net;
break;
case "vs2005":
case "vs8":
case "vs":
target = BuildTarget.VS2005;
break;
case "vs2008":
case "vs9":
target = BuildTarget.VS2008;
break;
case "clean":
target = BuildTarget.Clean;
break;
case "distclean":
target = BuildTarget.DistClean;
break;
default:
Console.WriteLine("Unknown command: {0}", s);
PrintUsage();
return;
}
}
switch (target)
{
//case BuildTarget.Mono:
// Console.WriteLine("Building OpenTK using Mono/XBuild.");
// ExecuteProcess(PrebuildPath, "/target nant /file " + PrebuildXml);
// Console.WriteLine();
// ExecuteProcess(
// "nant",
// "-buildfile:./Build/OpenTK.build -t:mono-2.0 " + (mode == BuildMode.Debug ? "build-debug" : "build-release"));
// CopyBinaries();
// break;
//case BuildTarget.Net:
// Console.WriteLine("Building OpenTK using .Net");
// ExecuteProcess(PrebuildPath, "/target nant /file " + PrebuildXml);
// Console.WriteLine();
// ExecuteProcess(
// "nant",
// "-buildfile:./Build/OpenTK.build -t:net-2.0 " + (mode == BuildMode.Debug ? "build-debug" : "build-release"));
// CopyBinaries();
// break;
case BuildTarget.VS2005:
Console.WriteLine("Creating VS2005 project files");
ExecutePrebuild("/target", "vs2008", "/file", bindings);
ExecutePrebuild("/target", "vs2005", "/file", opentk);
ExecutePrebuild("/target", "vs2005", "/file", quickstart);
break;
case BuildTarget.VS2008:
Console.WriteLine("Creating VS2008 project files");
ExecutePrebuild("/target", "vs2008", "/file", bindings);
ExecutePrebuild("/target", "vs2008", "/file", opentk);
ExecutePrebuild("/target", "vs2008", "/file", quickstart);
break;
case BuildTarget.Clean:
Console.WriteLine("Cleaning intermediate object files.");
ExecutePrebuild("/clean", "/yes", "/file", bindings);
ExecutePrebuild("/clean", "/yes", "/file", opentk);
ExecutePrebuild("/clean", "/yes", "/file", quickstart);
DeleteDirectories(RootPath, "obj");
break;
case BuildTarget.DistClean:
Console.WriteLine("Cleaning intermediate and final object files.");
ExecutePrebuild("/clean", "/yes", "/file", bindings);
ExecutePrebuild("/clean", "/yes", "/file", opentk);
ExecutePrebuild("/clean", "/yes", "/file", quickstart);
DeleteDirectories(RootPath, "obj");
DeleteDirectories(RootPath, "bin");
string binaries_path = Path.Combine(RootPath, "Binaries");
if (Directory.Exists(binaries_path))
Directory.Delete(binaries_path, true);
break;
default:
Console.WriteLine("Unknown target: {0}", target);
PrintUsage();
return;
}
// Wait until Prebuild releases the input files.
System.Threading.Thread.Sleep(1000);
File.Delete(bindings);
File.Delete(opentk);
File.Delete(quickstart);
if (Debugger.IsAttached)
{
Console.WriteLine("Press any key to continue...");
Console.ReadKey(true);
}
}
static void DeleteDirectories(string root_path, string search)
{
Console.WriteLine("Deleting {0} directories", search);
List matches = new List();
FindDirectories(root_path, search, matches);
foreach (string m in matches)
{
Directory.Delete(m, true);
}
}
static void FindDirectories(string directory, string search, List matches)
{
try
{
foreach (string d in Directory.GetDirectories(directory))
{
foreach (string f in Directory.GetDirectories(d, search))
{
matches.Add(f);
}
FindDirectories(d, search, matches);
}
}
catch (System.Exception e)
{
Console.WriteLine(e.Message);
}
}
static void FileCopy(string srcdir, string destdir, Regex match)
{
//DirectoryInfo dir;
//FileInfo[] files;
//DirectoryInfo[] dirs;
//string tmppath;
//determine if the destination directory exists, if not create it
if (!Directory.Exists(destdir))
Directory.CreateDirectory(destdir);
if (!Directory.Exists(srcdir))
throw new ArgumentException("source dir doesn't exist -> " + srcdir);
string[] files = Directory.GetFiles(srcdir);
foreach (string f in files)
//if (Path.GetExtension(f).ToLower() == ext.ToLower())
if (match.IsMatch(Path.GetExtension(f)))
File.Copy(f, Path.Combine(destdir, Path.GetFileName(f)), true);
foreach (string dir in Directory.GetDirectories(srcdir))
{
string name = dir.Substring(dir.LastIndexOf(Path.DirectorySeparatorChar)+1);
if (!name.StartsWith("."))
FileCopy(dir, Path.Combine(destdir, name), match);
}
}
static void ExecutePrebuild(params string[] options)
{
Prebuild.EntryPoint.Invoke(null, new object[] { options });
}
static bool CheckKeyFile(string keyfile)
{
if (!File.Exists(keyfile))
{
//Console.WriteLine("Keyfile {0} not found. Generating temporary key pair.", keyfile);
//Process keygen = Process.Start("sn", "-k " + keyfile);
//keygen.WaitForExit();
Console.WriteLine("Keyfile {0} not found. Assemblies will not be signed.", keyfile);
Console.WriteLine();
return false;
}
else
{
Console.WriteLine("Keyfile {0} found. Assemblies will be signed.", keyfile);
Console.WriteLine();
return true;
}
}
}
}