diff options
Diffstat (limited to 'tools/niminst')
-rw-r--r-- | tools/niminst/buildsh.tmpl | 44 | ||||
-rw-r--r-- | tools/niminst/deinstall.tmpl | 25 | ||||
-rw-r--r-- | tools/niminst/install.tmpl | 79 | ||||
-rw-r--r-- | tools/niminst/makefile.tmpl | 6 | ||||
-rw-r--r-- | tools/niminst/niminst.nim | 104 | ||||
-rw-r--r-- | tools/niminst/nsis.tmpl | 2 |
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" "" |