diff options
Diffstat (limited to 'tools/niminst/niminst.nim')
-rw-r--r-- | tools/niminst/niminst.nim | 202 |
1 files changed, 95 insertions, 107 deletions
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index e2cc8cf3a..40ee79814 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -7,15 +7,16 @@ # distribution, for details about the copyright. # -const - haveZipLib = false # zip not in stdlib anymore +import + os, strutils, parseopt, parsecfg, strtabs, streams, debcreation -when haveZipLib: - import zipfiles +import ../../dist/checksums/src/checksums/sha1 -import - os, osproc, strutils, parseopt, parsecfg, strtabs, streams, debcreation, - std / sha1 +when defined(nimPreviewSlimSystem): + import std/syncio + +when not defined(nimHasEffectsOf): + {.pragma: effectsOf.} const maxOS = 20 # max number of OSes @@ -36,7 +37,7 @@ type actionInno, # action: create Inno Setup installer actionNsis, # action: create NSIS installer actionScripts # action: create install and deinstall scripts - actionZip, # action: create zip file + actionZip # action: create zip file actionXz, # action: create xz file actionDeb # action: prepare deb package @@ -75,7 +76,7 @@ const "$configdir", "$datadir", "$docdir", "$libdir" ] -proc iniConfigData(c: var ConfigData) = +func iniConfigData(c: var ConfigData) = c.actions = {} for i in low(FileCategory)..high(FileCategory): c.cat[i] = @[] c.binPaths = @[] @@ -107,17 +108,17 @@ proc iniConfigData(c: var ConfigData) = c.debOpts.shortDesc = "" c.debOpts.licenses = @[] -proc firstBinPath(c: ConfigData): string = +func firstBinPath(c: ConfigData): string = if c.binPaths.len > 0: result = c.binPaths[0] else: result = "" -proc `\`(a, b: string): string = +func `\`(a, b: string): string = result = if a.len == 0: b else: a & '\\' & b template toUnix(s: string): string = s.replace('\\', '/') template toWin(s: string): string = s.replace('/', '\\') -proc skipRoot(f: string): string = +func skipRoot(f: string): string = # "abc/def/xyz" --> "def/xyz" var i = 0 result = "" @@ -126,13 +127,13 @@ proc skipRoot(f: string): string = inc i if result.len == 0: result = f -include "inno.tmpl" -include "nsis.tmpl" -include "buildsh.tmpl" -include "makefile.tmpl" -include "buildbat.tmpl" -include "install.tmpl" -include "deinstall.tmpl" +include "inno.nimf" +include "nsis.nimf" +include "buildsh.nimf" +include "makefile.nimf" +include "buildbat.nimf" +include "install.nimf" +include "deinstall.nimf" # ------------------------- configuration file ------------------------------- @@ -167,11 +168,11 @@ proc parseCmdLine(c: var ConfigData) = next(p) var kind = p.kind var key = p.key - var val = p.val.string + var val = p.val case kind of cmdArgument: if c.actions == {}: - for a in split(normalize(key.string), {';', ','}): + for a in split(normalize(key), {';', ','}): case a of "csource": incl(c.actions, actionCSource) of "scripts": incl(c.actions, actionScripts) @@ -182,11 +183,11 @@ proc parseCmdLine(c: var ConfigData) = of "deb": incl(c.actions, actionDeb) else: quit(Usage) else: - c.infile = addFileExt(key.string, "ini") - c.nimArgs = cmdLineRest(p).string + c.infile = addFileExt(key, "ini") + c.nimArgs = cmdLineRest(p) break - of cmdLongoption, cmdShortOption: - case normalize(key.string) + of cmdLongOption, cmdShortOption: + case normalize(key) of "help", "h": stdout.write(Usage) quit(0) @@ -204,7 +205,7 @@ proc parseCmdLine(c: var ConfigData) = if c.infile.len == 0: quit(Usage) if c.mainfile.len == 0: c.mainfile = changeFileExt(c.infile, "nim") -proc eqT(a, b: string; t: proc (a: char): char{.nimcall.}): bool = +proc eqT(a, b: string; t: proc (a: char): char {.nimcall.}): bool {.effectsOf: t.} = ## equality under a transformation ``t``. candidate for the stdlib? var i = 0 var j = 0 @@ -221,11 +222,11 @@ proc eqT(a, b: string; t: proc (a: char): char{.nimcall.}): bool = inc j result = i >= a.len and j >= b.len -proc tPath(c: char): char = +func tPath(c: char): char = if c == '\\': '/' else: c -proc ignoreFile(f, explicit: string, allowHtml: bool): bool = +func 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 @@ -251,12 +252,12 @@ proc walkDirRecursively(s: var seq[string], root, explicit: string, proc addFiles(s: var seq[string], patterns: seq[string]) = for p in items(patterns): - if existsDir(p): + if dirExists(p): walkDirRecursively(s, p, p, false) else: var i = 0 for f in walkPattern(p): - if existsDir(f): + if dirExists(f): walkDirRecursively(s, f, p, false) elif not ignoreFile(f, p, false): add(s, unixToNativePath(f)) @@ -283,13 +284,13 @@ proc yesno(p: var CfgParser, v: string): bool = result = false else: quit(errorStr(p, "unknown value; use: yes|no")) -proc incl(s: var seq[string], x: string): int = +func incl(s: var seq[string], x: string): int = for i in 0 ..< s.len: if cmpIgnoreStyle(s[i], x) == 0: return i s.add(x) result = s.len-1 -proc platforms(c: var ConfigData, v: string) = +func platforms(c: var ConfigData, v: string) = for line in splitLines(v): let p = line.find(": ") if p <= 1: continue @@ -462,10 +463,10 @@ proc readCFiles(c: var ConfigData, osA, cpuA: int) = else: quit("Cannot open: " & f) -proc buildDir(os, cpu: int): string = - return "c_code" / ($os & "_" & $cpu) +func buildDir(os, cpu: int): string = + "c_code" / ($os & "_" & $cpu) -proc getOutputDir(c: var ConfigData): string = +func getOutputDir(c: var ConfigData): string = if c.outdir.len > 0: c.outdir else: "build" proc writeFile(filename, content, newline: string) = @@ -483,7 +484,6 @@ proc deduplicateFiles(c: var ConfigData) = let build = getOutputDir(c) for osA in countup(1, c.oses.len): for cpuA in countup(1, c.cpus.len): - if c.cfiles[osA][cpuA].isNil: c.cfiles[osA][cpuA] = @[] if c.explicitPlatforms and not c.platforms[osA][cpuA]: continue for dup in mitems(c.cfiles[osA][cpuA]): let key = $secureHashFile(build / dup) @@ -504,12 +504,32 @@ proc writeInstallScripts(c: var ConfigData) = writeFile(deinstallShFile, generateDeinstallScript(c), "\10") inclFilePermissions(deinstallShFile, {fpUserExec, fpGroupExec, fpOthersExec}) +template gatherFiles(fun, libpath, outDir) = + block: + template copySrc(src) = + let dst = outDir / extractFilename(src) + when false: echo (dst, dst) + fun(src, dst) + + for f in walkFiles(libpath / "lib/*.h"): copySrc(f) + # commenting out for now, see discussion in https://github.com/nim-lang/Nim/pull/13413 + # copySrc(libpath / "lib/wrappers/linenoise/linenoise.h") + +proc exe(f: string): string = + result = addFileExt(f, ExeExt) + when defined(windows): + result = result.replace('/','\\') + +proc findNim(): string = + let nim = "nim".exe + result = quoteShell("bin" / nim) + if not fileExists(result): + result = "nim" + proc srcdist(c: var ConfigData) = - if not existsDir(getOutputDir(c) / "c_code"): - createDir(getOutputDir(c) / "c_code") - for x in walkFiles(c.libpath / "lib/*.h"): - when false: echo(getOutputDir(c) / "c_code" / extractFilename(x)) - copyFile(dest=getOutputDir(c) / "c_code" / extractFilename(x), source=x) + let cCodeDir = getOutputDir(c) / "c_code" + if not dirExists(cCodeDir): createDir(cCodeDir) + gatherFiles(copyFile, c.libpath, cCodeDir) var winIndex = -1 var intel32Index = -1 var intel64Index = -1 @@ -522,12 +542,12 @@ proc srcdist(c: var ConfigData) = if cpuname.cmpIgnoreStyle("i386") == 0: intel32Index = cpuA elif cpuname.cmpIgnoreStyle("amd64") == 0: intel64Index = cpuA var dir = getOutputDir(c) / buildDir(osA, cpuA) - if existsDir(dir): removeDir(dir) + if dirExists(dir): removeDir(dir) createDir(dir) - var cmd = ("nim compile -f --symbolfiles:off --compileonly " & + var cmd = ("$# compile -f --incremental:off --compileonly " & "--gen_mapping --cc:gcc --skipUserCfg" & " --os:$# --cpu:$# $# $#") % - [osname, cpuname, c.nimArgs, c.mainfile] + [findNim(), osname, cpuname, c.nimArgs, c.mainfile] echo(cmd) if execShellCmd(cmd) != 0: quit("Error: call to nim compiler failed") @@ -586,41 +606,6 @@ proc setupDist2(c: var ConfigData) = else: quit("External program failed") -# ------------------ generate ZIP file --------------------------------------- -when haveZipLib: - proc zipDist(c: var ConfigData) = - var proj = toLowerAscii(c.name) & "-" & c.version - var n = "$#.zip" % proj - if c.outdir.len == 0: n = "build" / n - else: n = c.outdir / n - var z: ZipArchive - if open(z, n, fmWrite): - addFile(z, proj / buildBatFile, "build" / buildBatFile) - addFile(z, proj / buildBatFile32, "build" / buildBatFile32) - addFile(z, proj / buildBatFile64, "build" / buildBatFile64) - addFile(z, proj / buildShFile, "build" / buildShFile) - addFile(z, proj / makeFile, "build" / makeFile) - addFile(z, proj / installShFile, installShFile) - addFile(z, proj / deinstallShFile, deinstallShFile) - for f in walkFiles(c.libpath / "lib/*.h"): - addFile(z, proj / "c_code" / extractFilename(f), f) - for osA in 1..c.oses.len: - for cpuA in 1..c.cpus.len: - var dir = buildDir(osA, cpuA) - for k, f in walkDir("build" / dir): - if k == pcFile: addFile(z, proj / dir / extractFilename(f), f) - - 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) - proc xzDist(c: var ConfigData; windowsZip=false) = let proj = toLowerAscii(c.name) & "-" & c.version let tmpDir = if c.outdir.len == 0: "build" else: c.outdir @@ -628,15 +613,15 @@ proc xzDist(c: var ConfigData; windowsZip=false) = proc processFile(destFile, src: string) = let dest = tmpDir / destFile when false: echo "Copying ", src, " to ", dest - if not existsFile(src): + if not fileExists(src): echo "[Warning] Source file doesn't exist: ", src let destDir = dest.splitFile.dir if not dirExists(destDir): createDir(destDir) copyFileWithPermissions(src, dest) - if not windowsZip and not existsFile("build" / buildBatFile): + if not windowsZip and not fileExists("build" / buildBatFile): quit("No C sources found in ./build/, please build by running " & - "./koch csource -d:release.") + "./koch csource -d:danger.") if not windowsZip: processFile(proj / buildBatFile, "build" / buildBatFile) @@ -646,8 +631,8 @@ proc xzDist(c: var ConfigData; windowsZip=false) = processFile(proj / makeFile, "build" / makeFile) processFile(proj / installShFile, installShFile) processFile(proj / deinstallShFile, deinstallShFile) - for f in walkFiles(c.libpath / "lib/*.h"): - processFile(proj / "c_code" / extractFilename(f), f) + template processFileAux(src, dst) = processFile(dst, src) + gatherFiles(processFileAux, c.libpath, proj / "c_code") for osA in 1..c.oses.len: for cpuA in 1..c.cpus.len: var dir = buildDir(osA, cpuA) @@ -683,7 +668,7 @@ RunProgram="tools\downloader.exe" if execShellCmd("7z a -sfx7zS2.sfx -t7z $1.exe $1" % proj) != 0: echo("External program failed (7z)") else: - if execShellCmd("gtar cf $1.tar $1 --exclude=.DS_Store" % + if execShellCmd("gtar cf $1.tar --exclude=.DS_Store $1" % proj) != 0: # try old 'tar' without --exclude feature: if execShellCmd("tar cf $1.tar $1" % proj) != 0: @@ -697,8 +682,8 @@ RunProgram="tools\downloader.exe" # -- prepare build files for .deb creation proc debDist(c: var ConfigData) = - if not existsFile(getOutputDir(c) / "build.sh"): quit("No build.sh found.") - if not existsFile(getOutputDir(c) / "install.sh"): quit("No install.sh found.") + if not fileExists(getOutputDir(c) / "build.sh"): quit("No build.sh found.") + if not fileExists(getOutputDir(c) / "install.sh"): quit("No install.sh found.") if c.debOpts.shortDesc == "": quit("shortDesc must be set in the .ini file.") if c.debOpts.licenses.len == 0: @@ -721,8 +706,7 @@ proc debDist(c: var ConfigData) = copyNimDist(makeFile, makeFile) copyNimDist(installShFile, installShFile) createDir(workingDir / upstreamSource / "build") - for f in walkFiles(c.libpath / "lib/*.h"): - copyNimDist(f, "build" / extractFilename(f)) + gatherFiles(copyNimDist, c.libpath, "build") for osA in 1..c.oses.len: for cpuA in 1..c.cpus.len: var dir = buildDir(osA, cpuA) @@ -743,21 +727,25 @@ proc debDist(c: var ConfigData) = # ------------------- main ---------------------------------------------------- -var c: ConfigData -iniConfigData(c) -parseCmdLine(c) -parseIniFile(c) -if actionInno in c.actions: - setupDist(c) -if actionNsis in c.actions: - setupDist2(c) -if actionCSource in c.actions: - srcdist(c) -if actionScripts in c.actions: - writeInstallScripts(c) -if actionZip in c.actions: - xzDist(c, true) -if actionXz in c.actions: - xzDist(c) -if actionDeb in c.actions: - debDist(c) +proc main() = + var c: ConfigData + iniConfigData(c) + parseCmdLine(c) + parseIniFile(c) + if actionInno in c.actions: + setupDist(c) + if actionNsis in c.actions: + setupDist2(c) + if actionCSource in c.actions: + srcdist(c) + if actionScripts in c.actions: + writeInstallScripts(c) + if actionZip in c.actions: + xzDist(c, true) + if actionXz in c.actions: + xzDist(c) + if actionDeb in c.actions: + debDist(c) + +when isMainModule: + main() |