/** The main program entry point. */ public static int Main(string[] args) { int result = 0; try { // parse and check command-line parameters Setup setup = new Setup(); setup.Parse(args); setup.Check(); // tell the world who's running the show if (setup.Verbose >= 1) { System.Console.WriteLine("Braceless.Builder v0.15/.NET - http://www.braceless.org"); System.Console.WriteLine("Copyright (C) 2013-2016 Mikael Egevig. All Rights Reserved."); System.Console.WriteLine(); } // show help, if requested by the user if (setup.Help) { Setup.ShowHelp(); return 1; } // ensure the user is using the latest and greatest version of Builder.cs { string filename = System.Environment.GetCommandLineArgs()[0]; filename = System.IO.Path.GetFileNameWithoutExtension(filename); if (System.IO.File.Exists(filename + ".exe") && System.IO.File.Exists(filename + ".cs")) { System.DateTime bintime = System.IO.File.GetLastWriteTime(filename + ".exe"); System.DateTime srctime = System.IO.File.GetLastWriteTime(filename + ".cs"); if (srctime > bintime) throw new BuildError("'Builder.cs' is newer than 'Builder.exe' - please rebuild 'Builder.exe'"); } } #if false /* This is a very dangerous idea if the user tries to specify "-output:."... */ // remove the output folder to ensure everything's neat and fine (it is recreated automatically) System.IO.Directory.Delete(setup.Output, true); #endif // build the various assemblies and executables that make up the Braceless compiler. string[] core = { "Braceless.Toolbox.dll", "Braceless.Diction.dll" }; string[] reader = { "Braceless.Toolbox.dll", "Braceless.Diction.dll", "Braceless.Reader.dll" }; string[] writer0 = { "Braceless.Toolbox.dll", "Braceless.Diction.dll", "Braceless.Walkers.dll" }; string[] writer1 = { "Braceless.Toolbox.dll", "Braceless.Diction.dll", "Braceless.Walkers.dll", "Braceless.Writer.dll" }; string[] full = { "Braceless.Toolbox.dll", "Braceless.Diction.dll", "Braceless.Reader.dll", "Braceless.Reader.Braceless0.dll", "Braceless.Walkers.dll", "Braceless.Writer.dll", "Braceless.Writer.Braceless0.dll", "Braceless.Writer.LLVM.dll" }; Build("Braceless.Toolbox.dll", "Toolbox", true, new string[0], setup); Build("Braceless.Diction.dll", "Diction", true, new string[] { "Braceless.Toolbox.dll" }, setup); Build("Braceless.Reader.dll", "Readers", false, core, setup); Build("Braceless.Reader.Braceless0.dll", "Readers/Braceless0", true, reader, setup); Build("Braceless.Walkers.dll", "Walkers", true, core, setup); Build("Braceless.Writer.dll", "Writers", false, writer0, setup); Build("Braceless.Writer.Braceless0.dll", "Writers/Braceless0", true, writer1, setup); Build("Braceless.Writer.LLVM.dll", "Writers/LLVM", true, writer1, setup); Build("b0c.exe", "Drivers/Compiler", true, full, setup); Build("Bugfind.exe", "Bugfind", false, new string[]{ "Braceless.Toolbox.dll" }, setup); // build documentation in ../obj/doc/html. if (setup.Documentation) { string helpdir = "../obj/doc"; System.Console.WriteLine("Building: {0}", helpdir); if (System.IO.Directory.Exists(helpdir)) System.IO.Directory.Delete(helpdir, true); System.IO.Directory.CreateDirectory(helpdir); Process.Execute("doxygen", false); } } catch (BuildError exception) { // report a neat error to STDOUT (I loathe tools that report errors to STDERR!) System.Console.WriteLine("Error: {0}", exception.Message); result = 1; } return result; }
/** Build the specified target (basename) from the source files in the home path. * * The target is linked with the specified assemblies and the specified setup is used. */ public static void Build(string basename, string homepath, bool recurse, string[] assemblies, Setup setup) { List<string> args = new List<string>(); // compute the full output path of the target string target = setup.Output + '/' + basename; if (setup.Verbose >= 1) System.Console.WriteLine("Building: {0}", target); // determine if target is up-to-date and skip build if so string[] files = FileFind(homepath, "*.cs", recurse); if (!setup.Clean && System.IO.File.Exists(target)) { long filedate = FileDate(target); bool uptodate = true; // check if any source file is newer than the target file foreach (string file in files) { if (FileDate(file) > filedate) { uptodate = false; break; } } // check if any needed assembly is newer than the target file foreach (string assembly in assemblies) { if (FileDate(setup.Output + '/' + assembly) > filedate) { uptodate = false; break; } } // if up-to-date, don't build target if (uptodate) return; } // handle the SHIP/TEST cases if (setup.Ship) { args.Add("-define:SHIP"); args.Add("-optimize+"); } else { args.Add("-define:TEST"); args.Add("-debug+"); } // enable C# overflow checking (this is probably disabled by default due to the severe speed penalty it imposes) if (setup.Checked) args.Add("-checked+"); // sign the assembly so that we get rid of future warnings and errors args.Add("-keyfile:Braceless.snk"); // tell the compiler to stop littering the screen/log file with copyright messages, if applicable if (!setup.Logo) args.Add("-nologo"); // tell the compiler the name of the output file args.Add("-out:" + target); // reference each of the specified assemblies foreach (string assembly in assemblies) args.Add(string.Format("-reference:{0}/{1}", setup.Output, assembly)); // ensure libraries (.dll files) get built correctly if (System.IO.Path.GetExtension(basename) == ".dll") args.Add("-target:library"); // append the source file names foreach (string file in files) args.Add(file); // ensure the output directory exists if (!System.IO.Directory.Exists(setup.Output)) System.IO.Directory.CreateDirectory(setup.Output); // convert list of arguments into a single string with embedded spaces in it string[] arglist = args.ToArray(); string arguments = Process.JoinCommandLine(arglist); // output command if verbosity is greater than or equal to two if (setup.Verbose >= 2) System.Console.WriteLine("{0} {1}", setup.Compiler, arguments); // invoke the specified compiler Process.Status status = Process.Execute(setup.Compiler, arguments, (setup.Verbose >= 1)); if (status.Code != 0) { // remove the failed target so as to ensure the next invokation of 'build.cs' does not succeed. System.IO.File.Delete(target); throw new BuildError("Error invoking command '" + setup.Compiler + "'"); } }