Skip to content

Commit 9502e39

Browse files
authored
nim doc --backend:js, nim doc --doccmd:-d:foo, nim r --backend:js, --doccmd:skip + other improvements (#14278)
* `nim doc --backend:js|cpp...` `nim doc --doccmd:'-d:foo --threads:on'` `nim r --backend:cpp...` (implies --run --usenimcache) * --usenimcache works with all targets * --docCmd:skip now skips compiling snippets; 50X speedup for doc/manual.rst
1 parent d11cb9d commit 9502e39

22 files changed

+213
-99
lines changed

compiler/ccgthreadvars.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ proc generateThreadLocalStorage(m: BModule) =
4646

4747
proc generateThreadVarsSize(m: BModule) =
4848
if m.g.nimtv != nil:
49-
let externc = if m.config.cmd == cmdCompileToCpp or
49+
let externc = if m.config.backend == backendCpp or
5050
sfCompileToCpp in m.module.flags: "extern \"C\" "
5151
else: ""
5252
m.s[cfsProcs].addf(

compiler/cgen.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -279,7 +279,7 @@ proc genProc(m: BModule, prc: PSym)
279279
proc raiseInstr(p: BProc): Rope
280280

281281
template compileToCpp(m: BModule): untyped =
282-
m.config.cmd == cmdCompileToCpp or sfCompileToCpp in m.module.flags
282+
m.config.backend == backendCpp or sfCompileToCpp in m.module.flags
283283

284284
proc getTempName(m: BModule): Rope =
285285
result = m.tmpBase & rope(m.labels)
@@ -1066,11 +1066,11 @@ proc genProcAux(m: BModule, prc: PSym) =
10661066
proc requiresExternC(m: BModule; sym: PSym): bool {.inline.} =
10671067
result = (sfCompileToCpp in m.module.flags and
10681068
sfCompileToCpp notin sym.getModule().flags and
1069-
m.config.cmd != cmdCompileToCpp) or (
1069+
m.config.backend != backendCpp) or (
10701070
sym.flags * {sfInfixCall, sfCompilerProc, sfMangleCpp} == {} and
10711071
sym.flags * {sfImportc, sfExportc} != {} and
10721072
sym.magic == mNone and
1073-
m.config.cmd == cmdCompileToCpp)
1073+
m.config.backend == backendCpp)
10741074

10751075
proc genProcPrototype(m: BModule, sym: PSym) =
10761076
useHeader(m, sym)
@@ -1867,7 +1867,7 @@ proc writeHeader(m: BModule) =
18671867
proc getCFile(m: BModule): AbsoluteFile =
18681868
let ext =
18691869
if m.compileToCpp: ".nim.cpp"
1870-
elif m.config.cmd == cmdCompileToOC or sfCompileToObjc in m.module.flags: ".nim.m"
1870+
elif m.config.backend == backendObjc or sfCompileToObjc in m.module.flags: ".nim.m"
18711871
else: ".nim.c"
18721872
result = changeFileExt(completeCfilePath(m.config, withPackageName(m.config, m.cfilename)), ext)
18731873

compiler/cmdlinehelper.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ proc loadConfigsAndRunMainCommand*(self: NimProg, cache: IdentCache; conf: Confi
7878
# XXX This is hacky. We need to find a better way.
7979
case conf.command
8080
of "cpp", "compiletocpp":
81-
conf.cmd = cmdCompileToCpp
81+
conf.backend = backendCpp
82+
conf.cmd = cmdCompileToBackend
8283
else:
8384
discard
8485

compiler/commands.nim

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,18 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
434434
of "outdir":
435435
expectArg(conf, switch, arg, pass, info)
436436
conf.outDir = processPath(conf, arg, info, notRelativeToProj=true)
437+
of "usenimcache":
438+
processOnOffSwitchG(conf, {optUseNimcache}, arg, pass, info)
437439
of "docseesrcurl":
438440
expectArg(conf, switch, arg, pass, info)
439441
conf.docSeeSrcUrl = arg
440442
of "docroot":
441443
conf.docRoot = if arg.len == 0: "@default" else: arg
444+
of "backend", "b":
445+
let backend = parseEnum(arg.normalize, TBackend.default)
446+
if backend == TBackend.default: localError(conf, info, "invalid backend: '$1'" % arg)
447+
conf.backend = backend
448+
of "doccmd": conf.docCmd = arg
442449
of "mainmodule", "m":
443450
discard "allow for backwards compatibility, but don't do anything"
444451
of "define", "d":
@@ -495,7 +502,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
495502
defineSymbol(conf.symbols, "gcmarkandsweep")
496503
of "destructors", "arc":
497504
conf.selectedGC = gcArc
498-
if conf.cmd != cmdCompileToCpp:
505+
if conf.backend != backendCpp:
499506
conf.exc = excGoto
500507
defineSymbol(conf.symbols, "gcdestructors")
501508
defineSymbol(conf.symbols, "gcarc")
@@ -506,7 +513,7 @@ proc processSwitch*(switch, arg: string, pass: TCmdLinePass, info: TLineInfo;
506513
defineSymbol(conf.symbols, "nimV2")
507514
of "orc":
508515
conf.selectedGC = gcOrc
509-
if conf.cmd != cmdCompileToCpp:
516+
if conf.backend != backendCpp:
510517
conf.exc = excGoto
511518
defineSymbol(conf.symbols, "gcdestructors")
512519
defineSymbol(conf.symbols, "gcorc")

compiler/docgen.nim

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import
2222
const
2323
exportSection = skField
2424
htmldocsDir = RelativeDir"htmldocs"
25+
docCmdSkip = "skip"
2526

2627
type
2728
TSections = array[TSymKind, Rope]
@@ -196,6 +197,7 @@ proc newDocumentor*(filename: AbsoluteFile; cache: IdentCache; conf: ConfigRef,
196197
initStrTable result.types
197198
result.onTestSnippet =
198199
proc (gen: var RstGenerator; filename, cmd: string; status: int; content: string) =
200+
if conf.docCmd == docCmdSkip: return
199201
inc(gen.id)
200202
var d = TDocumentor(gen)
201203
var outp: AbsoluteFile
@@ -444,21 +446,26 @@ proc testExample(d: PDoc; ex: PNode) =
444446
d.examples.add "import r\"" & outp.string & "\"\n"
445447

446448
proc runAllExamples(d: PDoc) =
447-
if d.examples.len == 0: return
449+
let docCmd = d.conf.docCmd
450+
let backend = d.conf.backend
451+
# This used to be: `let backend = if isDefined(d.conf, "js"): "js"` (etc), however
452+
# using `-d:js` (etc) cannot work properly, eg would fail with `importjs`
453+
# since semantics are affected by `config.backend`, not by isDefined(d.conf, "js")
454+
if d.examples.len == 0 or docCmd == docCmdSkip: return
448455
let outputDir = d.conf.getNimcacheDir / RelativeDir"runnableExamples"
449456
let outp = outputDir / RelativeFile(extractFilename(d.filename.changeFileExt"" &
450457
"_examples.nim"))
451458
writeFile(outp, d.examples)
452-
let backend = if isDefined(d.conf, "js"): "js"
453-
elif isDefined(d.conf, "cpp"): "cpp"
454-
elif isDefined(d.conf, "objc"): "objc"
455-
else: "c"
456-
if os.execShellCmd(os.getAppFilename() & " " & backend &
457-
" --warning[UnusedImport]:off" &
458-
" --path:" & quoteShell(d.conf.projectPath) &
459-
" --nimcache:" & quoteShell(outputDir) &
460-
" -r " & quoteShell(outp)) != 0:
461-
quit "[Examples] failed: see " & outp.string
459+
let cmd = "$nim $backend -r --warning:UnusedImport:off --path:$path --nimcache:$nimcache $docCmd $file" % [
460+
"nim", os.getAppFilename(),
461+
"backend", $d.conf.backend,
462+
"path", quoteShell(d.conf.projectPath),
463+
"nimcache", quoteShell(outputDir),
464+
"file", quoteShell(outp),
465+
"docCmd", docCmd,
466+
]
467+
if os.execShellCmd(cmd) != 0:
468+
quit "[runnableExamples] failed: generated file: '$1' cmd: $2" % [outp.string, cmd]
462469
else:
463470
# keep generated source file `outp` to allow inspection.
464471
rawMessage(d.conf, hintSuccess, ["runnableExamples: " & outp.string])

compiler/extccomp.nim

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -307,14 +307,12 @@ proc getConfigVar(conf: ConfigRef; c: TSystemCC, suffix: string): string =
307307
# use ``cpu.os.cc`` for cross compilation, unless ``--compileOnly`` is given
308308
# for niminst support
309309
let fullSuffix =
310-
if conf.cmd == cmdCompileToCpp:
311-
".cpp" & suffix
312-
elif conf.cmd == cmdCompileToOC:
313-
".objc" & suffix
314-
elif conf.cmd == cmdCompileToJS:
315-
".js" & suffix
310+
case conf.backend
311+
of backendCpp, backendJs, backendObjc: "." & $conf.backend & suffix
312+
of backendC: suffix
316313
else:
317-
suffix
314+
doAssert false
315+
""
318316

319317
if (conf.target.hostOS != conf.target.targetOS or conf.target.hostCPU != conf.target.targetCPU) and
320318
optCompileOnly notin conf.globalOptions:
@@ -481,10 +479,10 @@ proc needsExeExt(conf: ConfigRef): bool {.inline.} =
481479
(conf.target.hostOS == osWindows)
482480

483481
proc useCpp(conf: ConfigRef; cfile: AbsoluteFile): bool =
484-
conf.cmd == cmdCompileToCpp and not cfile.string.endsWith(".c")
482+
conf.backend == backendCpp and not cfile.string.endsWith(".c")
485483

486484
proc envFlags(conf: ConfigRef): string =
487-
result = if conf.cmd == cmdCompileToCpp:
485+
result = if conf.backend == backendCpp:
488486
getEnv("CXXFLAGS")
489487
else:
490488
getEnv("CFLAGS")
@@ -535,7 +533,7 @@ proc ccHasSaneOverflow*(conf: ConfigRef): bool =
535533

536534
proc getLinkerExe(conf: ConfigRef; compiler: TSystemCC): string =
537535
result = if CC[compiler].linkerExe.len > 0: CC[compiler].linkerExe
538-
elif optMixedMode in conf.globalOptions and conf.cmd != cmdCompileToCpp: CC[compiler].cppCompiler
536+
elif optMixedMode in conf.globalOptions and conf.backend != backendCpp: CC[compiler].cppCompiler
539537
else: getCompilerExe(conf, compiler, AbsoluteFile"")
540538

541539
proc getCompileCFileCmd*(conf: ConfigRef; cfile: Cfile,
@@ -626,8 +624,10 @@ proc footprint(conf: ConfigRef; cfile: Cfile): SecureHash =
626624
getCompileCFileCmd(conf, cfile))
627625

628626
proc externalFileChanged(conf: ConfigRef; cfile: Cfile): bool =
629-
if conf.cmd notin {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToLLVM, cmdNone}:
630-
return false
627+
case conf.backend
628+
of backendInvalid: doAssert false
629+
of backendJs: return false # pre-existing behavior, but not sure it's good
630+
else: discard
631631

632632
var hashFile = toGeneratedFile(conf, conf.withPackageName(cfile.cname), "sha1")
633633
var currentHash = footprint(conf, cfile)

compiler/lambdalifting.nim

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ template isIterator*(owner: PSym): bool =
235235
proc liftingHarmful(conf: ConfigRef; owner: PSym): bool {.inline.} =
236236
## lambda lifting can be harmful for JS-like code generators.
237237
let isCompileTime = sfCompileTime in owner.flags or owner.kind == skMacro
238-
result = conf.cmd == cmdCompileToJS and not isCompileTime
238+
result = conf.backend == backendJs and not isCompileTime
239239

240240
proc createTypeBoundOpsLL(g: ModuleGraph; refType: PType; info: TLineInfo; owner: PSym) =
241241
createTypeBoundOps(g, nil, refType.lastSon, info)
@@ -846,14 +846,14 @@ proc liftIterToProc*(g: ModuleGraph; fn: PSym; body: PNode; ptrType: PType): PNo
846846
fn.typ.callConv = oldCC
847847

848848
proc liftLambdas*(g: ModuleGraph; fn: PSym, body: PNode; tooEarly: var bool): PNode =
849-
# XXX gCmd == cmdCompileToJS does not suffice! The compiletime stuff needs
849+
# XXX backend == backendJs does not suffice! The compiletime stuff needs
850850
# the transformation even when compiling to JS ...
851851

852852
# However we can do lifting for the stuff which is *only* compiletime.
853853
let isCompileTime = sfCompileTime in fn.flags or fn.kind == skMacro
854854

855855
if body.kind == nkEmpty or (
856-
g.config.cmd == cmdCompileToJS and not isCompileTime) or
856+
g.config.backend == backendJs and not isCompileTime) or
857857
fn.skipGenericOwner.kind != skModule:
858858

859859
# ignore forward declaration:

compiler/main.nim

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,14 @@ when not defined(leanCompiler):
119119
let conf = graph.config
120120
conf.exc = excCpp
121121

122-
if conf.outDir.isEmpty:
123-
conf.outDir = conf.projectPath
122+
setOutDir(conf)
124123
if conf.outFile.isEmpty:
125124
conf.outFile = RelativeFile(conf.projectName & ".js")
126125

127126
#incl(gGlobalOptions, optSafeCode)
128127
setTarget(graph.config.target, osJS, cpuJS)
129128
#initDefines()
130129
defineSymbol(graph.config.symbols, "ecmascript") # For backward compatibility
131-
defineSymbol(graph.config.symbols, "js")
132130
semanticPasses(graph)
133131
registerPass(graph, JSgenPass)
134132
compileProject(graph)
@@ -190,44 +188,53 @@ proc mainCommand*(graph: ModuleGraph) =
190188
conf.lastCmdTime = epochTime()
191189
conf.searchPaths.add(conf.libpath)
192190
setId(100)
193-
template handleC() =
194-
conf.cmd = cmdCompileToC
195-
if conf.exc == excNone: conf.exc = excSetjmp
196-
defineSymbol(graph.config.symbols, "c")
197-
commandCompileToC(graph)
191+
192+
## Calling `setOutDir(conf)` unconditionally would fix regression
193+
## https://github.com/nim-lang/Nim/issues/6583#issuecomment-625711125
194+
when false: setOutDir(conf)
195+
if optUseNimcache in conf.globalOptions: setOutDir(conf)
196+
197+
template handleBackend(backend2: TBackend) =
198+
conf.backend = backend2
199+
conf.cmd = cmdCompileToBackend
200+
defineSymbol(graph.config.symbols, $backend2)
201+
case backend2
202+
of backendC:
203+
if conf.exc == excNone: conf.exc = excSetjmp
204+
commandCompileToC(graph)
205+
of backendCpp:
206+
if conf.exc == excNone: conf.exc = excCpp
207+
commandCompileToC(graph)
208+
of backendObjc:
209+
commandCompileToC(graph)
210+
of backendJs:
211+
when defined(leanCompiler):
212+
globalError(conf, unknownLineInfo, "compiler wasn't built with JS code generator")
213+
else:
214+
if conf.hcrOn:
215+
# XXX: At the moment, system.nim cannot be compiled in JS mode
216+
# with "-d:useNimRtl". The HCR option has been processed earlier
217+
# and it has added this define implictly, so we must undo that here.
218+
# A better solution might be to fix system.nim
219+
undefSymbol(conf.symbols, "useNimRtl")
220+
commandCompileToJS(graph)
221+
of backendInvalid: doAssert false
222+
198223
case conf.command.normalize
199-
of "c", "cc", "compile", "compiletoc": handleC() # compile means compileToC currently
200-
of "cpp", "compiletocpp":
201-
conf.cmd = cmdCompileToCpp
202-
if conf.exc == excNone: conf.exc = excCpp
203-
defineSymbol(graph.config.symbols, "cpp")
204-
commandCompileToC(graph)
205-
of "objc", "compiletooc":
206-
conf.cmd = cmdCompileToOC
207-
defineSymbol(graph.config.symbols, "objc")
208-
commandCompileToC(graph)
224+
of "c", "cc", "compile", "compiletoc": handleBackend(backendC) # compile means compileToC currently
225+
of "cpp", "compiletocpp": handleBackend(backendCpp)
226+
of "objc", "compiletooc": handleBackend(backendObjc)
227+
of "js", "compiletojs": handleBackend(backendJs)
209228
of "r": # different from `"run"`!
210229
conf.globalOptions.incl {optRun, optUseNimcache}
211-
handleC()
230+
handleBackend(conf.backend)
212231
of "run":
213232
conf.cmd = cmdRun
214233
when hasTinyCBackend:
215234
extccomp.setCC(conf, "tcc", unknownLineInfo)
216235
commandCompileToC(graph)
217236
else:
218237
rawMessage(conf, errGenerated, "'run' command not available; rebuild with -d:tinyc")
219-
of "js", "compiletojs":
220-
when defined(leanCompiler):
221-
quit "compiler wasn't built with JS code generator"
222-
else:
223-
conf.cmd = cmdCompileToJS
224-
if conf.hcrOn:
225-
# XXX: At the moment, system.nim cannot be compiled in JS mode
226-
# with "-d:useNimRtl". The HCR option has been processed earlier
227-
# and it has added this define implictly, so we must undo that here.
228-
# A better solution might be to fix system.nim
229-
undefSymbol(conf.symbols, "useNimRtl")
230-
commandCompileToJS(graph)
231238
of "doc0":
232239
when defined(leanCompiler):
233240
quit "compiler wasn't built with documentation generator"

compiler/nim.nim

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,19 @@ proc handleCmdLine(cache: IdentCache; conf: ConfigRef) =
8888
tccgen.run(conf, conf.arguments)
8989
if optRun in conf.globalOptions:
9090
let output = conf.absOutFile
91-
let ex = quoteShell output
9291
case conf.cmd
93-
of cmdCompileToJS:
94-
execExternalProgram(conf, findNodeJs() & " " & ex & ' ' & conf.arguments)
92+
of cmdCompileToBackend:
93+
var cmdPrefix = ""
94+
case conf.backend
95+
of backendC, backendCpp, backendObjc: discard
96+
of backendJs: cmdPrefix = findNodeJs() & " "
97+
else: doAssert false, $conf.backend
98+
execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments)
9599
of cmdDoc, cmdRst2html:
96100
if conf.arguments.len > 0:
97101
# reserved for future use
98102
rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd])
99103
openDefaultBrowser($output)
100-
of cmdCompileToC, cmdCompileToCpp, cmdCompileToOC:
101-
execExternalProgram(conf, ex & ' ' & conf.arguments)
102104
else:
103105
# support as needed
104106
rawMessage(conf, errGenerated, "'$1 cannot handle --run" % [$conf.cmd])

0 commit comments

Comments
 (0)