Precompiled config for the incremental compiler (nim ic).
nim ic builds the program by spawning one nim m child per module (or strongly-connected import group) plus a final nim nifc. Each child is a full Nim process, so each would normally re-read the whole nim.cfg chain and re-run config.nims through the VM — work that is identical for every child and, because of the VM run, far from free. With ~85 modules in the compiler itself that config work is paid ~85 times during koch bootic.
The fix mirrors Nimony's .cfg.nif: the driver parses config once, records the net effect, and the children replay it. Every config-file switch funnels through processSwitch(..., passPP, ...) (nimconf.parseAssignment and the switch() callback in scriptconfig), so the recorded sequence of those switches, replayed in order, reproduces an identical ConfigRef without any file read or VM run. The one config side effect that does not go through processSwitch is cppDefine (it mutates conf.cppDefines directly), so the resolved set is serialised alongside.
Path-search switches are deliberately excluded from the recording (see commands.processSwitch): their resolved result already lives in conf.searchPaths, which the driver forwards to every child as absolute --path arguments; replaying their raw, config-dir-relative arguments here would misresolve.
Consts
IcConfigVersion = "2"
- Artifact format version. Bump on any layout change here so a child built by an older compiler rejects a stale artifact and falls back to normal config loading instead of replaying a format it cannot parse. Source Edit
Procs
proc applyIcConfig(conf: ConfigRef; infile: string): bool {....raises: [ValueError, Exception, OSError, KeyError, IOError, ERecoverableError, EOFError], tags: [ ReadDirEffect, RootEffect, WriteIOEffect, ReadIOEffect, ReadEnvEffect, WriteDirEffect, WriteEnvEffect], forbids: [].}
- Replay the precompiled config into conf. Returns false (and applies nothing meaningful) when the artifact is missing or written by a compiler with an incompatible format version, so the caller can fall back to reading the config files normally. Source Edit
proc ensureIcConfig(conf: ConfigRef) {....raises: [OSError, IOError, ValueError, Exception, KeyError, ERecoverableError], tags: [ReadEnvEffect, ReadIOEffect, WriteDirEffect, ReadDirEffect, WriteIOEffect, RootEffect, ExecIOEffect, TimeEffect], forbids: [].}
- Driver-side (cmdIc). Make sure an up-to-date precompiled config exists, (re)producing it in a separate process when missing or stale, then point conf.icPreparsedConfig at it so the driver replays the very same config its nim m/nim nifc children will — perfect speed (config parsed at most once, skipped entirely when nothing changed) and consistency (one producer, every process replays its output). The artifact lives in the nimcache derived from the command line (pre-config-parse), which is the one the children are told; a --nimcache: set inside nim.cfg is recovered from the artifact itself. Source Edit
proc produceIcConfig(conf: ConfigRef) {....raises: [Exception, ValueError, OSError, KeyError, IOError, ERecoverableError], tags: [RootEffect, ReadDirEffect, WriteIOEffect, ReadIOEffect, ReadEnvEffect, WriteDirEffect], forbids: [].}
- The cmdIcConfig command. By the time it runs, the normal pipeline has already fully parsed the nim.cfg chain and run config.nims, so the resolved config is sitting in conf; just serialise it to --o. Source Edit
proc sourcesChanged(configFile: string): bool {....raises: [OSError, ValueError], tags: [ReadDirEffect, RootEffect], forbids: [].}
- True when the precompiled config at configFile is missing, malformed, written by an incompatible version, or any recorded config source file is newer than it (or has vanished) — i.e. the artifact must be regenerated. Mirrors nifler's sourcesChanged: the source list lives inside the artifact so this needs no out-of-band knowledge of which nim.cfgs were read. Source Edit
proc writeIcConfig(conf: ConfigRef; outfile: string) {....raises: [Exception], tags: [RootEffect], forbids: [].}
- Serialise the resolved config (the config-file switches recorded during loadConfigs, the resolved cppDefines/searchPaths, the nimcache dir, and the list of config source files for staleness detection) into outfile. OnlyIfChanged: when the content is byte-identical to what is already on disk the file is left untouched so its mtime does not advance — otherwise every nim ic run would re-fire the whole nifmake graph (see nifler's produceConfig, whose model this mirrors). Source Edit