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 }