1 module reggae.buildgen; 2 3 import reggae.build; 4 import reggae.options; 5 import reggae.types; 6 import reggae.backend; 7 import reggae.reflect; 8 9 import std.stdio; 10 11 /** 12 Creates a build generator out of a module and a list of top-level targets. 13 This will define a function with the signature $(D Build buildFunc()) in 14 the calling module and a $(D main) entry point function for a command-line 15 executable. 16 */ 17 mixin template buildGen(string buildModule, targets...) { 18 mixin buildImpl!targets; 19 mixin BuildGenMain!buildModule; 20 } 21 22 mixin template BuildGenMain(string buildModule = "reggaefile") { 23 import std.stdio; 24 25 int main(string[] args) { 26 try { 27 import reggae.config: options; 28 generateBuildFor!(buildModule)(options, args); //the user's build description 29 } catch(Exception ex) { 30 stderr.writeln(ex.msg); 31 return 1; 32 } 33 34 return 0; 35 } 36 } 37 38 void generateBuildFor(alias module_)(in Options options, string[] args) { 39 const buildFunc = getBuild!(module_); //get the function to call by CT reflection 40 const build = buildFunc(); //actually call the function to get the build description 41 generateBuild(build, options, args); 42 } 43 44 void generateBuild(in Build build, in Options options, string[] args = []) { 45 final switch(options.backend) with(Backend) { 46 47 case make: 48 handleMake(build, options); 49 break; 50 51 case ninja: 52 handleNinja(build, options); 53 break; 54 55 case tup: 56 handleTup(build, options); 57 break; 58 59 case binary: 60 Binary(build, options).run(args); 61 break; 62 63 case none: 64 throw new Exception("A backend must be specified with -b/--backend"); 65 } 66 } 67 68 private void handleNinja(in Build build, in Options options) { 69 version(minimal) { 70 throw new Exception("Ninja backend support not compiled in"); 71 } else { 72 73 const ninja = Ninja(build, options); 74 75 auto buildNinja = File("build.ninja", "w"); 76 buildNinja.writeln("include rules.ninja\n"); 77 buildNinja.writeln(ninja.buildOutput); 78 79 auto rulesNinja = File("rules.ninja", "w"); 80 rulesNinja.writeln(ninja.rulesOutput); 81 } 82 } 83 84 85 private void handleMake(in Build build, in Options options) { 86 version(minimal) { 87 throw new Exception("Make backend support not compiled in"); 88 } else { 89 90 const makefile = Makefile(build, options); 91 auto file = File(makefile.fileName, "w"); 92 file.write(makefile.output); 93 } 94 } 95 96 private void handleTup(in Build build, in Options options) { 97 version(minimal) { 98 throw new Exception("Tup backend support not compiled in"); 99 } else { 100 if(!".tup".exists) execute(["tup", "init"]); 101 const tup = Tup(build, options); 102 auto file = File(tup.fileName, "w"); 103 file.write(tup.output); 104 } 105 }