mirror of
https://github.com/nim-lang/Nim.git
synced 2026-06-06 11:54:11 +00:00
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:
11
changelog.md
11
changelog.md
@@ -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
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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) =
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user