1 /**
2  High-level rules for building dub projects. The rules in this module
3  only replicate what dub does itself. This allows a reggaefile.d to
4  reuse the information that dub already knows about.
5  */
6 
7 module reggae.rules.dub;
8 
9 import reggae.config; // isDubProject
10 
11 static if(isDubProject) {
12 
13     import reggae.dub.info;
14     import reggae.types;
15     import reggae.build;
16     import reggae.rules.common;
17     import std.typecons;
18     import std.traits;
19 
20     /**
21      Builds the main dub target (equivalent of "dub build")
22     */
23     Target dubDefaultTarget(Flags compilerFlags = Flags(), Flag!"allTogether" allTogether = No.allTogether)() {
24         enum config = "default";
25         const dubInfo = configToDubInfo[config];
26         enum exeName = dubInfo.exeName;
27         enum linkerFlags = dubInfo.mainLinkerFlags;
28         return dubTarget!(() { Target[] t; return t;})
29             (
30                 exeName,
31                 dubInfo,
32                 compilerFlags.value,
33                 Yes.main,
34                 allTogether,
35                 linkerFlags
36             );
37     }
38 
39 
40     /**
41        A target corresponding to `dub test`
42      */
43     Target dubTestTarget(Flags compilerFlags = Flags())() {
44         const config = "unittest" in configToDubInfo ? "unittest" : "default";
45 
46         auto actualCompilerFlags = compilerFlags.value;
47         if("unittest" !in configToDubInfo) actualCompilerFlags ~= " -unittest";
48 
49         const hasMain = configToDubInfo[config].packages[0].mainSourceFile != "";
50         const linkerFlags = hasMain ? [] : ["-main"];
51 
52         // since dmd has a bug pertaining to separate compilation and __traits(getUnitTests),
53         // we default here to compiling all-at-once for the unittest build
54         return dubTarget!()(ExeName("ut"),
55                             configToDubInfo[config],
56                             actualCompilerFlags,
57                             Yes.main,
58                             Yes.allTogether,
59                             linkerFlags);
60     }
61 
62 
63     /**
64      Builds a particular dub configuration (executable, unittest, etc.)
65      */
66     Target dubConfigurationTarget(ExeName exeName,
67                                   Configuration config = Configuration("default"),
68                                   Flags compilerFlags = Flags(),
69                                   Flag!"main" includeMain = Yes.main,
70                                   Flag!"allTogether" allTogether = No.allTogether,
71                                   alias objsFunction = () { Target[] t; return t; },
72                                   )
73         () if(isCallable!objsFunction)
74     {
75 
76         return dubTarget!(objsFunction)(exeName,
77                                         configToDubInfo[config.value],
78                                         compilerFlags.value,
79                                         includeMain,
80                                         allTogether);
81     }
82 
83 
84     Target dubTarget(alias objsFunction = () { Target[] t; return t;})
85                     (in ExeName exeName,
86                      in DubInfo dubInfo,
87                      in string compilerFlags,
88                      in Flag!"main" includeMain = Yes.main,
89                      in Flag!"allTogether" allTogether = No.allTogether,
90                      in string[] linkerFlags = [])
91     {
92 
93         import std.array: join;
94 
95         const allLinkerFlags = (linkerFlags ~ dubInfo.linkerFlags).join(" ");
96         auto dubObjs = dubInfo.toTargets(includeMain, compilerFlags, allTogether);
97         return link(exeName,
98                     objsFunction() ~ dubObjs ~ dubInfo.staticLibrarySources(),
99                     Flags(allLinkerFlags));
100     }
101 }