options.nim 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. import
  10. lineinfos, platform,
  11. prefixmatches, pathutils, nimpaths
  12. import std/[tables, os, strutils, strtabs, sets]
  13. from std/terminal import isatty
  14. from std/times import utc, fromUnix, local, getTime, format, DateTime
  15. from std/private/globs import nativeToUnixPath
  16. when defined(nimPreviewSlimSystem):
  17. import std/[syncio, assertions]
  18. const
  19. hasTinyCBackend* = defined(tinyc)
  20. useEffectSystem* = true
  21. useWriteTracking* = false
  22. hasFFI* = defined(nimHasLibFFI)
  23. copyrightYear* = "2024"
  24. nimEnableCovariance* = defined(nimEnableCovariance)
  25. type # please make sure we have under 32 options
  26. # (improves code efficiency a lot!)
  27. TOption* = enum # **keep binary compatible**
  28. optNone, optObjCheck, optFieldCheck, optRangeCheck, optBoundsCheck,
  29. optOverflowCheck, optRefCheck,
  30. optNaNCheck, optInfCheck, optStaticBoundsCheck, optStyleCheck,
  31. optAssert, optLineDir, optWarns, optHints,
  32. optOptimizeSpeed, optOptimizeSize,
  33. optStackTrace, # stack tracing support
  34. optStackTraceMsgs, # enable custom runtime msgs via `setFrameMsg`
  35. optLineTrace, # line tracing support (includes stack tracing)
  36. optByRef, # use pass by ref for objects
  37. # (for interfacing with C)
  38. optProfiler, # profiler turned on
  39. optImplicitStatic, # optimization: implicit at compile time
  40. # evaluation
  41. optTrMacros, # en/disable pattern matching
  42. optMemTracker,
  43. optSinkInference # 'sink T' inference
  44. optCursorInference
  45. optImportHidden
  46. optQuirky
  47. TOptions* = set[TOption]
  48. TGlobalOption* = enum
  49. gloptNone, optForceFullMake,
  50. optWasNimscript, # redundant with `cmdNimscript`, could be removed
  51. optListCmd, optCompileOnly, optNoLinking,
  52. optCDebug, # turn on debugging information
  53. optGenDynLib, # generate a dynamic library
  54. optGenStaticLib, # generate a static library
  55. optGenGuiApp, # generate a GUI application
  56. optGenScript, # generate a script file to compile the *.c files
  57. optGenCDeps, # generate a list of *.c files to be read by CMake
  58. optGenMapping, # generate a mapping file
  59. optRun, # run the compiled project
  60. optUseNimcache, # save artifacts (including binary) in $nimcache
  61. optStyleHint, # check that the names adhere to NEP-1
  62. optStyleError, # enforce that the names adhere to NEP-1
  63. optStyleUsages, # only enforce consistent **usages** of the symbol
  64. optSkipSystemConfigFile, # skip the system's cfg/nims config file
  65. optSkipProjConfigFile, # skip the project's cfg/nims config file
  66. optSkipUserConfigFile, # skip the users's cfg/nims config file
  67. optSkipParentConfigFiles, # skip parent dir's cfg/nims config files
  68. optNoMain, # do not generate a "main" proc
  69. optUseColors, # use colors for hints, warnings, and errors
  70. optThreads, # support for multi-threading
  71. optStdout, # output to stdout
  72. optThreadAnalysis, # thread analysis pass
  73. optTlsEmulation, # thread var emulation turned on
  74. optGenIndex # generate index file for documentation;
  75. optGenIndexOnly # generate only index file for documentation
  76. optNoImportdoc # disable loading external documentation files
  77. optEmbedOrigSrc # embed the original source in the generated code
  78. # also: generate header file
  79. optIdeDebug # idetools: debug mode
  80. optIdeTerse # idetools: use terse descriptions
  81. optIdeExceptionInlayHints
  82. optExcessiveStackTrace # fully qualified module filenames
  83. optShowAllMismatches # show all overloading resolution candidates
  84. optWholeProject # for 'doc': output any dependency
  85. optDocInternal # generate documentation for non-exported symbols
  86. optMixedMode # true if some module triggered C++ codegen
  87. optDeclaredLocs # show declaration locations in messages
  88. optNoNimblePath
  89. optHotCodeReloading
  90. optDynlibOverrideAll
  91. optSeqDestructors # active if the implementation uses the new
  92. # string/seq implementation based on destructors
  93. optTinyRtti # active if we use the new "tiny RTTI"
  94. # implementation
  95. optOwnedRefs # active if the Nim compiler knows about 'owned'.
  96. optMultiMethods
  97. optBenchmarkVM # Enables cpuTime() in the VM
  98. optProduceAsm # produce assembler code
  99. optPanics # turn panics (sysFatal) into a process termination
  100. optSourcemap
  101. optProfileVM # enable VM profiler
  102. optEnableDeepCopy # ORC specific: enable 'deepcopy' for all types.
  103. optShowNonExportedFields # for documentation: show fields that are not exported
  104. optJsBigInt64 # use bigints for 64-bit integers in JS
  105. TGlobalOptions* = set[TGlobalOption]
  106. const
  107. harmlessOptions* = {optForceFullMake, optNoLinking, optRun, optUseColors, optStdout}
  108. genSubDir* = RelativeDir"nimcache"
  109. NimExt* = "nim"
  110. RodExt* = "rod"
  111. HtmlExt* = "html"
  112. JsonExt* = "json"
  113. TagsExt* = "tags"
  114. TexExt* = "tex"
  115. IniExt* = "ini"
  116. DefaultConfig* = RelativeFile"nim.cfg"
  117. DefaultConfigNims* = RelativeFile"config.nims"
  118. DocConfig* = RelativeFile"nimdoc.cfg"
  119. DocTexConfig* = RelativeFile"nimdoc.tex.cfg"
  120. htmldocsDir* = htmldocsDirname.RelativeDir
  121. docRootDefault* = "@default" # using `@` instead of `$` to avoid shell quoting complications
  122. oKeepVariableNames* = true
  123. spellSuggestSecretSauce* = -1
  124. type
  125. TBackend* = enum
  126. backendInvalid = "" # for parseEnum
  127. backendC = "c"
  128. backendCpp = "cpp"
  129. backendJs = "js"
  130. backendObjc = "objc"
  131. backendNir = "nir"
  132. # backendNimscript = "nimscript" # this could actually work
  133. # backendLlvm = "llvm" # probably not well supported; was cmdCompileToLLVM
  134. Command* = enum ## Nim's commands
  135. cmdNone # not yet processed command
  136. cmdUnknown # command unmapped
  137. cmdCompileToC, cmdCompileToCpp, cmdCompileToOC, cmdCompileToJS,
  138. cmdCompileToNir,
  139. cmdCrun # compile and run in nimache
  140. cmdTcc # run the project via TCC backend
  141. cmdCheck # semantic checking for whole project
  142. cmdM # only compile a single
  143. cmdParse # parse a single file (for debugging)
  144. cmdRod # .rod to some text representation (for debugging)
  145. cmdIdeTools # ide tools (e.g. nimsuggest)
  146. cmdNimscript # evaluate nimscript
  147. cmdDoc0
  148. cmdDoc # convert .nim doc comments to HTML
  149. cmdDoc2tex # convert .nim doc comments to LaTeX
  150. cmdRst2html # convert a reStructuredText file to HTML
  151. cmdRst2tex # convert a reStructuredText file to TeX
  152. cmdMd2html # convert a Markdown file to HTML
  153. cmdMd2tex # convert a Markdown file to TeX
  154. cmdJsondoc0
  155. cmdJsondoc
  156. cmdCtags
  157. cmdBuildindex
  158. cmdGendepend
  159. cmdDump
  160. cmdInteractive # start interactive session
  161. cmdNop
  162. cmdJsonscript # compile a .json build file
  163. # old unused: cmdInterpret, cmdDef: def feature (find definition for IDEs)
  164. const
  165. cmdBackends* = {cmdCompileToC, cmdCompileToCpp, cmdCompileToOC,
  166. cmdCompileToJS, cmdCrun, cmdCompileToNir}
  167. cmdDocLike* = {cmdDoc0, cmdDoc, cmdDoc2tex, cmdJsondoc0, cmdJsondoc,
  168. cmdCtags, cmdBuildindex}
  169. type
  170. NimVer* = tuple[major: int, minor: int, patch: int]
  171. TStringSeq* = seq[string]
  172. TGCMode* = enum # the selected GC
  173. gcUnselected = "unselected"
  174. gcNone = "none"
  175. gcBoehm = "boehm"
  176. gcRegions = "regions"
  177. gcArc = "arc"
  178. gcOrc = "orc"
  179. gcAtomicArc = "atomicArc"
  180. gcMarkAndSweep = "markAndSweep"
  181. gcHooks = "hooks"
  182. gcRefc = "refc"
  183. gcGo = "go"
  184. # gcRefc and the GCs that follow it use a write barrier,
  185. # as far as usesWriteBarrier() is concerned
  186. IdeCmd* = enum
  187. ideNone, ideSug, ideCon, ideDef, ideUse, ideDus, ideChk, ideChkFile, ideMod,
  188. ideHighlight, ideOutline, ideKnown, ideMsg, ideProject, ideGlobalSymbols,
  189. ideRecompile, ideChanged, ideType, ideDeclaration, ideExpand, ideInlayHints
  190. Feature* = enum ## experimental features; DO NOT RENAME THESE!
  191. dotOperators,
  192. callOperator,
  193. parallel,
  194. destructor,
  195. notnil,
  196. dynamicBindSym,
  197. forLoopMacros, # not experimental anymore; remains here for backwards compatibility
  198. caseStmtMacros, # ditto
  199. codeReordering,
  200. compiletimeFFI,
  201. ## This requires building nim with `-d:nimHasLibFFI`
  202. ## which itself requires `koch installdeps libffi`, see #10150
  203. ## Note: this feature can't be localized with {.push.}
  204. vmopsDanger,
  205. strictFuncs,
  206. views,
  207. strictNotNil,
  208. overloadableEnums, # deadcode
  209. strictEffects,
  210. unicodeOperators, # deadcode
  211. flexibleOptionalParams,
  212. strictDefs,
  213. strictCaseObjects,
  214. inferGenericTypes,
  215. genericsOpenSym,
  216. vtables
  217. LegacyFeature* = enum
  218. allowSemcheckedAstModification,
  219. ## Allows to modify a NimNode where the type has already been
  220. ## flagged with nfSem. If you actually do this, it will cause
  221. ## bugs.
  222. checkUnsignedConversions
  223. ## Historically and especially in version 1.0.0 of the language
  224. ## conversions to unsigned numbers were checked. In 1.0.4 they
  225. ## are not anymore.
  226. laxEffects
  227. ## Lax effects system prior to Nim 2.0.
  228. verboseTypeMismatch
  229. emitGenerics
  230. ## generics are emitted in the module that contains them.
  231. ## Useful for libraries that rely on local passC
  232. SymbolFilesOption* = enum
  233. disabledSf, writeOnlySf, readOnlySf, v2Sf, stressTest
  234. TSystemCC* = enum
  235. ccNone, ccGcc, ccNintendoSwitch, ccLLVM_Gcc, ccCLang, ccBcc, ccVcc,
  236. ccTcc, ccEnv, ccIcl, ccIcc, ccClangCl
  237. ExceptionSystem* = enum
  238. excNone, # no exception system selected yet
  239. excSetjmp, # setjmp based exception handling
  240. excCpp, # use C++'s native exception handling
  241. excGoto, # exception handling based on goto (should become the new default for C)
  242. excQuirky # quirky exception handling
  243. CfileFlag* {.pure.} = enum
  244. Cached, ## no need to recompile this time
  245. External ## file was introduced via .compile pragma
  246. Cfile* = object
  247. nimname*: string
  248. cname*, obj*: AbsoluteFile
  249. flags*: set[CfileFlag]
  250. customArgs*: string
  251. CfileList* = seq[Cfile]
  252. Suggest* = ref object
  253. section*: IdeCmd
  254. qualifiedPath*: seq[string]
  255. name*: ptr string # not used beyond sorting purposes; name is also
  256. # part of 'qualifiedPath'
  257. filePath*: string
  258. line*: int # Starts at 1
  259. column*: int # Starts at 0
  260. doc*: string # Not escaped (yet)
  261. forth*: string # type
  262. quality*: range[0..100] # matching quality
  263. isGlobal*: bool # is a global variable
  264. contextFits*: bool # type/non-type context matches
  265. prefix*: PrefixMatch
  266. symkind*: byte
  267. scope*, localUsages*, globalUsages*: int # more usages is better
  268. tokenLen*: int
  269. version*: int
  270. endLine*: uint16
  271. endCol*: int
  272. inlayHintInfo*: SuggestInlayHint
  273. Suggestions* = seq[Suggest]
  274. SuggestInlayHintKind* = enum
  275. sihkType = "Type",
  276. sihkParameter = "Parameter"
  277. sihkException = "Exception"
  278. SuggestInlayHint* = ref object
  279. kind*: SuggestInlayHintKind
  280. line*: int # Starts at 1
  281. column*: int # Starts at 0
  282. label*: string
  283. paddingLeft*: bool
  284. paddingRight*: bool
  285. allowInsert*: bool
  286. tooltip*: string
  287. ProfileInfo* = object
  288. time*: float
  289. count*: int
  290. ProfileData* = ref object
  291. data*: TableRef[TLineInfo, ProfileInfo]
  292. StdOrrKind* = enum
  293. stdOrrStdout
  294. stdOrrStderr
  295. FilenameOption* = enum
  296. foAbs # absolute path, e.g.: /pathto/bar/foo.nim
  297. foRelProject # relative to project path, e.g.: ../foo.nim
  298. foCanonical # canonical module name
  299. foLegacyRelProj # legacy, shortest of (foAbs, foRelProject)
  300. foName # lastPathPart, e.g.: foo.nim
  301. foStacktrace # if optExcessiveStackTrace: foAbs else: foName
  302. ConfigRef* {.acyclic.} = ref object ## every global configuration
  303. ## fields marked with '*' are subject to
  304. ## the incremental compilation mechanisms
  305. ## (+) means "part of the dependency"
  306. backend*: TBackend # set via `nim x` or `nim --backend:x`
  307. target*: Target # (+)
  308. linesCompiled*: int # all lines that have been compiled
  309. options*: TOptions # (+)
  310. globalOptions*: TGlobalOptions # (+)
  311. macrosToExpand*: StringTableRef
  312. arcToExpand*: StringTableRef
  313. m*: MsgConfig
  314. filenameOption*: FilenameOption # how to render paths in compiler messages
  315. unitSep*: string
  316. evalTemplateCounter*: int
  317. evalMacroCounter*: int
  318. exitcode*: int8
  319. cmd*: Command # raw command parsed as enum
  320. cmdInput*: string # input command
  321. projectIsCmd*: bool # whether we're compiling from a command input
  322. implicitCmd*: bool # whether some flag triggered an implicit `command`
  323. selectedGC*: TGCMode # the selected GC (+)
  324. exc*: ExceptionSystem
  325. hintProcessingDots*: bool # true for dots, false for filenames
  326. verbosity*: int # how verbose the compiler is
  327. numberOfProcessors*: int # number of processors
  328. lastCmdTime*: float # when caas is enabled, we measure each command
  329. symbolFiles*: SymbolFilesOption
  330. spellSuggestMax*: int # max number of spelling suggestions for typos
  331. cppDefines*: HashSet[string] # (*)
  332. headerFile*: string
  333. nimbasePattern*: string # pattern to find nimbase.h
  334. features*: set[Feature]
  335. legacyFeatures*: set[LegacyFeature]
  336. arguments*: string ## the arguments to be passed to the program that
  337. ## should be run
  338. ideCmd*: IdeCmd
  339. oldNewlines*: bool
  340. cCompiler*: TSystemCC # the used compiler
  341. modifiedyNotes*: TNoteKinds # notes that have been set/unset from either cmdline/configs
  342. cmdlineNotes*: TNoteKinds # notes that have been set/unset from cmdline
  343. foreignPackageNotes*: TNoteKinds
  344. notes*: TNoteKinds # notes after resolving all logic(defaults, verbosity)/cmdline/configs
  345. warningAsErrors*: TNoteKinds
  346. mainPackageNotes*: TNoteKinds
  347. mainPackageId*: int
  348. errorCounter*: int
  349. hintCounter*: int
  350. warnCounter*: int
  351. errorMax*: int
  352. maxLoopIterationsVM*: int ## VM: max iterations of all loops
  353. isVmTrace*: bool
  354. configVars*: StringTableRef
  355. symbols*: StringTableRef ## We need to use a StringTableRef here as defined
  356. ## symbols are always guaranteed to be style
  357. ## insensitive. Otherwise hell would break lose.
  358. packageCache*: StringTableRef
  359. nimblePaths*: seq[AbsoluteDir]
  360. searchPaths*: seq[AbsoluteDir]
  361. lazyPaths*: seq[AbsoluteDir]
  362. outFile*: RelativeFile
  363. outDir*: AbsoluteDir
  364. jsonBuildFile*: AbsoluteFile
  365. prefixDir*, libpath*, nimcacheDir*: AbsoluteDir
  366. nimStdlibVersion*: NimVer
  367. dllOverrides, moduleOverrides*, cfileSpecificOptions*: StringTableRef
  368. projectName*: string # holds a name like 'nim'
  369. projectPath*: AbsoluteDir # holds a path like /home/alice/projects/nim/compiler/
  370. projectFull*: AbsoluteFile # projectPath/projectName
  371. projectIsStdin*: bool # whether we're compiling from stdin
  372. lastMsgWasDot*: set[StdOrrKind] # the last compiler message was a single '.'
  373. projectMainIdx*: FileIndex # the canonical path id of the main module
  374. projectMainIdx2*: FileIndex # consider merging with projectMainIdx
  375. command*: string # the main command (e.g. cc, check, scan, etc)
  376. commandArgs*: seq[string] # any arguments after the main command
  377. commandLine*: string
  378. extraCmds*: seq[string] # for writeJsonBuildInstructions
  379. keepComments*: bool # whether the parser needs to keep comments
  380. implicitImports*: seq[string] # modules that are to be implicitly imported
  381. implicitIncludes*: seq[string] # modules that are to be implicitly included
  382. docSeeSrcUrl*: string # if empty, no seeSrc will be generated. \
  383. # The string uses the formatting variables `path` and `line`.
  384. docRoot*: string ## see nim --fullhelp for --docRoot
  385. docCmd*: string ## see nim --fullhelp for --docCmd
  386. configFiles*: seq[AbsoluteFile] # config files (cfg,nims)
  387. cIncludes*: seq[AbsoluteDir] # directories to search for included files
  388. cLibs*: seq[AbsoluteDir] # directories to search for lib files
  389. cLinkedLibs*: seq[string] # libraries to link
  390. externalToLink*: seq[string] # files to link in addition to the file
  391. # we compiled (*)
  392. linkOptionsCmd*: string
  393. compileOptionsCmd*: seq[string]
  394. linkOptions*: string # (*)
  395. compileOptions*: string # (*)
  396. cCompilerPath*: string
  397. toCompile*: CfileList # (*)
  398. suggestionResultHook*: proc (result: Suggest) {.closure.}
  399. suggestVersion*: int
  400. suggestMaxResults*: int
  401. lastLineInfo*: TLineInfo
  402. writelnHook*: proc (output: string) {.closure, gcsafe.}
  403. structuredErrorHook*: proc (config: ConfigRef; info: TLineInfo; msg: string;
  404. severity: Severity) {.closure, gcsafe.}
  405. cppCustomNamespace*: string
  406. nimMainPrefix*: string
  407. vmProfileData*: ProfileData
  408. expandProgress*: bool
  409. expandLevels*: int
  410. expandNodeResult*: string
  411. expandPosition*: TLineInfo
  412. currentConfigDir*: string # used for passPP only; absolute dir
  413. clientProcessId*: int
  414. proc parseNimVersion*(a: string): NimVer =
  415. # could be moved somewhere reusable
  416. result = default(NimVer)
  417. if a.len > 0:
  418. let b = a.split(".")
  419. assert b.len == 3, a
  420. template fn(i) = result[i] = b[i].parseInt # could be optimized if needed
  421. fn(0)
  422. fn(1)
  423. fn(2)
  424. proc assignIfDefault*[T](result: var T, val: T, def = default(T)) =
  425. ## if `result` was already assigned to a value (that wasn't `def`), this is a noop.
  426. if result == def: result = val
  427. template setErrorMaxHighMaybe*(conf: ConfigRef) =
  428. ## do not stop after first error (but honor --errorMax if provided)
  429. assignIfDefault(conf.errorMax, high(int))
  430. proc setNoteDefaults*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  431. template fun(op) =
  432. conf.notes.op note
  433. conf.mainPackageNotes.op note
  434. conf.foreignPackageNotes.op note
  435. if enabled: fun(incl) else: fun(excl)
  436. proc setNote*(conf: ConfigRef, note: TNoteKind, enabled = true) =
  437. # see also `prepareConfigNotes` which sets notes
  438. if note notin conf.cmdlineNotes:
  439. if enabled: incl(conf.notes, note) else: excl(conf.notes, note)
  440. proc hasHint*(conf: ConfigRef, note: TNoteKind): bool =
  441. # ternary states instead of binary states would simplify logic
  442. if optHints notin conf.options: false
  443. elif note in {hintConf, hintProcessing}:
  444. # could add here other special notes like hintSource
  445. # these notes apply globally.
  446. note in conf.mainPackageNotes
  447. else: note in conf.notes
  448. proc hasWarn*(conf: ConfigRef, note: TNoteKind): bool {.inline.} =
  449. optWarns in conf.options and note in conf.notes
  450. proc hcrOn*(conf: ConfigRef): bool = return optHotCodeReloading in conf.globalOptions
  451. when false:
  452. template depConfigFields*(fn) {.dirty.} = # deadcode
  453. fn(target)
  454. fn(options)
  455. fn(globalOptions)
  456. fn(selectedGC)
  457. const oldExperimentalFeatures* = {dotOperators, callOperator, parallel}
  458. const
  459. ChecksOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  460. optOverflowCheck, optBoundsCheck, optAssert, optNaNCheck, optInfCheck,
  461. optStyleCheck}
  462. DefaultOptions* = {optObjCheck, optFieldCheck, optRangeCheck,
  463. optBoundsCheck, optOverflowCheck, optAssert, optWarns, optRefCheck,
  464. optHints, optStackTrace, optLineTrace, # consider adding `optStackTraceMsgs`
  465. optTrMacros, optStyleCheck, optCursorInference}
  466. DefaultGlobalOptions* = {optThreadAnalysis, optExcessiveStackTrace,
  467. optJsBigInt64}
  468. proc getSrcTimestamp(): DateTime =
  469. try:
  470. result = utc(fromUnix(parseInt(getEnv("SOURCE_DATE_EPOCH",
  471. "not a number"))))
  472. except ValueError:
  473. # Environment variable malformed.
  474. # https://reproducible-builds.org/specs/source-date-epoch/: "If the
  475. # value is malformed, the build process SHOULD exit with a non-zero
  476. # error code", which this doesn't do. This uses local time, because
  477. # that maintains compatibility with existing usage.
  478. result = utc getTime()
  479. proc getDateStr*(): string =
  480. result = format(getSrcTimestamp(), "yyyy-MM-dd")
  481. proc getClockStr*(): string =
  482. result = format(getSrcTimestamp(), "HH:mm:ss")
  483. template newPackageCache*(): untyped =
  484. newStringTable(when FileSystemCaseSensitive:
  485. modeCaseInsensitive
  486. else:
  487. modeCaseSensitive)
  488. proc newProfileData(): ProfileData =
  489. ProfileData(data: newTable[TLineInfo, ProfileInfo]())
  490. const foreignPackageNotesDefault* = {
  491. hintProcessing, warnUnknownMagic, hintQuitCalled, hintExecuting, hintUser, warnUser}
  492. proc isDefined*(conf: ConfigRef; symbol: string): bool
  493. when defined(nimDebugUtils):
  494. # this allows inserting debugging utilties in all modules that import `options`
  495. # with a single switch, which is useful when debugging compiler.
  496. import debugutils
  497. export debugutils
  498. proc initConfigRefCommon(conf: ConfigRef) =
  499. conf.selectedGC = gcUnselected
  500. conf.verbosity = 1
  501. conf.hintProcessingDots = true
  502. conf.options = DefaultOptions
  503. conf.globalOptions = DefaultGlobalOptions
  504. conf.filenameOption = foAbs
  505. conf.foreignPackageNotes = foreignPackageNotesDefault
  506. conf.notes = NotesVerbosity[1]
  507. conf.mainPackageNotes = NotesVerbosity[1]
  508. proc newConfigRef*(): ConfigRef =
  509. result = ConfigRef(
  510. cCompiler: ccGcc,
  511. macrosToExpand: newStringTable(modeStyleInsensitive),
  512. arcToExpand: newStringTable(modeStyleInsensitive),
  513. m: initMsgConfig(),
  514. cppDefines: initHashSet[string](),
  515. headerFile: "", features: {}, legacyFeatures: {},
  516. configVars: newStringTable(modeStyleInsensitive),
  517. symbols: newStringTable(modeStyleInsensitive),
  518. packageCache: newPackageCache(),
  519. searchPaths: @[],
  520. lazyPaths: @[],
  521. outFile: RelativeFile"",
  522. outDir: AbsoluteDir"",
  523. prefixDir: AbsoluteDir"",
  524. libpath: AbsoluteDir"", nimcacheDir: AbsoluteDir"",
  525. dllOverrides: newStringTable(modeCaseInsensitive),
  526. moduleOverrides: newStringTable(modeStyleInsensitive),
  527. cfileSpecificOptions: newStringTable(modeCaseSensitive),
  528. projectName: "", # holds a name like 'nim'
  529. projectPath: AbsoluteDir"", # holds a path like /home/alice/projects/nim/compiler/
  530. projectFull: AbsoluteFile"", # projectPath/projectName
  531. projectIsStdin: false, # whether we're compiling from stdin
  532. projectMainIdx: FileIndex(0'i32), # the canonical path id of the main module
  533. command: "", # the main command (e.g. cc, check, scan, etc)
  534. commandArgs: @[], # any arguments after the main command
  535. commandLine: "",
  536. keepComments: true, # whether the parser needs to keep comments
  537. implicitImports: @[], # modules that are to be implicitly imported
  538. implicitIncludes: @[], # modules that are to be implicitly included
  539. docSeeSrcUrl: "",
  540. cIncludes: @[], # directories to search for included files
  541. cLibs: @[], # directories to search for lib files
  542. cLinkedLibs: @[], # libraries to link
  543. backend: backendInvalid,
  544. externalToLink: @[],
  545. linkOptionsCmd: "",
  546. compileOptionsCmd: @[],
  547. linkOptions: "",
  548. compileOptions: "",
  549. ccompilerpath: "",
  550. toCompile: @[],
  551. arguments: "",
  552. suggestMaxResults: 10_000,
  553. maxLoopIterationsVM: 10_000_000,
  554. vmProfileData: newProfileData(),
  555. spellSuggestMax: spellSuggestSecretSauce,
  556. currentConfigDir: ""
  557. )
  558. initConfigRefCommon(result)
  559. setTargetFromSystem(result.target)
  560. # enable colors by default on terminals
  561. if terminal.isatty(stderr):
  562. incl(result.globalOptions, optUseColors)
  563. when defined(nimDebugUtils):
  564. onNewConfigRef(result)
  565. proc newPartialConfigRef*(): ConfigRef =
  566. ## create a new ConfigRef that is only good enough for error reporting.
  567. when defined(nimDebugUtils):
  568. result = getConfigRef()
  569. else:
  570. result = ConfigRef()
  571. initConfigRefCommon(result)
  572. proc cppDefine*(c: ConfigRef; define: string) =
  573. c.cppDefines.incl define
  574. proc getStdlibVersion*(conf: ConfigRef): NimVer =
  575. if conf.nimStdlibVersion == (0,0,0):
  576. let s = conf.symbols.getOrDefault("nimVersion", "")
  577. conf.nimStdlibVersion = s.parseNimVersion
  578. result = conf.nimStdlibVersion
  579. proc isDefined*(conf: ConfigRef; symbol: string): bool =
  580. if conf.symbols.hasKey(symbol):
  581. result = true
  582. elif cmpIgnoreStyle(symbol, CPU[conf.target.targetCPU].name) == 0:
  583. result = true
  584. elif cmpIgnoreStyle(symbol, platform.OS[conf.target.targetOS].name) == 0:
  585. result = true
  586. else:
  587. case symbol.normalize
  588. of "x86": result = conf.target.targetCPU == cpuI386
  589. of "itanium": result = conf.target.targetCPU == cpuIa64
  590. of "x8664": result = conf.target.targetCPU == cpuAmd64
  591. of "posix", "unix":
  592. result = conf.target.targetOS in {osLinux, osMorphos, osSkyos, osIrix, osPalmos,
  593. osQnx, osAtari, osAix,
  594. osHaiku, osVxWorks, osSolaris, osNetbsd,
  595. osFreebsd, osOpenbsd, osDragonfly, osMacosx, osIos,
  596. osAndroid, osNintendoSwitch, osFreeRTOS, osCrossos, osZephyr, osNuttX}
  597. of "linux":
  598. result = conf.target.targetOS in {osLinux, osAndroid}
  599. of "bsd":
  600. result = conf.target.targetOS in {osNetbsd, osFreebsd, osOpenbsd, osDragonfly, osCrossos}
  601. of "freebsd":
  602. result = conf.target.targetOS in {osFreebsd, osCrossos}
  603. of "emulatedthreadvars":
  604. result = platform.OS[conf.target.targetOS].props.contains(ospLacksThreadVars)
  605. of "msdos": result = conf.target.targetOS == osDos
  606. of "mswindows", "win32": result = conf.target.targetOS == osWindows
  607. of "macintosh":
  608. result = conf.target.targetOS in {osMacos, osMacosx, osIos}
  609. of "osx", "macosx":
  610. result = conf.target.targetOS in {osMacosx, osIos}
  611. of "sunos": result = conf.target.targetOS == osSolaris
  612. of "nintendoswitch":
  613. result = conf.target.targetOS == osNintendoSwitch
  614. of "freertos", "lwip":
  615. result = conf.target.targetOS == osFreeRTOS
  616. of "zephyr":
  617. result = conf.target.targetOS == osZephyr
  618. of "nuttx":
  619. result = conf.target.targetOS == osNuttX
  620. of "littleendian": result = CPU[conf.target.targetCPU].endian == littleEndian
  621. of "bigendian": result = CPU[conf.target.targetCPU].endian == bigEndian
  622. of "cpu8": result = CPU[conf.target.targetCPU].bit == 8
  623. of "cpu16": result = CPU[conf.target.targetCPU].bit == 16
  624. of "cpu32": result = CPU[conf.target.targetCPU].bit == 32
  625. of "cpu64": result = CPU[conf.target.targetCPU].bit == 64
  626. of "nimrawsetjmp":
  627. result = conf.target.targetOS in {osSolaris, osNetbsd, osFreebsd, osOpenbsd,
  628. osDragonfly, osMacosx}
  629. else: result = false
  630. template quitOrRaise*(conf: ConfigRef, msg = "") =
  631. # xxx in future work, consider whether to also intercept `msgQuit` calls
  632. if conf.isDefined("nimDebug"):
  633. raiseAssert msg
  634. else:
  635. quit(msg) # quits with QuitFailure
  636. proc importantComments*(conf: ConfigRef): bool {.inline.} = conf.cmd in cmdDocLike + {cmdIdeTools}
  637. proc usesWriteBarrier*(conf: ConfigRef): bool {.inline.} = conf.selectedGC >= gcRefc
  638. template compilationCachePresent*(conf: ConfigRef): untyped =
  639. false
  640. # conf.symbolFiles in {v2Sf, writeOnlySf}
  641. template optPreserveOrigSource*(conf: ConfigRef): untyped =
  642. optEmbedOrigSrc in conf.globalOptions
  643. proc mainCommandArg*(conf: ConfigRef): string =
  644. ## This is intended for commands like check or parse
  645. ## which will work on the main project file unless
  646. ## explicitly given a specific file argument
  647. if conf.commandArgs.len > 0:
  648. result = conf.commandArgs[0]
  649. else:
  650. result = conf.projectName
  651. proc existsConfigVar*(conf: ConfigRef; key: string): bool =
  652. result = hasKey(conf.configVars, key)
  653. proc getConfigVar*(conf: ConfigRef; key: string, default = ""): string =
  654. result = conf.configVars.getOrDefault(key, default)
  655. proc setConfigVar*(conf: ConfigRef; key, val: string) =
  656. conf.configVars[key] = val
  657. proc getOutFile*(conf: ConfigRef; filename: RelativeFile, ext: string): AbsoluteFile =
  658. # explains regression https://github.com/nim-lang/Nim/issues/6583#issuecomment-625711125
  659. # Yet another reason why "" should not mean "."; `""/something` should raise
  660. # instead of implying "" == "." as it's bug prone.
  661. doAssert conf.outDir.string.len > 0
  662. result = conf.outDir / changeFileExt(filename, ext)
  663. proc absOutFile*(conf: ConfigRef): AbsoluteFile =
  664. doAssert not conf.outDir.isEmpty
  665. doAssert not conf.outFile.isEmpty
  666. result = conf.outDir / conf.outFile
  667. when defined(posix):
  668. if dirExists(result.string): result.string.add ".out"
  669. proc prepareToWriteOutput*(conf: ConfigRef): AbsoluteFile =
  670. ## Create the output directory and returns a full path to the output file
  671. result = conf.absOutFile
  672. createDir result.string.parentDir
  673. proc getPrefixDir*(conf: ConfigRef): AbsoluteDir =
  674. ## Gets the prefix dir, usually the parent directory where the binary resides.
  675. ##
  676. ## This is overridden by some tools (namely nimsuggest) via the ``conf.prefixDir``
  677. ## field.
  678. ## This should resolve to root of nim sources, whether running nim from a local
  679. ## clone or using installed nim, so that these exist: `result/doc/advopt.txt`
  680. ## and `result/lib/system.nim`
  681. if not conf.prefixDir.isEmpty: result = conf.prefixDir
  682. else:
  683. let binParent = AbsoluteDir splitPath(getAppDir()).head
  684. when defined(posix):
  685. if binParent == AbsoluteDir"/usr":
  686. result = AbsoluteDir"/usr/lib/nim"
  687. elif binParent == AbsoluteDir"/usr/local":
  688. result = AbsoluteDir"/usr/local/lib/nim"
  689. else:
  690. result = binParent
  691. else:
  692. result = binParent
  693. proc setDefaultLibpath*(conf: ConfigRef) =
  694. # set default value (can be overwritten):
  695. if conf.libpath.isEmpty:
  696. # choose default libpath:
  697. var prefix = getPrefixDir(conf)
  698. conf.libpath = prefix / RelativeDir"lib"
  699. # Special rule to support other tools (nimble) which import the compiler
  700. # modules and make use of them.
  701. let realNimPath = findExe("nim")
  702. # Find out if $nim/../../lib/system.nim exists.
  703. let parentNimLibPath = realNimPath.parentDir.parentDir / "lib"
  704. if not fileExists(conf.libpath.string / "system.nim") and
  705. fileExists(parentNimLibPath / "system.nim"):
  706. conf.libpath = AbsoluteDir parentNimLibPath
  707. proc canonicalizePath*(conf: ConfigRef; path: AbsoluteFile): AbsoluteFile =
  708. result = AbsoluteFile path.string.expandFilename
  709. proc setFromProjectName*(conf: ConfigRef; projectName: string) =
  710. try:
  711. conf.projectFull = canonicalizePath(conf, AbsoluteFile projectName)
  712. except OSError:
  713. conf.projectFull = AbsoluteFile projectName
  714. let p = splitFile(conf.projectFull)
  715. let dir = if p.dir.isEmpty: AbsoluteDir getCurrentDir() else: p.dir
  716. try:
  717. conf.projectPath = AbsoluteDir canonicalizePath(conf, AbsoluteFile dir)
  718. except OSError:
  719. conf.projectPath = dir
  720. conf.projectName = p.name
  721. proc removeTrailingDirSep*(path: string): string =
  722. if (path.len > 0) and (path[^1] == DirSep):
  723. result = substr(path, 0, path.len - 2)
  724. else:
  725. result = path
  726. proc disableNimblePath*(conf: ConfigRef) =
  727. incl conf.globalOptions, optNoNimblePath
  728. conf.lazyPaths.setLen(0)
  729. conf.nimblePaths.setLen(0)
  730. proc clearNimblePath*(conf: ConfigRef) =
  731. conf.lazyPaths.setLen(0)
  732. conf.nimblePaths.setLen(0)
  733. include packagehandling
  734. proc getOsCacheDir(): string =
  735. when defined(posix):
  736. result = getEnv("XDG_CACHE_HOME", getHomeDir() / ".cache") / "nim"
  737. else:
  738. result = getHomeDir() / genSubDir.string
  739. proc getNimcacheDir*(conf: ConfigRef): AbsoluteDir =
  740. proc nimcacheSuffix(conf: ConfigRef): string =
  741. if conf.cmd == cmdCheck: "_check"
  742. elif isDefined(conf, "release") or isDefined(conf, "danger"): "_r"
  743. else: "_d"
  744. # XXX projectName should always be without a file extension!
  745. result =
  746. if not conf.nimcacheDir.isEmpty:
  747. conf.nimcacheDir
  748. elif conf.backend == backendJs:
  749. if conf.outDir.isEmpty:
  750. conf.projectPath / genSubDir
  751. else:
  752. conf.outDir / genSubDir
  753. else:
  754. AbsoluteDir(getOsCacheDir() / splitFile(conf.projectName).name &
  755. nimcacheSuffix(conf))
  756. proc pathSubs*(conf: ConfigRef; p, config: string): string =
  757. let home = removeTrailingDirSep(os.getHomeDir())
  758. result = unixToNativePath(p % [
  759. "nim", getPrefixDir(conf).string,
  760. "lib", conf.libpath.string,
  761. "home", home,
  762. "config", config,
  763. "projectname", conf.projectName,
  764. "projectpath", conf.projectPath.string,
  765. "projectdir", conf.projectPath.string,
  766. "nimcache", getNimcacheDir(conf).string]).expandTilde
  767. iterator nimbleSubs*(conf: ConfigRef; p: string): string =
  768. let pl = p.toLowerAscii
  769. if "$nimblepath" in pl or "$nimbledir" in pl:
  770. for i in countdown(conf.nimblePaths.len-1, 0):
  771. let nimblePath = removeTrailingDirSep(conf.nimblePaths[i].string)
  772. yield p % ["nimblepath", nimblePath, "nimbledir", nimblePath]
  773. else:
  774. yield p
  775. proc toGeneratedFile*(conf: ConfigRef; path: AbsoluteFile,
  776. ext: string): AbsoluteFile =
  777. ## converts "/home/a/mymodule.nim", "rod" to "/home/a/nimcache/mymodule.rod"
  778. result = getNimcacheDir(conf) / RelativeFile path.string.splitPath.tail.changeFileExt(ext)
  779. proc completeGeneratedFilePath*(conf: ConfigRef; f: AbsoluteFile,
  780. createSubDir: bool = true): AbsoluteFile =
  781. ## Return an absolute path of a generated intermediary file.
  782. ## Optionally creates the cache directory if `createSubDir` is `true`.
  783. let subdir = getNimcacheDir(conf)
  784. if createSubDir:
  785. try:
  786. createDir(subdir.string)
  787. except OSError:
  788. conf.quitOrRaise "cannot create directory: " & subdir.string
  789. result = subdir / RelativeFile f.string.splitPath.tail
  790. proc rawFindFile(conf: ConfigRef; f: RelativeFile; suppressStdlib: bool): AbsoluteFile =
  791. for it in conf.searchPaths:
  792. if suppressStdlib and it.string.startsWith(conf.libpath.string):
  793. continue
  794. result = it / f
  795. if fileExists(result):
  796. return canonicalizePath(conf, result)
  797. result = AbsoluteFile""
  798. proc rawFindFile2(conf: ConfigRef; f: RelativeFile): AbsoluteFile =
  799. for i, it in conf.lazyPaths:
  800. result = it / f
  801. if fileExists(result):
  802. # bring to front
  803. for j in countdown(i, 1):
  804. swap(conf.lazyPaths[j], conf.lazyPaths[j-1])
  805. return canonicalizePath(conf, result)
  806. result = AbsoluteFile""
  807. template patchModule(conf: ConfigRef) {.dirty.} =
  808. if not result.isEmpty and conf.moduleOverrides.len > 0:
  809. let key = getPackageName(conf, result.string) & "_" & splitFile(result).name
  810. if conf.moduleOverrides.hasKey(key):
  811. let ov = conf.moduleOverrides[key]
  812. if ov.len > 0: result = AbsoluteFile(ov)
  813. const stdlibDirs* = [
  814. "pure", "core", "arch",
  815. "pure/collections",
  816. "pure/concurrency",
  817. "pure/unidecode", "impure",
  818. "wrappers", "wrappers/linenoise",
  819. "windows", "posix", "js",
  820. "deprecated/pure"]
  821. const
  822. pkgPrefix = "pkg/"
  823. stdPrefix* = "std/"
  824. proc getRelativePathFromConfigPath*(conf: ConfigRef; f: AbsoluteFile, isTitle = false): RelativeFile =
  825. result = RelativeFile("")
  826. let f = $f
  827. if isTitle:
  828. for dir in stdlibDirs:
  829. let path = conf.libpath.string / dir / f.lastPathPart
  830. if path.cmpPaths(f) == 0:
  831. return RelativeFile(stdPrefix & f.splitFile.name)
  832. template search(paths) =
  833. for it in paths:
  834. let it = $it
  835. if f.isRelativeTo(it):
  836. return relativePath(f, it).RelativeFile
  837. search(conf.searchPaths)
  838. search(conf.lazyPaths)
  839. proc findFile*(conf: ConfigRef; f: string; suppressStdlib = false): AbsoluteFile =
  840. if f.isAbsolute:
  841. result = if f.fileExists: AbsoluteFile(f) else: AbsoluteFile""
  842. else:
  843. result = rawFindFile(conf, RelativeFile f, suppressStdlib)
  844. if result.isEmpty:
  845. result = rawFindFile(conf, RelativeFile f.toLowerAscii, suppressStdlib)
  846. if result.isEmpty:
  847. result = rawFindFile2(conf, RelativeFile f)
  848. if result.isEmpty:
  849. result = rawFindFile2(conf, RelativeFile f.toLowerAscii)
  850. patchModule(conf)
  851. proc findModule*(conf: ConfigRef; modulename, currentModule: string): AbsoluteFile =
  852. # returns path to module
  853. var m = addFileExt(modulename, NimExt)
  854. var hasRelativeDot = false
  855. if m.startsWith(pkgPrefix):
  856. result = findFile(conf, m.substr(pkgPrefix.len), suppressStdlib = true)
  857. else:
  858. if m.startsWith(stdPrefix):
  859. result = AbsoluteFile("")
  860. let stripped = m.substr(stdPrefix.len)
  861. for candidate in stdlibDirs:
  862. let path = (conf.libpath.string / candidate / stripped)
  863. if fileExists(path):
  864. result = AbsoluteFile path
  865. break
  866. else: # If prefixed with std/ why would we add the current module path!
  867. let currentPath = currentModule.splitFile.dir
  868. result = AbsoluteFile currentPath / m
  869. if m.startsWith('.') and not fileExists(result):
  870. result = AbsoluteFile ""
  871. hasRelativeDot = true
  872. if not fileExists(result) and not hasRelativeDot:
  873. result = findFile(conf, m)
  874. patchModule(conf)
  875. proc findProjectNimFile*(conf: ConfigRef; pkg: string): string =
  876. const extensions = [".nims", ".cfg", ".nimcfg", ".nimble"]
  877. var
  878. candidates: seq[string] = @[]
  879. dir = pkg
  880. prev = dir
  881. nimblepkg = ""
  882. let pkgname = pkg.lastPathPart()
  883. while true:
  884. for k, f in os.walkDir(dir, relative = true):
  885. if k == pcFile and f != "config.nims":
  886. let (_, name, ext) = splitFile(f)
  887. if ext in extensions:
  888. let x = changeFileExt(dir / name, ".nim")
  889. if fileExists(x):
  890. candidates.add x
  891. if ext == ".nimble":
  892. if nimblepkg.len == 0:
  893. nimblepkg = name
  894. # Since nimble packages can have their source in a subfolder,
  895. # check the last folder we were in for a possible match.
  896. if dir != prev:
  897. let x = prev / x.extractFilename()
  898. if fileExists(x):
  899. candidates.add x
  900. else:
  901. # If we found more than one nimble file, chances are that we
  902. # missed the real project file, or this is an invalid nimble
  903. # package. Either way, bailing is the better choice.
  904. return ""
  905. let pkgname = if nimblepkg.len > 0: nimblepkg else: pkgname
  906. for c in candidates:
  907. if pkgname in c.extractFilename(): return c
  908. if candidates.len > 0:
  909. return candidates[0]
  910. prev = dir
  911. dir = parentDir(dir)
  912. if dir == "": break
  913. return ""
  914. proc canonicalImportAux*(conf: ConfigRef, file: AbsoluteFile): string =
  915. ##[
  916. Shows the canonical module import, e.g.:
  917. system, std/tables, fusion/pointers, system/assertions, std/private/asciitables
  918. ]##
  919. var ret = getRelativePathFromConfigPath(conf, file, isTitle = true)
  920. let dir = getNimbleFile(conf, $file).parentDir.AbsoluteDir
  921. if not dir.isEmpty:
  922. let relPath = relativeTo(file, dir)
  923. if not relPath.isEmpty and (ret.isEmpty or relPath.string.len < ret.string.len):
  924. ret = relPath
  925. if ret.isEmpty:
  926. ret = relativeTo(file, conf.projectPath)
  927. result = ret.string
  928. proc canonicalImport*(conf: ConfigRef, file: AbsoluteFile): string =
  929. let ret = canonicalImportAux(conf, file)
  930. result = ret.nativeToUnixPath.changeFileExt("")
  931. proc canonDynlibName(s: string): string =
  932. let start = if s.startsWith("lib"): 3 else: 0
  933. let ende = strutils.find(s, {'(', ')', '.'})
  934. if ende >= 0:
  935. result = s.substr(start, ende-1)
  936. else:
  937. result = s.substr(start)
  938. proc inclDynlibOverride*(conf: ConfigRef; lib: string) =
  939. conf.dllOverrides[lib.canonDynlibName] = "true"
  940. proc isDynlibOverride*(conf: ConfigRef; lib: string): bool =
  941. result = optDynlibOverrideAll in conf.globalOptions or
  942. conf.dllOverrides.hasKey(lib.canonDynlibName)
  943. proc showNonExportedFields*(conf: ConfigRef) =
  944. incl(conf.globalOptions, optShowNonExportedFields)
  945. proc expandDone*(conf: ConfigRef): bool =
  946. result = conf.ideCmd == ideExpand and conf.expandLevels == 0 and conf.expandProgress
  947. proc parseIdeCmd*(s: string): IdeCmd =
  948. case s:
  949. of "sug": ideSug
  950. of "con": ideCon
  951. of "def": ideDef
  952. of "use": ideUse
  953. of "dus": ideDus
  954. of "chk": ideChk
  955. of "chkFile": ideChkFile
  956. of "mod": ideMod
  957. of "highlight": ideHighlight
  958. of "outline": ideOutline
  959. of "known": ideKnown
  960. of "msg": ideMsg
  961. of "project": ideProject
  962. of "globalSymbols": ideGlobalSymbols
  963. of "recompile": ideRecompile
  964. of "changed": ideChanged
  965. of "type": ideType
  966. else: ideNone
  967. proc `$`*(c: IdeCmd): string =
  968. case c:
  969. of ideSug: "sug"
  970. of ideCon: "con"
  971. of ideDef: "def"
  972. of ideUse: "use"
  973. of ideDus: "dus"
  974. of ideChk: "chk"
  975. of ideChkFile: "chkFile"
  976. of ideMod: "mod"
  977. of ideNone: "none"
  978. of ideHighlight: "highlight"
  979. of ideOutline: "outline"
  980. of ideKnown: "known"
  981. of ideMsg: "msg"
  982. of ideProject: "project"
  983. of ideGlobalSymbols: "globalSymbols"
  984. of ideDeclaration: "declaration"
  985. of ideExpand: "expand"
  986. of ideRecompile: "recompile"
  987. of ideChanged: "changed"
  988. of ideType: "type"
  989. of ideInlayHints: "inlayHints"
  990. proc floatInt64Align*(conf: ConfigRef): int16 =
  991. ## Returns either 4 or 8 depending on reasons.
  992. if conf != nil and conf.target.targetCPU == cpuI386:
  993. #on Linux/BSD i386, double are aligned to 4bytes (except with -malign-double)
  994. if conf.target.targetOS != osWindows:
  995. # on i386 for all known POSIX systems, 64bits ints are aligned
  996. # to 4bytes (except with -malign-double)
  997. return 4
  998. return 8