summary refs log tree commit diff stats
path: root/koch.nim
diff options
context:
space:
mode:
authorAndreas Rumpf <andreas@andreas-desktop>2009-12-07 01:21:35 +0100
committerAndreas Rumpf <andreas@andreas-desktop>2009-12-07 01:21:35 +0100
commit90119066adf6a9a2e8d779d4955637c6dd99aba3 (patch)
treef05e2bbf6aad693cc8455ff5e51b33dd5ec7ed6d /koch.nim
parent196ef92c86d8b8971d4b316f7c18e404842c4b9b (diff)
downloadNim-90119066adf6a9a2e8d779d4955637c6dd99aba3.tar.gz
version 0.8.5: bugfixes; compiler now maintained in Nimrod
Diffstat (limited to 'koch.nim')
-rwxr-xr-xkoch.nim201
1 files changed, 201 insertions, 0 deletions
diff --git a/koch.nim b/koch.nim
new file mode 100755
index 000000000..02b0334b0
--- /dev/null
+++ b/koch.nim
@@ -0,0 +1,201 @@
+#
+#
+#         Maintenance program for Nimrod  
+#        (c) Copyright 2009 Andreas Rumpf
+#
+#    See the file "copying.txt", included in this
+#    distribution, for details about the copyright.
+#
+
+import
+  os, strutils, parseopt
+
+const
+  HelpText = """
++-----------------------------------------------------------------+
+|         Maintenance program for Nimrod                          |
+|             Version $1|
+|             (c) 2009 Andreas Rumpf                              |
++-----------------------------------------------------------------+
+Build time: $2, $3
+
+Usage:
+  koch.py [options] command [options for command]
+Options:
+  --help, -h               shows this help and quits
+Possible Commands:
+  boot [options]           bootstraps with given command line options
+  clean                    cleans Nimrod project; removes generated files
+  web                      generates the website
+  csource [options]        builds the C sources for installation
+  zip                      builds the installation ZIP package
+  inno                     builds the Inno Setup installer
+"""
+
+proc exec(cmd: string) =
+  echo(cmd)
+  if execShellCmd(cmd) != 0: quit("FAILURE")
+
+proc tryExec(cmd: string): bool = 
+  echo(cmd)
+  result = execShellCmd(cmd) == 0
+
+proc csource(args: string) = 
+  exec("nimrod cc $# -r tools/niminst --var:version=$# csource rod/nimrod $2" %
+       [args, NimrodVersion])
+
+proc zip(args: string) = 
+  exec("nimrod cc -r tools/niminst --var:version=$# zip rod/nimrod" %
+       NimrodVersion)
+  
+proc inno(args: string) = 
+  exec("nimrod cc -r tools/niminst --var:version=$# inno rod/nimrod" %
+       NimrodVersion)
+
+proc install(args: string) = 
+  exec("sh ./build.sh")
+
+proc web(args: string) =
+  exec("nimrod cc -r tools/nimweb.nim web/nimrod --putenv:nimrodversion=$#" %
+       NimrodVersion)
+  
+proc exe(f: string): string = return addFileExt(f, ExeExt)
+
+# -------------- nim ----------------------------------------------------------
+
+proc compileNimCmd(args: string): string = 
+  var cwd = getCurrentDir()
+  result = ("fpc -Cs16777216 -gl -bl -Crtoi -Sgidh -vw -Se1 $4 -o\"$1\" " &
+            "-FU\"$2\" \"$3\"") % [cwd / "bin" / "nim".exe, 
+                                   cwd / "obj",
+                                   cwd / "nim" / "nimrod.pas",
+                                   args]
+
+proc nim(args: string) = exec(compileNimCmd(args))
+
+# -------------- boot ---------------------------------------------------------
+
+proc writePlatdefC =
+  const
+    PlatdefCTmpl = """
+      /* Generated by boot.nim */
+      char* nimOS(void) { return "$#"; }
+      char* nimCPU(void) { return "$#"; }
+    """
+  var f: TFile
+  if open(f, "build/platdef.c", fmWrite): 
+    write(f, PlatdefcTmpl % [system.hostOS, system.hostCPU])
+    close(f)
+  else:
+    quit("Cannot write 'build/platdef.c'\n")
+
+const
+  bootOptions = "--compile:build/platdef.c"
+
+proc findStartNimrod: string = 
+  const buildScript = "build.sh"
+  # we try several things before giving up:
+  # * bin/nimrod
+  # * $PATH/nimrod
+  # * bin/nim
+  # If these fail, we build nimrod with the "build.sh" script
+  # (but only on UNIX). Otherwise we try to compile "nim" with FPC 
+  # and use "bin/nim".
+  var nimrod = "nimrod".exe
+  result = "bin" / nimrod
+  if ExistsFile(result): return
+  for dir in split(getEnv("PATH"), PathSep):
+    if ExistsFile(dir / nimrod): return nimrod
+  result = "bin" / "nim".exe
+  if ExistsFile(result): return
+  when defined(Posix):
+    if ExistsFile(buildScript): 
+      if tryExec("./" & buildScript): return "bin" / nimrod
+  
+  if tryExec(compileNimCmd("")): return 
+  echo("Found no nimrod compiler and every attempt to build one failed!")
+  quit("FAILURE")
+
+proc bootIteration(args: string): bool = 
+  var nimrod1 = "rod" / "nimrod1".exe
+  moveFile nimrod1, "rod" / "nimrod".exe
+  exec "rod" / "nimrod1 cc $# $# rod/nimrod.nim" % [bootOptions, args]
+  result = sameFileContent("rod" / "nimrod".exe, "rod" / "nimrod1".exe)
+  if result:
+    moveFile "bin" / "nimrod".exe, "rod" / "nimrod".exe
+    echo "executables are equal: SUCCESS!"
+  removeFile nimrod1
+
+proc boot(args: string) =
+  writePlatdefC()
+  echo "iteration: 1"
+  exec findStartNimrod() & " cc $# $# rod" / "nimrod.nim" % [bootOptions, args]
+  echo "iteration: 2"
+  if not bootIteration(args):
+    echo "executables are not equal: compile once again..."
+    if not bootIteration(args):
+      echo "[Warning] executables are still not equal"
+
+# -------------- clean --------------------------------------------------------
+
+const
+  cleanExt = [
+    ".ppu", ".o", ".obj", ".dcu", ".~pas", ".~inc", ".~dsk", ".~dpr",
+    ".map", ".tds", ".err", ".bak", ".pyc", ".exe", ".rod", ".pdb", ".idb"
+  ]
+  ignore = [
+    ".bzrignore", "nimrod", "nimrod.exe", "koch", "koch.exe"
+  ]
+
+proc cleanAux(dir: string) = 
+  for kind, path in walkDir(dir):
+    case kind
+    of pcFile:
+      var (dir, name, ext) = splitFile(path)
+      if ext == "" or cleanExt.contains(ext):
+        if not ignore.contains(name):
+          echo "removing: ", path
+          removeFile(path)
+    of pcDir:
+      case splitPath(path).tail
+      of "nimcache": 
+        echo "removing dir: ", path
+        removeDir(path)
+      of "dist", ".bzr":
+        nil
+      else:
+        cleanAux(path)
+    else: nil
+
+proc removePattern(pattern: string) = 
+  for f in WalkFiles(pattern): 
+    echo "removing: ", f
+    removeFile(f)
+
+proc clean(args: string) = 
+  if ExistsFile("koch.dat"): removeFile("koch.dat")
+  removePattern("web/*.html")
+  removePattern("doc/*.html")
+  cleanAux(getCurrentDir())
+
+proc showHelp() = 
+  quit(HelpText % [NimrodVersion & repeatChar(44-len(NimrodVersion)), 
+                   CompileDate, CompileTime])
+
+var op = initOptParser()
+op.next()
+case op.kind
+of cmdLongOption, cmdShortOption: showHelp()
+of cmdArgument:
+  case normalize(op.key) 
+  of "boot": boot(op.cmdLineRest)
+  of "clean": clean(op.cmdLineRest)
+  of "web": web(op.cmdLineRest)
+  of "csource": csource(op.cmdLineRest)
+  of "zip": zip(op.cmdLineRest)
+  of "inno": inno(op.cmdLineRest)
+  of "install": install(op.cmdLineRest)
+  of "nim": nim(op.cmdLineRest)
+  else: showHelp()
+of cmdEnd: showHelp()
+