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 targetName = dubInfo.targetName;
27         enum linkerFlags = dubInfo.mainLinkerFlags;
28         return dubTarget!(() { Target[] t; return t;})
29             (
30                 targetName,
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!()(TargetName("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      Builds a particular dub configuration (executable, unittest, etc.)
85      */
86     Target dubConfigurationTarget(TargetName targetName,
87                                   Configuration config = Configuration("default"),
88                                   Flags compilerFlags = Flags(),
89                                   Flag!"main" includeMain = Yes.main,
90                                   Flag!"allTogether" allTogether = No.allTogether,
91                                   alias objsFunction = () { Target[] t; return t; },
92                                   )
93         () if(isCallable!objsFunction)
94     {
95 
96         return dubTarget!(objsFunction)(targetName,
97                                         configToDubInfo[config.value],
98                                         compilerFlags.value,
99                                         includeMain,
100                                         allTogether);
101     }
102 
103 
104     Target dubTarget(alias objsFunction = () { Target[] t; return t;})
105                     (in TargetName targetName,
106                      in DubInfo dubInfo,
107                      in string compilerFlags,
108                      in Flag!"main" includeMain = Yes.main,
109                      in Flag!"allTogether" allTogether = No.allTogether,
110                      in string[] linkerFlags = [])
111     {
112 
113         import reggae.rules.common: staticLibraryTarget;
114         import std.array: join;
115 
116         const allLinkerFlags = (linkerFlags ~ dubInfo.linkerFlags).join(" ");
117         auto dubObjs = dubInfo.toTargets(includeMain, compilerFlags, allTogether);
118         auto allObjs = objsFunction() ~ dubObjs;
119 
120         return dubInfo.targetType == "library"
121             ? staticLibraryTarget(targetName.value, allObjs)[0]
122             : link(ExeName(targetName.value),
123                    allObjs,
124                    Flags(allLinkerFlags));
125     }
126 }