mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-12 04:09:34 +00:00
56 lines
2.4 KiB
Nim
56 lines
2.4 KiB
Nim
#
|
|
#
|
|
# The Nim Compiler
|
|
# (c) Copyright 2026 Andreas Rumpf
|
|
#
|
|
# See the file "copying.txt", included in this
|
|
# distribution, for details about the copyright.
|
|
#
|
|
|
|
## Nim's OWN module-suffix, replacing nimony's `gear2/modnames.moduleSuffix`.
|
|
##
|
|
## nimony's version hashes a path made RELATIVE to `getCurrentDir()` (or the
|
|
## shortest search-path-relative form), so the produced suffix depends on the
|
|
## current working directory AND the searchPath set. Under `nim ic` the
|
|
## DISCOVERY pass (`deps.nim`, in the driver process) and the COMPILE pass
|
|
## (`nifgen`/`typekeys`, in a child `nim m` process) can run with different CWDs
|
|
## or `--path` sets, so the SAME file hashes to two different suffixes: e.g.
|
|
## `std/staticos` became `sta5rk8sn1` at discovery but `sta4c0qxk` at compile, so
|
|
## every importer waited forever for a `.s.bif` that was actually written under
|
|
## the other name — a cold `nim ic` build (of anything pulling in `std/os`, whose
|
|
## `oscommon` does `from std/staticos import PathComponent`) never converged.
|
|
##
|
|
## Hashing the CANONICAL ABSOLUTE path makes the suffix a pure function of the
|
|
## file, identical across every process and call site. The base-name prefix +
|
|
## base-36 `uhash` layout is kept byte-for-byte compatible with the old scheme so
|
|
## nothing but the hashed string changes.
|
|
|
|
import std/os
|
|
import "../dist/nimony/src/lib" / tinyhashes
|
|
|
|
const
|
|
PrefixLen = 3 # keep it short: the suffix ends up in every mangled C name
|
|
Base36 = "0123456789abcdefghijklmnopqrstuvwxyz"
|
|
|
|
proc moduleSuffix*(path: string; searchPaths: openArray[string]): string =
|
|
## `searchPaths` is accepted for signature-compatibility with the replaced
|
|
## `modnames.moduleSuffix` but is deliberately IGNORED — the suffix must not
|
|
## depend on the search-path set or the CWD (see the module doc).
|
|
# Absolute inputs (the norm at every call site: `toFullPath`/`projectFull`)
|
|
# pass straight through `normalizedPath` with no `getCurrentDir` involvement;
|
|
# a stray relative path is made absolute against the CWD only as a fallback.
|
|
var f = path
|
|
if not isAbsolute(f):
|
|
try: f = absolutePath(f)
|
|
except CatchableError: discard
|
|
f = normalizedPath(f)
|
|
let m = splitFile(f).name
|
|
var id = uhash(f)
|
|
result = newStringOfCap(10)
|
|
for i in 0 ..< min(m.len, PrefixLen):
|
|
result.add m[i]
|
|
# base-36 of the hash, low digit first (order is irrelevant for identity).
|
|
while id > 0'u32:
|
|
result.add Base36[int(id mod 36'u32)]
|
|
id = id div 36'u32
|