
1 // 2 // Copyright (c) 2006, Brian Frank and Andy Frank 3 // Licensed under the Academic Free License version 3.0 4 // 5 // History: 6 // 3 Nov 06 Brian Frank Creation 7 // 8 9 ** 10 ** BuildPod is the base class for build scripts used to manage 11 ** building a Fan source code and resources into a Fan pod. 12 ** 13 ** See `docTools::Build` for details. 14 ** 15 abstract class BuildPod : BuildScript 16 { 17 18 ////////////////////////////////////////////////////////////////////////// 19 // Pod Meta-Data 20 ////////////////////////////////////////////////////////////////////////// 21 22 ** 23 ** Programatic name of the pod. Required. 24 ** 25 Str podName := null 26 27 ** 28 ** Short one sentence description of the pod. Required. 29 ** 30 Str description := null 31 32 ** 33 ** User defined pod level facets. Optional. 34 ** 35 Str:Obj podFacets := Str:Obj[:] 36 37 ** 38 ** Version of the pod - typically set to 39 ** `BuildScript.globalVersion`. Required. 40 ** 41 Version version := null 42 43 ** 44 ** Dependencies of the pod formatted as a list 45 ** of `sys::Depend` strings. Required. 46 ** 47 Str[] depends := null 48 49 ** 50 ** The directory to look in for the dependency pod file (and 51 ** potentially their recursive dependencies). If null then we 52 ** use the compiler's own pod definitions via reflection (which 53 ** is more efficient). 54 ** 55 Uri dependsDir := null 56 57 ** 58 ** List of Uris relative to `scriptDir` of directories containing 59 ** the Fan source files to compile. Required. 60 ** 61 Uri[] srcDirs := null 62 63 ** 64 ** List of Uris relative to `scriptDir` of directories of resources 65 ** files to package into pod zip file. Optional. 66 ** 67 Uri[] resDirs := null 68 69 ** 70 ** List of Uris relative to `scriptDir` of directories containing 71 ** the Java source files to compile for Java native jar. 72 ** 73 Uri[] javaDirs := null 74 75 ** 76 ** List of Uris relative to `scriptDir` of Java jar files which 77 ** are automatically included in the classpath when compiling the 78 ** `javaDirs`. 79 ** 80 Uri[] javaLibs := null 81 82 ** 83 ** List of Uris relative to `scriptDir` of directories containing 84 ** the C# source files to compile for .NET native dll. 85 ** 86 Uri[] netDirs := null 87 88 ** 89 ** List of Uris relative to `scriptDir` of .NET assemblies which 90 ** are automatically included in the library path when compiling 91 ** the `netDirs`. 92 ** 93 Uri[] netLibs := null 94 95 ////////////////////////////////////////////////////////////////////////// 96 // Setup 97 ////////////////////////////////////////////////////////////////////////// 98 99 ** 100 ** Validate subclass constructor setup required meta-data. 101 ** 102 internal override Void validate() 103 { 104 ok := true 105 ok &= validateReqField("podName") 106 ok &= validateReqField("version") 107 ok &= validateReqField("depends") 108 if (!ok) throw FatalBuildErr.make 109 } 110 111 ////////////////////////////////////////////////////////////////////////// 112 // BuildScript 113 ////////////////////////////////////////////////////////////////////////// 114 115 ** 116 ** Default target is `compile`. 117 ** 118 override Target defaultTarget() { return target("compile") } 119 120 ////////////////////////////////////////////////////////////////////////// 121 // Compile 122 ////////////////////////////////////////////////////////////////////////// 123 124 @target="compile fan source into pod" 125 virtual Void compile(Bool full := false) 126 { 127 log.info("compile [$podName]") 128 log.indent 129 fanc := CompileFan.make(this) 130 fanc.includeDoc = full 131 fanc.includeSrc = full 132 fanc.run 133 log.unindent 134 } 135 136 internal Depend[] parseDepends() 137 { 138 return (Depend[])depends.map(Depend[,]) |Str s->Depend| { return Depend.fromStr(s) } 139 } 140 141 ////////////////////////////////////////////////////////////////////////// 142 // Clean 143 ////////////////////////////////////////////////////////////////////////// 144 145 @target="delete all intermediate and target files" 146 virtual Void clean() 147 { 148 log.info("clean [$podName]") 149 log.indent 150 Delete.make(this, libFanDir+"${podName}.pod".toUri).run 151 Delete.make(this, libJavaDir+"${podName}.jar".toUri).run 152 Delete.make(this, libNetDir+"${podName}.dll".toUri).run 153 Delete.make(this, libNetDir+"${podName}.pdb".toUri).run 154 Delete.make(this, scriptDir+"temp-java/".toUri).run 155 Delete.make(this, scriptDir+"temp-net/".toUri).run 156 log.unindent 157 } 158 159 ////////////////////////////////////////////////////////////////////////// 160 // JavaNative 161 ////////////////////////////////////////////////////////////////////////// 162 163 @target="build native Java jar file" 164 virtual Void javaNative() 165 { 166 if (javaDirs == null) return 167 168 log.info("javaNative [$podName]") 169 log.indent 170 171 // env 172 jtemp := scriptDir + `temp-java/` 173 jstub := jtemp + "${podName}.jar".toUri 174 jdk := JdkTask.make(this) 175 javaExe := jdk.javaExe 176 jarExe := jdk.jarExe 177 curPod := libFanDir + "${podName}.pod".toUri 178 curJar := libJavaDir + "${podName}.jar".toUri 179 javaDirs := resolveDirs(javaDirs) 180 javaLibs := resolveFiles(javaLibs) 181 depends := parseDepends 182 183 // start with a clean directory 184 Delete.make(this, jtemp).run 185 CreateDir.make(this, jtemp).run 186 187 // stub the pods fan classes into Java classfiles 188 // by calling the JStub tool in the jsys runtime 189 Exec.make(this, [javaExe.osPath, 190 "-cp", "${libJavaDir}sys.jar", 191 "fanx.tools.Jstub", 192 "-d", jtemp.osPath, 193 podName]).run 194 195 // compile 196 javac := CompileJava.make(this) 197 javac.outDir = jtemp 198 javac.cp.add(jtemp+"${podName}.jar".toUri).addAll(javaLibs) 199 depends.each |Depend d| { javac.cp.add(libJavaDir+(d.name+".jar").toUri) } 200 javac.src = javaDirs 201 javac.run 202 203 // extract stub jar into the temp directory 204 Exec.make(this, [jarExe.osPath, "-xf", jstub.osPath], jtemp).run 205 206 // now we can nuke the stub jar (and manifest) 207 Delete.make(this, jstub).run 208 Delete.make(this, jtemp + `meta-inf/`).run 209 210 // jar everything back up to lib/java/{pod}.jar 211 Exec.make(this, [jarExe.osPath, "cf", curJar.osPath, "-C", jtemp.osPath, "."], jtemp).run 212 213 // append files to the pod zip (we use java's jar tool) 214 Exec.make(this, [jarExe.osPath, "-fu", curPod.osPath, "-C", jtemp.osPath, "."], jtemp).run 215 216 // cleanup temp 217 Delete.make(this, jtemp).run 218 219 log.unindent 220 } 221 222 ////////////////////////////////////////////////////////////////////////// 223 // NetNative 224 ////////////////////////////////////////////////////////////////////////// 225 226 @target="build native .NET assembly" 227 virtual Void netNative() 228 { 229 if (netDirs == null) return 230 231 log.info("netNative [$podName]") 232 log.indent 233 234 // env 235 ntemp := scriptDir + `temp-net/` 236 nstub := ntemp + "${podName}.dll".toUri 237 nout := ntemp + "${podName}Native.dll".toUri 238 ndirs := netDirs 239 nlibs := ["${libNetDir}sys.dll".toUri, nstub.uri] 240 if (netLibs != null) nlibs.addAll(nlibs) 241 nstubExe := binDir + `nstub` 242 243 // start with a clean directory 244 Delete.make(this, ntemp).run 245 CreateDir.make(this, ntemp).run 246 247 // stub the pods fan classes into Java classfiles 248 // by calling the JStub tool in the jsys runtime 249 Exec.make(this, [nstubExe.osPath, "-d", ntemp.osPath, podName]).run 250 251 // compile 252 csc := CompileCs.make(this) 253 csc.output = nout 254 csc.targetType = "library" 255 csc.src = resolveDirs(ndirs) 256 csc.libs = resolveFiles(nlibs) 257 csc.run 258 259 // append files to the pod zip (we use java's jar tool) 260 jdk := JdkTask.make(this) 261 jarExe := jdk.jarExe 262 curPod := libFanDir + "${podName}.pod".toUri 263 Exec.make(this, [jarExe.osPath, "-fu", curPod.osPath, "-C", ntemp.osPath, 264 "${podName}Native.dll", "${podName}Native.pdb"], ntemp).run 265 266 // cleanup temp 267 Delete.make(this, ntemp).run 268 269 log.unindent 270 } 271 272 ////////////////////////////////////////////////////////////////////////// 273 // Full 274 ////////////////////////////////////////////////////////////////////////// 275 276 @target="clean+compile+native (with doc+src)" 277 virtual Void full() 278 { 279 clean 280 compile(true) 281 javaNative 282 netNative 283 } 284 285 ////////////////////////////////////////////////////////////////////////// 286 // Test 287 ////////////////////////////////////////////////////////////////////////// 288 289 @target="run fant for specified pod" 290 virtual Void test() 291 { 292 log.info("test [$podName]") 293 log.indent 294 295 fant := binDir + `fant.exe` 296 Exec.make(this, [fant.osPath, podName]).run 297 298 log.unindent 299 } 300 301 }