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 }