new cmd: nim r main [args...] to compile & run, saving binary under $nimcache/main (#13382)

* implement `nim r main` to compile and run, saving binary to $nimcache
* remove outFileAbs for now
This commit is contained in:
Timothee Cour
2020-04-23 01:02:18 -07:00
committed by GitHub
parent 4b43d42b98
commit 5c534b2943
5 changed files with 39 additions and 16 deletions

View File

@@ -75,6 +75,17 @@
- Specific warnings can now be turned into errors via `--warningAsError[X]:on|off`.
- The `define` and `undef` pragmas have been de-deprecated.
- New command: `nim r main.nim [args...]` which compiles and runs main.nim, saving
the binary to $nimcache/main$exeExt, using the same logic as `nim c -r` to
avoid recompiling when sources don't change. This is now the preferred way to
run tests, avoiding the usual pain of clobbering your repo with binaries or
using tricky gitignore rules on posix. Example:
```nim
nim r compiler/nim.nim --help # only compiled the first time
echo 'import os; echo getCurrentCompilerExe()' | nim r - # this works too
nim r compiler/nim.nim --fullhelp # no recompilation
nim r --nimcache:/tmp main # binary saved to /tmp/main
```
## Tool changes

View File

@@ -66,16 +66,22 @@ when not defined(leanCompiler):
compileProject(graph)
finishDoc2Pass(graph.config.projectName)
proc setOutDir(conf: ConfigRef) =
if conf.outDir.isEmpty:
if optUseNimcache in conf.globalOptions:
conf.outDir = getNimcacheDir(conf)
else:
conf.outDir = conf.projectPath
proc commandCompileToC(graph: ModuleGraph) =
let conf = graph.config
if conf.outDir.isEmpty:
conf.outDir = conf.projectPath
setOutDir(conf)
if conf.outFile.isEmpty:
let base = conf.projectName
let targetName = if optGenDynLib in conf.globalOptions:
platform.OS[conf.target.targetOS].dllFrmt % conf.projectName
platform.OS[conf.target.targetOS].dllFrmt % base
else:
conf.projectName & platform.OS[conf.target.targetOS].exeExt
base & platform.OS[conf.target.targetOS].exeExt
conf.outFile = RelativeFile targetName
extccomp.initVars(conf)
@@ -181,13 +187,13 @@ proc mainCommand*(graph: ModuleGraph) =
conf.lastCmdTime = epochTime()
conf.searchPaths.add(conf.libpath)
setId(100)
case conf.command.normalize
of "c", "cc", "compile", "compiletoc":
# compile means compileToC currently
template handleC() =
conf.cmd = cmdCompileToC
if conf.exc == excNone: conf.exc = excSetjmp
defineSymbol(graph.config.symbols, "c")
commandCompileToC(graph)
case conf.command.normalize
of "c", "cc", "compile", "compiletoc": handleC() # compile means compileToC currently
of "cpp", "compiletocpp":
conf.cmd = cmdCompileToCpp
if conf.exc == excNone: conf.exc = excCpp
@@ -197,6 +203,9 @@ proc mainCommand*(graph: ModuleGraph) =
conf.cmd = cmdCompileToOC
defineSymbol(graph.config.symbols, "objc")
commandCompileToC(graph)
of "r": # different from `"run"`!
conf.globalOptions.incl {optRun, optUseNimcache}
handleC()
of "run":
conf.cmd = cmdRun
when hasTinyCBackend:

View File

@@ -63,7 +63,7 @@ proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) =
if processArgument(pass, p, argsCount, config): break
if pass == passCmd2:
if {optRun, optWasNimscript} * config.globalOptions == {} and
config.arguments.len > 0 and config.command.normalize notin ["run", "e"]:
config.arguments.len > 0 and config.command.normalize notin ["run", "e", "r"]:
rawMessage(config, errGenerated, errArgsNeedRunOption)
proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =

View File

@@ -57,6 +57,7 @@ type # please make sure we have under 32 options
optGenScript, # generate a script file to compile the *.c files
optGenMapping, # generate a mapping file
optRun, # run the compiled project
optUseNimcache, # save artifacts (including binary) in $nimcache
optStyleHint, # check that the names adhere to NEP-1
optStyleError, # enforce that the names adhere to NEP-1
optSkipSystemConfigFile, # skip the system's cfg/nims config file
@@ -524,18 +525,19 @@ proc getOutFile*(conf: ConfigRef; filename: RelativeFile, ext: string): Absolute
conf.outDir / changeFileExt(filename, ext)
proc absOutFile*(conf: ConfigRef): AbsoluteFile =
if false:
doAssert not conf.outDir.isEmpty
doAssert not conf.outFile.isEmpty
# xxx: fix this pre-existing bug causing `SuccessX` error messages to lie
# for `jsonscript`
result = conf.outDir / conf.outFile
when defined(posix):
if dirExists(result.string):
result.string.add ".out"
if dirExists(result.string): result.string.add ".out"
proc prepareToWriteOutput*(conf: ConfigRef): AbsoluteFile =
## Create the output directory and returns a full path to the output file
createDir conf.outDir
result = conf.outDir / conf.outFile
when defined(posix):
if dirExists(result.string):
result.string.add ".out"
result = conf.absOutFile
createDir result.string.parentDir
proc getPrefixDir*(conf: ConfigRef): AbsoluteDir =
## Gets the prefix dir, usually the parent directory where the binary resides.

View File

@@ -4,6 +4,7 @@
Command:
//compile, c compile project with default code generator (C)
//r compile & run $nimcach/projname [arguments]
//doc generate the documentation for inputfile
Arguments: