summary refs log tree commit diff stats
path: root/tools/niminst
diff options
context:
space:
mode:
Diffstat (limited to 'tools/niminst')
-rw-r--r--tools/niminst/buildsh.tmpl44
-rw-r--r--tools/niminst/deinstall.tmpl25
-rw-r--r--tools/niminst/install.tmpl79
-rw-r--r--tools/niminst/makefile.tmpl6
-rw-r--r--tools/niminst/niminst.nim104
-rw-r--r--tools/niminst/nsis.tmpl2
6 files changed, 198 insertions, 62 deletions
diff --git a/tools/niminst/buildsh.tmpl b/tools/niminst/buildsh.tmpl
index aa3bce3c3..13dfe5226 100644
--- a/tools/niminst/buildsh.tmpl
+++ b/tools/niminst/buildsh.tmpl
@@ -1,5 +1,5 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateBuildShellScript(c: ConfigData): string = 
+#proc generateBuildShellScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated from niminst\n" &
 #           "# Template is in tools/niminst/buildsh.tmpl\n" &
 #           "# To regenerate run ``niminst csource`` or ``koch csource``\n"
@@ -29,8 +29,8 @@ done
 
 CC="gcc"
 LINKER="gcc"
-COMP_FLAGS="?{c.ccompiler.flags}$extraBuildArgs"
-LINK_FLAGS="?{c.linker.flags}"
+COMP_FLAGS="${CPPFLAGS:-} ${CFLAGS:-} ?{c.ccompiler.flags}$extraBuildArgs"
+LINK_FLAGS="${LDFLAGS:-} ?{c.linker.flags}"
 PS4=""
 #  add(result, "# platform detection\n")
 ucpu=`uname -m`
@@ -51,8 +51,8 @@ ucpu=`echo $ucpu | tr "[:upper:]" "[:lower:]"`
 uos=`echo $uos | tr "[:upper:]" "[:lower:]"`
 
 case $uos in
-  *linux* ) 
-    myos="linux" 
+  *linux* )
+    myos="linux"
     LINK_FLAGS="$LINK_FLAGS -ldl -lm"
     ;;
   *dragonfly* )
@@ -66,14 +66,14 @@ case $uos in
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
   *openbsd* )
-    myos="openbsd" 
+    myos="openbsd"
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
   *netbsd* )
     myos="netbsd"
     LINK_FLAGS="$LINK_FLAGS -lm"
     ;;
-  *darwin* ) 
+  *darwin* )
     myos="macosx"
     CC="clang"
     LINKER="clang"
@@ -84,41 +84,45 @@ case $uos in
     ;;
   *aix* )
     myos="aix"
-    LINK_FLAGS="$LINK_FLAGS -ldl -lm"    
+    LINK_FLAGS="$LINK_FLAGS -ldl -lm"
     ;;
-  *solaris* | *sun* ) 
+  *solaris* | *sun* )
     myos="solaris"
     LINK_FLAGS="$LINK_FLAGS -ldl -lm -lsocket -lnsl"
     ;;
   *haiku* )
     myos="haiku"
     ;;
-  *) 
+  *)
     echo 2>&1 "Error: unknown operating system: $uos"
     exit 1
     ;;
 esac
 
 case $ucpu in
-  *i386* | *i486* | *i586* | *i686* | *bepc* | *i86pc* ) 
+  *i386* | *i486* | *i586* | *i686* | *bepc* | *i86pc* )
     mycpu="i386" ;;
-  *amd*64* | *x86-64* | *x86_64* ) 
+  *amd*64* | *x86-64* | *x86_64* )
     mycpu="amd64" ;;
-  *sparc*|*sun* ) 
-    mycpu="sparc" ;;
-  *ppc64* ) 
+  *sparc*|*sun* )
+    mycpu="sparc"
+    if [ "$(isainfo -b)" = "64" ]; then
+      mycpu="sparc64"
+    fi
+    ;;
+  *ppc64* )
     if [ "$myos" = "linux" ] ; then
       COMP_FLAGS="$COMP_FLAGS -m64"
       LINK_FLAGS="$LINK_FLAGS -m64"
     fi
     mycpu="powerpc64" ;;
-  *power*|*ppc* ) 
+  *power*|*ppc* )
     mycpu="powerpc" ;;
-  *mips* ) 
+  *mips* )
     mycpu="mips" ;;
   *arm*|*armv6l* )
     mycpu="arm" ;;
-  *) 
+  *)
     echo 2>&1 "Error: unknown processor: $ucpu"
     exit 1
     ;;
@@ -128,7 +132,7 @@ esac
 
 case $myos in
 #  for osA in 1..c.oses.len:
-?{c.oses[osA-1]}) 
+?{c.oses[osA-1]})
   case $mycpu in
 #    for cpuA in 1..c.cpus.len:
   ?{c.cpus[cpuA-1]})
@@ -149,7 +153,7 @@ case $myos in
   esac
   ;;
 #  end for
-*) 
+*)
   echo 2>&1 "Error: no C code generated for: [$myos: $mycpu]"
   exit 1
   ;;
diff --git a/tools/niminst/deinstall.tmpl b/tools/niminst/deinstall.tmpl
index 7349abcb4..3cdfbf45d 100644
--- a/tools/niminst/deinstall.tmpl
+++ b/tools/niminst/deinstall.tmpl
@@ -1,5 +1,5 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateDeinstallScript(c: ConfigData): string = 
+#proc generateDeinstallScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated by niminst\n"
 #  var proj = c.name.toLower
 
@@ -12,7 +12,7 @@ if [ $# -eq 1 ] ; then
       echo "  /usr/bin"
       echo "  /usr/local/bin"
       echo "  /opt"
-      echo "  <some other dir> (treated like '/opt')"
+      echo "  <some other dir> (treated similar '/opt')"
       exit 1
       ;;
     "/usr/bin")
@@ -21,6 +21,7 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/lib/?proj
       docdir=/usr/share/?proj/doc
       datadir=/usr/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
       ;;
     "/usr/local/bin")
       bindir=/usr/local/bin
@@ -28,6 +29,15 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/local/lib/?proj
       docdir=/usr/local/share/?proj/doc
       datadir=/usr/local/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
+      ;;
+    "/opt")
+      bindir="/opt/?proj/bin"
+      configdir="/opt/?proj/config"
+      libdir="/opt/?proj/lib"
+      docdir="/opt/?proj/doc"
+      datadir="/opt/?proj/data"
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
       ;;
     *)
       bindir="$1/?proj/bin"
@@ -35,6 +45,7 @@ if [ $# -eq 1 ] ; then
       libdir="$1/?proj/lib"
       docdir="$1/?proj/doc"
       datadir="$1/?proj/data"
+      nimbleDir="$1/?proj"
       ;;
   esac
   echo "removing files..."
@@ -43,7 +54,7 @@ if [ $# -eq 1 ] ; then
   #let f = ff.toUnix
   rm -f $bindir/?f.skipRoot
 #end for
-#for ff in items(c.cat[fcConfig]): 
+#for ff in items(c.cat[fcConfig]):
   #let f = ff.toUnix
   rm -f $configdir/?f.skipRoot
 #end for
@@ -51,6 +62,12 @@ if [ $# -eq 1 ] ; then
   rm -rf $datadir
   rm -rf $libdir
 
+  ## Nimble pkg stuff
+  #for f in items(c.cat[fcNimble]):
+    rm -f $nimbleDir/?f.toUnix
+  #end for
+  rm -f $nimbleDir/?{c.nimblePkgName}.nimble
+
   echo "deinstallation successful"
 else
   echo "?c.displayName deinstallation script"
@@ -59,6 +76,6 @@ else
   echo "  /usr/bin"
   echo "  /usr/local/bin"
   echo "  /opt"
-  echo "  <some other dir> (treated like '/opt')"
+  echo "  <some other dir> (treated similar '/opt')"
   exit 1
 fi
diff --git a/tools/niminst/install.tmpl b/tools/niminst/install.tmpl
index 14d88e07d..3f17840a8 100644
--- a/tools/niminst/install.tmpl
+++ b/tools/niminst/install.tmpl
@@ -1,14 +1,42 @@
 #? stdtmpl(subsChar = '?') | standard
-#proc generateInstallScript(c: ConfigData): string = 
+#proc generateInstallScript(c: ConfigData): string =
 #  result = "#! /bin/sh\n# Generated by niminst\n"
 #  var proj = c.name.toLower
 
-set -e
+## Current directory you start script from
+BASE_DIR=$(pwd)
+
+## The following one-liner takes directory path which contains install script.
+## `command -v -- "$0"` takes path if script sourced from interactive shell
+## `dirname` returns relative directory path to install script
+## `cd -P` dive into directory to use `pwd`
+## `pwd -P` prints full path to install script directory path
+## -P option allows to use symlinks in path
+## Good explanation can be found here:
+## http://stackoverflow.com/questions/29832037/how-to-get-script-directory-in-posix-sh
+NIM_DIR=$(cd -P -- "$(dirname -- "$(command -v -- "$0")")" && pwd -P)
+
+go_back() {
+  cd $BASE_DIR
+}
+
+## Go to base dir on exit
+trap go_back EXIT
+
+install_error() {
+  echo "Nim installation failed!"
+  exit 1
+}
+
+## Exit if any command failed
+trap install_error ERR ## `set -e` alternative
+
+cd $NIM_DIR
 
 if [ $# -eq 1 ] ; then
 # if c.cat[fcUnixBin].len > 0:
   if test -f ?{c.cat[fcUnixBin][0].toUnix}
-  then 
+  then
     echo "?c.displayName build detected"
   else
     echo "Please build ?c.displayName before installing it"
@@ -23,7 +51,7 @@ if [ $# -eq 1 ] ; then
       echo "  /usr/bin"
       echo "  /usr/local/bin"
       echo "  /opt"
-      echo "  <some other dir> (treated like '/opt')"
+      echo "  <some other dir> (treated similar to '/opt')"
       echo "To deinstall, use the command:"
       echo "sh deinstall.sh DIR"
       exit 1
@@ -34,6 +62,7 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/lib/?proj
       docdir=/usr/share/?proj/doc
       datadir=/usr/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
       ;;
     "/usr/local/bin")
       bindir=/usr/local/bin
@@ -41,6 +70,18 @@ if [ $# -eq 1 ] ; then
       libdir=/usr/local/lib/?proj
       docdir=/usr/local/share/?proj/doc
       datadir=/usr/local/share/?proj/data
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
+      ;;
+    "/opt")
+      bindir="/opt/?proj/bin"
+      configdir="/opt/?proj/config"
+      libdir="/opt/?proj/lib"
+      docdir="/opt/?proj/doc"
+      datadir="/opt/?proj/data"
+      nimbleDir="/opt/nimble/pkgs/?c.nimblePkgName-?c.version"
+      mkdir -p /opt/?proj
+      mkdir -p $bindir
+      mkdir -p $configdir
       ;;
     *)
       bindir="$1/?proj/bin"
@@ -48,25 +89,29 @@ if [ $# -eq 1 ] ; then
       libdir="$1/?proj/lib"
       docdir="$1/?proj/doc"
       datadir="$1/?proj/data"
-      
+      nimbleDir="$1/?proj"
       mkdir -p $1/?proj
       mkdir -p $bindir
       mkdir -p $configdir
       ;;
   esac
+
   mkdir -p $libdir
   mkdir -p $docdir
+  mkdir -p $nimbleDir/
   echo "copying files..."
 #var createdDirs = newStringTable()
-#for cat in fcConfig..fcLib:
+#for cat in {fcConfig..fcLib, fcNimble}:
 #  for f in items(c.cat[cat]):
 #    var mk = splitFile(f.skipRoot).dir
-#    if mk.len > 0:
+#    if cat != fcNimble:
 #      mk = unixDirVars[cat] & "/" & mk
-#      if not createdDirs.hasKey(mk):
-#        createdDirs[mk] = "true"
+#    else:
+#      mk = "$nimbleDir" / splitFile(f).dir
+#    end if
+#    if mk.len > 0 and not createdDirs.hasKey(mk):
+#      createdDirs[mk] = "true"
   mkdir -p ?{mk.toUnix}
-#      end if
 #    end if
 #  end for
 #end for
@@ -75,11 +120,11 @@ if [ $# -eq 1 ] ; then
   cp ?f.toUnix $bindir/?f.skipRoot.toUnix
   chmod 755 $bindir/?f.skipRoot.toUnix
 #end for
-#for f in items(c.cat[fcConfig]): 
+#for f in items(c.cat[fcConfig]):
   cp ?f.toUnix $configdir/?f.skipRoot.toUnix
   chmod 644 $configdir/?f.skipRoot.toUnix
 #end for
-#for f in items(c.cat[fcData]): 
+#for f in items(c.cat[fcData]):
   if [ -f ?f.toUnix ]; then
     cp ?f.toUnix $datadir/?f.skipRoot.toUnix
     chmod 644 $datadir/?f.skipRoot.toUnix
@@ -95,7 +140,13 @@ if [ $# -eq 1 ] ; then
   cp ?f.toUnix $libdir/?f.skipRoot.toUnix
   chmod 644 $libdir/?f.skipRoot.toUnix
 #end for
-  
+#for f in items(c.cat[fcNimble]):
+  cp ?f.toUnix $nimbleDir/?f.toUnix
+  chmod 644 $nimbleDir/?f.toUnix
+#end for
+cp ?{c.nimblePkgName}.nimble $nimbleDir/?{c.nimblePkgName}.nimble
+chmod 644 $nimbleDir/?{c.nimblePkgName}.nimble
+
   echo "installation successful"
 else
   echo "?c.displayName installation script"
@@ -104,7 +155,7 @@ else
   echo "  /usr/bin"
   echo "  /usr/local/bin"
   echo "  /opt"
-  echo "  <some other dir> (treated like '/opt')"
+  echo "  <some other dir> (treated similar to '/opt')"
   echo "To deinstall, use the command:"
   echo "sh deinstall.sh DIR"
   exit 1
diff --git a/tools/niminst/makefile.tmpl b/tools/niminst/makefile.tmpl
index 6615ddc02..5c95ccda9 100644
--- a/tools/niminst/makefile.tmpl
+++ b/tools/niminst/makefile.tmpl
@@ -1,13 +1,13 @@
 #? stdtmpl(subsChar='?') | standard
-#proc generateMakefile(c: ConfigData): string = 
+#proc generateMakefile(c: ConfigData): string =
 #  result = "# Generated from niminst\n" &
 #           "# Template is in tools/niminst/makefile.tmpl\n" &
 #           "# To regenerate run ``niminst csource`` or ``koch csource``\n"
 
 CC = gcc
 LINKER = gcc
-COMP_FLAGS = ?{c.ccompiler.flags}
-LINK_FLAGS = ?{c.linker.flags}
+COMP_FLAGS = $(CPPFLAGS) $(CFLAGS) ?{c.ccompiler.flags}
+LINK_FLAGS = $(LDFLAGS) ?{c.linker.flags}
 binDir = ?{firstBinPath(c).toUnix}
 
 koch := $(shell sh -c 'test -s ../koch.nim && echo "yes"')
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim
index d1216701f..4c8dfcddf 100644
--- a/tools/niminst/niminst.nim
+++ b/tools/niminst/niminst.nim
@@ -18,7 +18,7 @@ import
 
 const
   maxOS = 20 # max number of OSes
-  maxCPU = 10 # max number of CPUs
+  maxCPU = 20 # max number of CPUs
   buildShFile = "build.sh"
   buildBatFile32 = "build.bat"
   buildBatFile64 = "build64.bat"
@@ -48,7 +48,8 @@ type
     fcWindows,    # files only for Windows
     fcUnix,       # files only for Unix; must be after ``fcWindows``
     fcUnixBin,    # binaries for Unix
-    fcDocStart    # links to documentation for Windows installer
+    fcDocStart,   # links to documentation for Windows installer
+    fcNimble      # nimble package files to copy to /opt/nimble/pkgs/pkg-ver
 
   ConfigData = object of RootObj
     actions: set[Action]
@@ -65,6 +66,7 @@ type
     app: AppType
     nimArgs: string
     debOpts: TDebOptions
+    nimblePkgName: string
 
 const
   unixDirVars: array[fcConfig..fcLib, string] = [
@@ -200,22 +202,63 @@ proc parseCmdLine(c: var ConfigData) =
   if c.infile.len == 0: quit(Usage)
   if c.mainfile.len == 0: c.mainfile = changeFileExt(c.infile, "nim")
 
-proc walkDirRecursively(s: var seq[string], root: string) =
+proc eqT(a, b: string; t: proc (a: char): char{.nimcall.}): bool =
+  ## equality under a transformation ``t``. candidate for the stdlib?
+  var i = 0
+  var j = 0
+  while i < a.len and j < b.len:
+    let aa = t a[i]
+    let bb = t b[j]
+    if aa == '\0':
+      inc i
+      if bb == '\0': inc j
+    elif bb == '\0': inc j
+    else:
+      if aa != bb: return false
+      inc i
+      inc j
+  result = i >= a.len and j >= b.len
+
+proc tPath(c: char): char =
+  if c == '\\': '/'
+  else: c
+
+proc ignoreFile(f, explicit: string, allowHtml: bool): bool =
+  let (_, name, ext) = splitFile(f)
+  let html = if not allowHtml: ".html" else: ""
+  result = (ext in ["", ".exe", ".idx", ".o", ".obj", ".dylib"] or
+            ext == html or name[0] == '.') and not eqT(f, explicit, tPath)
+
+proc walkDirRecursively(s: var seq[string], root, explicit: string,
+                        allowHtml: bool) =
+  let tail = splitPath(root).tail
+  if tail == "nimcache" or tail[0] == '.':
+    return
+  let allowHtml = allowHtml or tail == "doc"
   for k, f in walkDir(root):
-    case k
-    of pcFile, pcLinkToFile: add(s, unixToNativePath(f))
-    of pcDir: walkDirRecursively(s, f)
-    of pcLinkToDir: discard
+    if f[0] == '.' and root[0] != '.':
+      discard "skip .git directories etc"
+    else:
+      case k
+      of pcFile, pcLinkToFile:
+        if not ignoreFile(f, explicit, allowHtml):
+          add(s, unixToNativePath(f))
+      of pcDir:
+        walkDirRecursively(s, f, explicit, allowHtml)
+      of pcLinkToDir: discard
 
 proc addFiles(s: var seq[string], patterns: seq[string]) =
   for p in items(patterns):
     if existsDir(p):
-      walkDirRecursively(s, p)
+      walkDirRecursively(s, p, p, false)
     else:
       var i = 0
-      for f in walkFiles(p):
-        add(s, unixToNativePath(f))
-        inc(i)
+      for f in walkPattern(p):
+        if existsDir(f):
+          walkDirRecursively(s, f, p, false)
+        elif not ignoreFile(f, p, false):
+          add(s, unixToNativePath(f))
+          inc(i)
       if i == 0: echo("[Warning] No file found that matches: " & p)
 
 proc pathFlags(p: var CfgParser, k, v: string,
@@ -362,6 +405,14 @@ proc parseIniFile(c: var ConfigData) =
                 else: file.add(v[i])
               inc(i)
           else: quit(errorStr(p, "unknown variable: " & k.key))
+        of "nimble":
+          case normalize(k.key)
+          of "pkgname":
+            c.nimblePkgName = v
+          of "pkgfiles":
+            addFiles(c.cat[fcNimble], split(v, {';'}))
+          else:
+            quit(errorStr(p, "invalid key: " & k.key))
         else: quit(errorStr(p, "invalid section: " & section))
 
       of cfgOption: quit(errorStr(p, "syntax error"))
@@ -554,8 +605,13 @@ when haveZipLib:
           for k, f in walkDir("build" / dir):
             if k == pcFile: addFile(z, proj / dir / extractFilename(f), f)
 
-      for cat in items({fcConfig..fcOther, fcUnix}):
+      for cat in items({fcConfig..fcOther, fcUnix, fcNimble}):
         for f in items(c.cat[cat]): addFile(z, proj / f, f)
+
+      # Copy the .nimble file over
+      let nimbleFile = c.nimblePkgName & ".nimble"
+      processFile(z, proj / nimbleFile, nimbleFile)
+
       close(z)
     else:
       quit("Cannot open for writing: " & n)
@@ -587,16 +643,24 @@ proc xzDist(c: var ConfigData) =
       for k, f in walkDir("build" / dir):
         if k == pcFile: processFile(z, proj / dir / extractFilename(f), f)
 
-  for cat in items({fcConfig..fcOther, fcUnix}):
+  for cat in items({fcConfig..fcOther, fcUnix, fcNimble}):
+    echo("Current category: ", cat)
     for f in items(c.cat[cat]): processFile(z, proj / f, f)
 
-  let oldDir = getCurrentDir()
-  setCurrentDir(tmpDir)
-  try:
-    if execShellCmd("XZ_OPT=-9 tar Jcf $1.tar.xz $1" % proj) != 0:
-      echo("External program failed")
-  finally:
-    setCurrentDir(oldDir)
+  # Copy the .nimble file over
+  let nimbleFile = c.nimblePkgName & ".nimble"
+  processFile(z, proj / nimbleFile, nimbleFile)
+
+  when true:
+    let oldDir = getCurrentDir()
+    setCurrentDir(tmpDir)
+    try:
+      if execShellCmd("XZ_OPT=-9 gtar Jcf $1.tar.xz $1 --exclude=.DS_Store" % proj) != 0:
+        # try old 'tar' without --exclude feature:
+        if execShellCmd("XZ_OPT=-9 tar Jcf $1.tar.xz $1" % proj) != 0:
+          echo("External program failed")
+    finally:
+      setCurrentDir(oldDir)
 
 # -- prepare build files for .deb creation
 
diff --git a/tools/niminst/nsis.tmpl b/tools/niminst/nsis.tmpl
index abf462388..0897d36a8 100644
--- a/tools/niminst/nsis.tmpl
+++ b/tools/niminst/nsis.tmpl
@@ -35,7 +35,7 @@
 
   ; Default installation folder
   ; This is changed later (in .onInit) to the root directory, if possible.
-  InstallDir "$LOCALAPPDATA\?{c.name}-?{c.version}"
+  InstallDir "$PROGRAMFILES?{when sizeof(int) == 8: "64" else: ""}\?{c.name}-?{c.version}"
 
   ; Get installation folder from registry if available
   InstallDirRegKey HKCU "Software\c.name\c.version" ""