forked from nim-works/nimskull
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnim.nim
166 lines (146 loc) · 5.49 KB
/
nim.nim
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#
#
# 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]
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
compiler/front/[
msgs, main, cmdlinehelper, options, commands, cli_reporter
],
compiler/modules/[
modulegraphs
],
compiler/utils/[
pathutils
],
compiler/ast/[
idents,
lineinfos
]
from std/osproc import execCmd
from std/browsers import openDefaultBrowser
from compiler/utils/nodejs import findNodeJs
when hasTinyCBackend:
import compiler/backend/tccgen
when defined(profiler) or defined(memProfiler):
{.hint: "Profiling support is turned on!".}
import sdt/nimprof
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"
type
CmdLineHandlingResult = enum
cliFinished # might still have errors, check `conf.errorCount`
cliErrNoParamsProvided
cliErrConfigProcessing
cliErrCommandProcessing
proc handleCmdLine(cache: IdentCache; conf: ConfigRef, argv: openArray[string]): CmdLineHandlingResult =
## Main entry point to the compiler - dispatches command-line commands
## into different subsystems, sets up configuration options for the
## `conf`:arg: and so on.
let self = NimProg(
supportsStdinFile: true,
processCmdLine: processCmdLine
)
self.initDefinesProg(conf, "nim_compiler")
if argv.len == 0:
return cliErrNoParamsProvided
self.processCmdLineAndProjectPath(conf, argv)
if conf.errorCounter != 0: return
let graph = newModuleGraph(cache, conf)
if not self.loadConfigsAndProcessCmdLine(cache, conf, graph, argv):
return
if conf.errorCounter != 0: return
mainCommand(graph)
if optCmdExitGcStats in conf.globalOptions:
conf.logGcStats(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: discard
of backendJs:
let nodejs = findNodeJs()
if nodejs.len > 0:
# 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 = nodejs.quoteShell
cmdPrefix.add " --unhandled-rejections=strict"
else:
conf.logError:
"NodeJS not found in path. For installing it, refer to " &
"https://nodejs.org/en/download"
return
of backendNimVm:
if cmdPrefix.len == 0:
cmdPrefix = changeFileExt(getAppDir() / "vmrunner", ExeExt)
of backendInvalid: 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`
let cmd = cmdPrefix & output.quoteShell & ' ' & conf.arguments
conf.logExecStart(cmd)
let code = execCmd(cmd)
if code != 0:
conf.logError(execExternalProgramFailedMsg(cmd, code))
of cmdDocLike, cmdRst2html, cmdRst2tex: # bugfix(cmdRst2tex was missing)
if conf.arguments.len > 0:
# reserved for future use
conf.logError:
CliEvent(kind: cliEvtErrCmdExpectedNoAdditionalArgs,
cmd: $conf.command,
unexpectedArgs: conf.arguments,
srcCodeOrigin: instLoc())
openDefaultBrowser($output)
else:
# support as needed
conf.logError(CliEvent(kind: cliEvtErrUnexpectedRunOpt,
cmd: $conf.command,
srcCodeOrigin: instLoc()))
when not defined(selftest):
var conf = newConfigRef(cli_reporter.reportHook)
conf.astDiagToLegacyReport = cli_reporter.legacyReportBridge
conf.writeHook = msgs.msgWrite
conf.writelnHook =
proc(conf: ConfigRef, msg: string, flags: MsgFlags) =
conf.writeHook(conf, msg & "\n", flags)
let argv = getExecArgs()
case handleCmdLine(newIdentCache(), conf, argv)
of cliErrNoParamsProvided:
inc conf.errorCounter # causes a non-0 exit, will be replaced soon
conf.msgWrite("no command-line parameters provided\n", {msgNoUnitSep})
writeUsage(conf)
of cliErrConfigProcessing, cliErrCommandProcessing, cliFinished:
# TODO: more specific handling here
discard "error messages reported internally"
when declared(GC_setMaxPause):
echo GC_getStatistics()
msgQuit(int8(conf.errorCounter > 0))