Skip to content

Instantly share code, notes, and snippets.

@lbmn
Created June 12, 2017 01:04
Show Gist options
  • Save lbmn/ce65093a2d10dcd47be84bb4652bacfd to your computer and use it in GitHub Desktop.
Save lbmn/ce65093a2d10dcd47be84bb4652bacfd to your computer and use it in GitHub Desktop.
import
os, osproc, times, tables, strutils, strtabs,
al_term, al_str, birthcert
let
srcDir = getEnv("NIMR_SRC")
binDir = getEnv("NIMR_BIN")
var
startTime = epochTime()
nimOpt = initTable[string,string]()
proc test() =
if paramCount() < 1: die "At least one argument required!"
if srcDir == "": die "NIMR_SRC environmental variable blank!"
if binDir == "": die "NIMR_BIN environmental variable blank!"
if not dirExists(srcDir): die "NIMR_SRC directory doesn't exist!"
if not dirExists(binDir): die "NIMR_BIN directory doesn't exist!"
if findExe("nim") == "": die "Required executable `nim` not found!"
proc findSourceFile(cmd: string): string =
var baseFilename = cmd.changeFileExt("nim")
var fullPath = joinPath(getCurrentDir(), baseFilename)
if fileExists(fullPath): return fullPath
for eachFile in walkDirRec(srcDir):
let eachBaseFn = eachFile.splitPath().tail
if baseFilename == eachBaseFn: return eachFile.expandFilename
die "Cannot find source code for command '$1'" % [cmd]
proc procSetOptions(srcFile: string) =
# Set options based on executable (or link name) used:
when nimCompilerOutFile == "nimf":
nimOpt["d"] = "release"
nimOpt["opt"] = "speed"
nimOpt["verbosity"] = "1"
elif nimCompilerOutFile == "nims":
nimOpt["d"] = "release"
nimOpt["opt"] = "size"
nimOpt["verbosity"] = "1"
else:
nimOpt["d"] = "debug"
nimOpt["opt"] = "none"
# Set options from directives inside the source file:
let srcHandle = open(srcFile)
defer: srcHandle.close
while not srcHandle.endOfFile:
let srcLine = srcHandle.readLine.strip
if not srcLine.startsWith("##:"): continue
let splitKeyVal = srcLine[3..^1].split("=")
if splitKeyVal.len < 2: continue
let key = splitKeyVal[0].strip
let val = splitKeyVal[1..^1].join("=").strip
nimOpt[key] = val
proc compile() =
let srcFile = findSourceFile(paramStr(1))
let srcPathSplit = splitPath(srcFile)
# if srcPathSplit.head != "":
# log "found source in: " & srcPathSplit.head
# setCurrentDir(srcPathSplit.head)
procSetOptions(srcFile)
nimOpt["out"] = binDir / srcPathSplit.tail.changeFileExt("")
var nimCmd = "nim c"
for k, v in nimOpt:
nimCmd &= " --" & k & ":" & v
nimCmd &= " " & srcFile
log "nimr running `$1`" % [nimCmd]
echo "{"
var exitCode = execCmd(nimCmd)
echo "}"
let runSec = epochTime() - startTime
let infoStr = "`nim c` completed in $1 sec, exit status $2." % [$runSec, $exitCode]
if exitCode != 0: die infoStr
else: grn infoStr
proc run() =
var runCmd = " " & nimOpt["out"]
for argN in 2..paramCount():
runCmd &= " " & paramStr(argN)
#log "nimr running `$1`" % [runCmd]
#echo "{"
startTime = epochTime()
let exitCode = execCmd(runCmd)
let runSec = epochTime() - startTime
#echo "}"
let infoStr = "execution completed in $1 sec, exit status $2." % [$runSec, $exitCode]
if exitCode != 0: err infoStr
#else: red infoStr
proc optimizeSize() =
startTime = epochTime()
if findExe("upx") == "":
yel "Cannot find `upx` command for further size optimization!"
return
let optCmd = "upx -9qqq --ultra-brute " & nimOpt["out"]
log "binary size: $1 bytes" % getFileSize(nimOpt["out"]).thousandsSep
grn "nimr running `$1`" % [optCmd]
#echo "{"
startTime = epochTime()
let exitCode = execCmd(optCmd)
let runSec = epochTime() - startTime
#echo "}"
let infoStr = "upx completed in $1 sec, exit status $2." % [$runSec, $exitCode]
if exitCode == 0:
grn infoStr
log "binary size: $1 bytes" % getFileSize(nimOpt["out"]).thousandsSep
else: die infoStr
when isMainModule:
test()
compile()
when nimCompilerOutFile == "nims": optimizeSize()
elif nimCompilerOutFile == "nimr": run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment