docs: clarify Windows library link dependencies

This commit is contained in:
Chris Tate
2026-08-12 17:25:29 -05:00
parent 76929c9da1
commit 4934259ee1
4 changed files with 36 additions and 25 deletions
+17 -11
View File
@@ -1101,9 +1101,12 @@ async function ensureTlsArchive(
* units a library may reach are the pure-data ones (regex + the vendored matcher, assert,
* inspect, symbol, searchParams, emitter+dyn_handle, zlib); every
* loop-hooked or ambient unit was refused at SC4005 before emission.
* External-symbol contract: undefined references only to libc/libm — which
* is why zlib rides the VENDORED per-flavor objects here even on hosts
* (the executable lane's system `-lz` cannot ride inside an archive). */
* External-symbol contract: undefined references only to the target's C/math
* runtime and system APIs. Windows embedders additionally link advapi32,
* iphlpapi, and ws2_32; the platform driver supplies its ordinary CRT and
* kernel imports. Zlib rides the VENDORED per-flavor objects here even on
* hosts because the executable lane's system `-lz` cannot ride inside an
* archive. */
/** The library base: the executable lane's unconditional sources minus the
* fiber/loop and child-process units, plus the library-mode TU. */
@@ -1129,11 +1132,12 @@ export interface LibArchiveOptions {
* symbol. Toolchain sanitizer ABI remains external as required,
* so N archives built under pairwise-distinct prefixes link into one
* process with no symbol collisions and no shared mutable runtime state.
* Undefined references (libc/libm, plus sanitizer ABI in instrumented
* builds) keep their global binding. Omitted = the classic archive,
* byte-for-byte. Admitted for darwin/linux/win32 native hosts, linux and
* windows cross triples from any host, and macos cross triples from a
* darwin host (compileLibrary owns the refusal fence). */
* Undefined references (the target C/math runtime and system APIs, plus
* sanitizer ABI in instrumented builds) keep their global binding. Windows
* embedders additionally link advapi32, iphlpapi, and ws2_32. Omitted = the
* classic archive, byte-for-byte. Admitted for darwin/linux/win32 native
* hosts, linux and windows cross triples from any host, and macos cross
* triples from a darwin host (compileLibrary owns the refusal fence). */
localizeSymbols?: readonly string[];
/** Thread-instanced state (the profile's abi.instance_per_thread): every
* TU of the archive compiles with -DSCR_THREAD_INSTANCES, moving the
@@ -1559,9 +1563,11 @@ export async function compileLibArchive(opts: LibArchiveOptions): Promise<void>
* renamed apart — they stop being visible to the embedder's linker at all,
* so a second archive built under a different prefix brings its own private
* copy of the whole runtime (allocator, collector, arena, panic sink) into
* the same process. Undefined references (libc/libm, plus sanitizer ABI in
* instrumented builds) keep their global binding: the C library and
* sanitizer are the embedder's, shared by design.
* the same process. Undefined references (the target C/math runtime and
* system APIs, plus sanitizer ABI in instrumented builds) keep their global
* binding: those platform services and the sanitizer are the embedder's,
* shared by design. Windows embedders additionally link advapi32, iphlpapi,
* and ws2_32.
*
* Member selection matters: a classic archive's unused members (and their
* undefined references to units library mode excludes, like the
@@ -29,10 +29,11 @@
* symbol.
*
* Shared demotion rule (GNU objcopy --keep-global-symbols semantics):
* undefined references keep their global binding (libc/libm and sanitizer
* ABI are the embedder's by design), and COMMON symbols stay global —
* sanitizer image-registration guards are COMMONs whose merging across
* archives is the documented single-registration discipline. */
* undefined references keep their global binding (the target C/math runtime,
* system APIs, and sanitizer ABI are the embedder's by design), and COMMON
* symbols stay global — sanitizer image-registration guards are COMMONs whose
* merging across archives is the documented single-registration discipline.
* Windows embedders additionally link advapi32, iphlpapi, and ws2_32. */
const textDecoder = new TextDecoder();
const textEncoder = new TextEncoder();
+9 -6
View File
@@ -90,12 +90,15 @@
* runtime internals — allocator, cycle collector, result arena, panic-sink
* registration, every other piece of runtime state — are demoted to LOCAL
* symbols behind the profile's prefix, so an ordinary archive's only
* external definitions are the profile-declared symbols and its only
* external references are libc/libm. Sanitized artifacts additionally carry
* their sanitizer ABI; Darwin ASan's image-registration COMMON deliberately
* remains shared so the final Mach-O image registers its globals exactly
* once. N such archives, built under pairwise-distinct prefixes, then link
* into ONE process with no scriptc-runtime symbol collisions or shared
* external definitions are the profile-declared symbols. External references
* are the target's C/math runtime and system APIs: Windows embedders
* additionally link advapi32, iphlpapi, and ws2_32, while the platform driver
* supplies its ordinary CRT and kernel imports. Sanitized artifacts also
* carry their sanitizer ABI; Darwin ASan's image-registration COMMON
* deliberately remains shared so the final Mach-O image registers its
* globals exactly once. N such archives, built under pairwise-distinct
* prefixes, then link into ONE process with no scriptc-runtime symbol
* collisions or shared
* mutable state: each instance owns a private copy of the whole runtime,
* panic sinks register per instance, and a trap poisons only the instance it
* fired in. The embedder contract that makes this sound:
+5 -4
View File
@@ -10,8 +10,9 @@
* M1 symbols-exact nm over a localized archive: the external defined
* set equals the profile-declared set EXACTLY (plus
* ASan's one image-registration common in a
* sanitized build), and undefineds stay libc/libm-
* shaped apart from sanitizer ABI references
* sanitized build), and undefineds stay target-
* runtime/system-API-shaped apart from sanitizer ABI
* references
* M2 two-instance run the acceptance probe: two archives (ma_/mb_), two
* embedder threads (one per instance — the
* documented contract), independent init and
@@ -207,8 +208,8 @@ describe.each(EMISSIONS)("localized archive symbols, %s emission", (emission) =>
: [];
expect([...defined].sort()).toEqual([...declared, ...toolchainDefinitions].sort());
// Undefineds: no runtime-internal or prefix-carrying reference
// escapes; libc/libm (and sanitizer ABI) references keep their global
// binding.
// escapes; target-runtime/system-API (and sanitizer ABI) references
// keep their global binding.
expect([...undef].filter((s) => s.startsWith("scr_") || s.startsWith("ma_") || s.startsWith("mb_"))).toEqual([]);
// The ambient audit holds through the combine step: no
// process-disposition or threading surface, no atexit teardown.