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