# # # The Nim Compiler # (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # import std/[os, strutils, parseopt] when defined(windows) and not defined(nimKochBootstrap): # remove workaround pending bootstrap >= 1.5.1 # refs https://github.com/nim-lang/Nim/issues/18334#issuecomment-867114536 # alternative would be to prepend `currentSourcePath.parentDir.quoteShell` when defined(gcc): when defined(x86): {.link: "../icons/nim.res".} else: {.link: "../icons/nim_icon.o".} when defined(amd64) and defined(vcc): {.link: "../icons/nim-amd64-windows-vcc.res".} when defined(i386) and defined(vcc): {.link: "../icons/nim-i386-windows-vcc.res".} import commands, options, msgs, extccomp, main, idents, lineinfos, cmdlinehelper, pathutils, modulegraphs from browsers import openDefaultBrowser from nodejs import findNodeJs when hasTinyCBackend: import tccgen when defined(profiler) or defined(memProfiler): {.hint: "Profiling support is turned on!".} import nimprof proc processCmdLine(pass: TCmdLinePass, cmd: string; config: ConfigRef) = var p = parseopt.initOptParser(cmd) var argsCount = 0 config.commandLine.setLen 0 # bugfix: otherwise, config.commandLine ends up duplicated while true: parseopt.next(p) case p.kind of cmdEnd: break of cmdLongOption, cmdShortOption: config.commandLine.add " " config.commandLine.addCmdPrefix p.kind config.commandLine.add p.key.quoteShell # quoteShell to be future proof if p.val.len > 0: config.commandLine.add ':' config.commandLine.add p.val.quoteShell if p.key == "": # `-` was passed to indicate main project is stdin p.key = "-" if processArgument(pass, p, argsCount, config): break else: processSwitch(pass, p, config) of cmdArgument: config.commandLine.add " " config.commandLine.add p.key.quoteShell if processArgument(pass, p, argsCount, config): break if pass == passCmd2: if {optRun, optWasNimscript} * config.globalOptions == {} and config.arguments.len > 0 and config.cmd notin {cmdTcc, cmdNimscript, cmdCrun}: rawMessage(config, errGenerated, errArgsNeedRunOption) proc getNimRunExe(conf: ConfigRef): string = # xxx consider defining `conf.getConfigVar("nimrun.exe")` to allow users to # customize the binary to run the command with, e.g. for custom `nodejs` or `wine`. if conf.isDefined("mingw"): if conf.isDefined("i386"): result = "wine" elif conf.isDefined("amd64"): result = "wine64" proc handleCmdLine(cache: IdentCache; conf: ConfigRef) = let self = NimProg( supportsStdinFile: true, processCmdLine: processCmdLine ) self.initDefinesProg(conf, "nim_compiler") if paramCount() == 0: writeCommandLineUsage(conf) return self.processCmdLineAndProjectPath(conf) var graph = newModuleGraph(cache, conf) if not self.loadConfigsAndProcessCmdLine(cache, conf, graph): return mainCommand(graph) if conf.hasHint(hintGCStats): echo(GC_getStatistics()) #echo(GC_getStatistics()) if conf.errorCounter != 0: return when hasTinyCBackend: if conf.cmd == cmdTcc: tccgen.run(conf, conf.arguments) if optRun in conf.globalOptions: let output = conf.absOutFile case conf.cmd of cmdBackends, cmdTcc: let nimRunExe = getNimRunExe(conf) var cmdPrefix: string if nimRunExe.len > 0: cmdPrefix.add nimRunExe.quoteShell case conf.backend of backendC, backendCpp, backendObjc: discard of backendJs: # D20210217T215950:here this flag is needed for node < v15.0.0, otherwise # tasyncjs_fail` would fail, refs https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode if cmdPrefix.len == 0: cmdPrefix = findNodeJs().quoteShell cmdPrefix.add " --unhandled-rejections=strict" else: doAssert false, $conf.backend if cmdPrefix.len > 0: cmdPrefix.add " " # without the `cmdPrefix.len > 0` check, on windows you'd get a cryptic: # `The parameter is incorrect` execExternalProgram(conf, cmdPrefix & output.quoteShell & ' ' & conf.arguments) of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing) if conf.arguments.len > 0: # reserved for future use rawMessage(conf, errGenerated, "'$1 cannot handle arguments" % [$conf.cmd]) openDefaultBrowser($output) else: # support as needed rawMessage(conf, errGenerated, "'$1 cannot handle --run" % [$conf.cmd]) when declared(GC_setMaxPause): GC_setMaxPause 2_000 when compileOption("gc", "refc"): # the new correct mark&sweet collector is too slow :-/ GC_disableMarkAndSweep() when not defined(selftest): let conf = newConfigRef() handleCmdLine(newIdentCache(), conf) when declared(GC_setMaxPause): echo GC_getStatistics() msgQuit(int8(conf.errorCounter > 0))