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 }