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 binary: 50 Binary(build, projectPath).run(); 51 break; 52 53 case none: 54 throw new Exception("A backend must be specified with -b/--backend"); 55 } 56 } 57 58 private void handleNinja(in Build build) { 59 version(minimal) { 60 throw new Exception("Ninja backend support not compiled in"); 61 } else { 62 63 const ninja = Ninja(build, projectPath); 64 65 auto buildNinja = File("build.ninja", "w"); 66 buildNinja.writeln("include rules.ninja\n"); 67 buildNinja.writeln(ninja.buildOutput); 68 69 auto rulesNinja = File("rules.ninja", "w"); 70 rulesNinja.writeln(ninja.rulesOutput); 71 } 72 } 73 74 75 private void handleMake(in Build build) { 76 version(minimal) { 77 throw new Exception("Make backend support not compiled in"); 78 } else { 79 80 const makefile = Makefile(build, projectPath); 81 auto file = File(makefile.fileName, "w"); 82 file.write(makefile.output); 83 } 84 }