logo

abstract class

build::BuildPod

sys::Obj
  build::BuildScript
    build::BuildPod
   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  }