diff options
Diffstat (limited to 'tools/niminst/niminst.nim')
-rw-r--r-- | tools/niminst/niminst.nim | 90 |
1 files changed, 51 insertions, 39 deletions
diff --git a/tools/niminst/niminst.nim b/tools/niminst/niminst.nim index 9ee3eb9b9..e50b251d3 100644 --- a/tools/niminst/niminst.nim +++ b/tools/niminst/niminst.nim @@ -1,7 +1,7 @@ # # # The Nim Installation Generator -# (c) Copyright 2014 Andreas Rumpf +# (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -22,12 +22,13 @@ const buildShFile = "build.sh" buildBatFile32 = "build.bat" buildBatFile64 = "build64.bat" + makeFile = "makefile" installShFile = "install.sh" deinstallShFile = "deinstall.sh" type - TAppType = enum appConsole, appGUI - TAction = enum + AppType = enum appConsole, appGUI + Action = enum actionNone, # action not yet known actionCSource # action: create C sources actionInno, # action: create Inno Setup installer @@ -36,7 +37,7 @@ type actionZip, # action: create zip file actionDeb # action: prepare deb package - TFileCategory = enum + FileCategory = enum fcWinBin, # binaries for Windows fcConfig, # configuration files fcData, # data files @@ -48,19 +49,19 @@ type fcUnixBin, # binaries for Unix fcDocStart # links to documentation for Windows installer - TConfigData = object of TObject - actions: set[TAction] - cat: array[TFileCategory, seq[string]] + ConfigData = object of RootObj + actions: set[Action] + cat: array[FileCategory, seq[string]] binPaths, authors, oses, cpus, downloads: seq[string] cfiles: array[1..maxOS, array[1..maxCPU, seq[string]]] platforms: array[1..maxOS, array[1..maxCPU, bool]] ccompiler, linker, innosetup, nsisSetup: tuple[path, flags: string] name, displayName, version, description, license, infile, outdir: string - libpath: string + mainfile, libpath: string innoSetupFlag, installScript, uninstallScript: bool explicitPlatforms: bool - vars: PStringTable - app: TAppType + vars: StringTableRef + app: AppType nimArgs: string debOpts: TDebOptions @@ -69,9 +70,9 @@ const "$configdir", "$datadir", "$docdir", "$libdir" ] -proc initConfigData(c: var TConfigData) = +proc iniConfigData(c: var ConfigData) = c.actions = {} - for i in low(TFileCategory)..high(TFileCategory): c.cat[i] = @[] + for i in low(FileCategory)..high(FileCategory): c.cat[i] = @[] c.binPaths = @[] c.authors = @[] c.oses = @[] @@ -87,6 +88,7 @@ proc initConfigData(c: var TConfigData) = c.description = "" c.license = "" c.infile = "" + c.mainfile = "" c.outdir = "" c.nimArgs = "" c.libpath = "" @@ -100,7 +102,7 @@ proc initConfigData(c: var TConfigData) = c.debOpts.shortDesc = "" c.debOpts.licenses = @[] -proc firstBinPath(c: TConfigData): string = +proc firstBinPath(c: ConfigData): string = if c.binPaths.len > 0: result = c.binPaths[0] else: result = "" @@ -122,6 +124,7 @@ proc skipRoot(f: string): string = include "inno.tmpl" include "nsis.tmpl" include "buildsh.tmpl" +include "makefile.tmpl" include "buildbat.tmpl" include "install.tmpl" include "deinstall.tmpl" @@ -132,7 +135,7 @@ const Version = "1.0" Usage = "niminst - Nim Installation Generator Version " & Version & """ - (c) 2014 Andreas Rumpf + (c) 2015 Andreas Rumpf Usage: niminst [options] command[;command2...] ini-file[.ini] [compile_options] Command: @@ -144,6 +147,8 @@ Command: deb create files for debhelper Options: -o, --output:dir set the output directory + -m, --main:file set the main nim file, by default ini-file with .nim + extension --var:name=value set the value of a variable -h, --help shows this help -v, --version shows the version @@ -151,7 +156,7 @@ Compile_options: will be passed to the Nim compiler """ -proc parseCmdLine(c: var TConfigData) = +proc parseCmdLine(c: var ConfigData) = var p = initOptParser() while true: next(p) @@ -183,6 +188,7 @@ proc parseCmdLine(c: var TConfigData) = stdout.write(Version & "\n") quit(0) of "o", "output": c.outdir = val + of "m", "main": c.mainfile = changeFileExt(val, "nim") of "var": var idx = val.find('=') if idx < 0: quit("invalid command line") @@ -190,6 +196,7 @@ proc parseCmdLine(c: var TConfigData) = else: quit(Usage) of cmdEnd: break 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) = for k, f in walkDir(root): @@ -209,19 +216,19 @@ proc addFiles(s: var seq[string], patterns: seq[string]) = inc(i) if i == 0: echo("[Warning] No file found that matches: " & p) -proc pathFlags(p: var TCfgParser, k, v: string, +proc pathFlags(p: var CfgParser, k, v: string, t: var tuple[path, flags: string]) = case normalize(k) of "path": t.path = v of "flags": t.flags = v else: quit(errorStr(p, "unknown variable: " & k)) -proc filesOnly(p: var TCfgParser, k, v: string, dest: var seq[string]) = +proc filesOnly(p: var CfgParser, k, v: string, dest: var seq[string]) = case normalize(k) of "files": addFiles(dest, split(v, {';'})) else: quit(errorStr(p, "unknown variable: " & k)) -proc yesno(p: var TCfgParser, v: string): bool = +proc yesno(p: var CfgParser, v: string): bool = case normalize(v) of "yes", "y", "on", "true": result = true @@ -235,7 +242,7 @@ proc incl(s: var seq[string], x: string): int = s.add(x) result = s.len-1 -proc platforms(c: var TConfigData, v: string) = +proc platforms(c: var ConfigData, v: string) = for line in splitLines(v): let p = line.find(": ") if p <= 1: continue @@ -246,9 +253,9 @@ proc platforms(c: var TConfigData, v: string) = let cpuIdx = c.cpus.incl(cpu) c.platforms[c.oses.len][cpuIdx+1] = true -proc parseIniFile(c: var TConfigData) = +proc parseIniFile(c: var ConfigData) = var - p: TCfgParser + p: CfgParser section = "" hasCpuOs = false var input = newFileStream(c.infile, fmRead) @@ -358,15 +365,15 @@ proc parseIniFile(c: var TConfigData) = of cfgOption: quit(errorStr(p, "syntax error")) of cfgError: quit(errorStr(p, k.msg)) close(p) - if c.name.len == 0: c.name = changeFileExt(extractFilename(c.infile), "") + if c.name.len == 0: c.name = changeFileExt(extractFilename(c.mainfile), "") if c.displayName.len == 0: c.displayName = c.name else: quit("cannot open: " & c.infile) # ------------------------- generate source based installation --------------- -proc readCFiles(c: var TConfigData, osA, cpuA: int) = - var p: TCfgParser +proc readCFiles(c: var ConfigData, osA, cpuA: int) = + var p: CfgParser var f = splitFile(c.infile).dir / "mapping.txt" c.cfiles[osA][cpuA] = @[] var input = newFileStream(f, fmRead) @@ -402,11 +409,11 @@ proc readCFiles(c: var TConfigData, osA, cpuA: int) = proc buildDir(os, cpu: int): string = return "c_code" / ($os & "_" & $cpu) -proc getOutputDir(c: var TConfigData): string = +proc getOutputDir(c: var ConfigData): string = if c.outdir.len > 0: c.outdir else: "build" proc writeFile(filename, content, newline: string) = - var f: TFile + var f: File if open(f, filename, fmWrite): for x in splitLines(content): write(f, x) @@ -415,7 +422,7 @@ proc writeFile(filename, content, newline: string) = else: quit("Cannot open for writing: " & filename) -proc removeDuplicateFiles(c: var TConfigData) = +proc removeDuplicateFiles(c: var ConfigData) = for osA in countdown(c.oses.len, 1): for cpuA in countdown(c.cpus.len, 1): if c.cfiles[osA][cpuA].isNil: c.cfiles[osA][cpuA] = @[] @@ -433,13 +440,15 @@ proc removeDuplicateFiles(c: var TConfigData) = removeFile(dup) c.cfiles[osA][cpuA][i] = orig -proc writeInstallScripts(c: var TConfigData) = +proc writeInstallScripts(c: var ConfigData) = if c.installScript: writeFile(installShFile, generateInstallScript(c), "\10") + inclFilePermissions(installShFile, {fpUserExec, fpGroupExec, fpOthersExec}) if c.uninstallScript: writeFile(deinstallShFile, generateDeinstallScript(c), "\10") + inclFilePermissions(deinstallShFile, {fpUserExec, fpGroupExec, fpOthersExec}) -proc srcdist(c: var TConfigData) = +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"): @@ -462,8 +471,7 @@ proc srcdist(c: var TConfigData) = var cmd = ("nim compile -f --symbolfiles:off --compileonly " & "--gen_mapping --cc:gcc --skipUserCfg" & " --os:$# --cpu:$# $# $#") % - [osname, cpuname, c.nimArgs, - changeFileExt(c.infile, "nim")] + [osname, cpuname, c.nimArgs, c.mainfile] echo(cmd) if execShellCmd(cmd) != 0: quit("Error: call to nim compiler failed") @@ -476,6 +484,8 @@ proc srcdist(c: var TConfigData) = # second pass: remove duplicate files removeDuplicateFiles(c) writeFile(getOutputDir(c) / buildShFile, generateBuildShellScript(c), "\10") + inclFilePermissions(getOutputDir(c) / buildShFile, {fpUserExec, fpGroupExec, fpOthersExec}) + writeFile(getOutputDir(c) / makeFile, generateMakefile(c), "\10") if winIndex >= 0: if intel32Index >= 0: writeFile(getOutputDir(c) / buildBatFile32, @@ -486,7 +496,7 @@ proc srcdist(c: var TConfigData) = writeInstallScripts(c) # --------------------- generate inno setup ----------------------------------- -proc setupDist(c: var TConfigData) = +proc setupDist(c: var ConfigData) = let scrpt = generateInnoSetup(c) let n = "build" / "install_$#_$#.iss" % [toLower(c.name), c.version] writeFile(n, scrpt, "\13\10") @@ -503,7 +513,7 @@ proc setupDist(c: var TConfigData) = quit("External program failed") # --------------------- generate NSIS setup ----------------------------------- -proc setupDist2(c: var TConfigData) = +proc setupDist2(c: var ConfigData) = let scrpt = generateNsisSetup(c) let n = "build" / "install_$#_$#.nsi" % [toLower(c.name), c.version] writeFile(n, scrpt, "\13\10") @@ -521,9 +531,9 @@ proc setupDist2(c: var TConfigData) = # ------------------ generate ZIP file --------------------------------------- when haveZipLib: - proc zipDist(c: var TConfigData) = - var proj = toLower(c.name) - var n = "$#_$#.zip" % [proj, c.version] + proc zipDist(c: var ConfigData) = + var proj = toLower(c.name) & "-" & c.version + var n = "$#.zip" % proj if c.outdir.len == 0: n = "build" / n else: n = c.outdir / n var z: TZipArchive @@ -531,6 +541,7 @@ when haveZipLib: 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"): @@ -549,7 +560,7 @@ when haveZipLib: # -- prepare build files for .deb creation -proc debDist(c: var TConfigData) = +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.") @@ -571,6 +582,7 @@ proc debDist(c: var TConfigData) = # Don't copy all files, only the ones specified in the config: copyNimDist(buildShFile, buildShFile) + copyNimDist(makeFile, makeFile) copyNimDist(installShFile, installShFile) createDir(workingDir / upstreamSource / "build") for f in walkFiles(c.libpath / "lib/*.h"): @@ -595,8 +607,8 @@ proc debDist(c: var TConfigData) = # ------------------- main ---------------------------------------------------- -var c: TConfigData -initConfigData(c) +var c: ConfigData +iniConfigData(c) parseCmdLine(c) parseIniFile(c) if actionInno in c.actions: |