std:: Module Structure
This describes the intended organization and
build integration for std::. A first, minimal slice of the build integration
is implemented (auto-resolving std::... imports from a configurable stdlib
root), while most std APIs remain unimplemented.
This document defines how the standard library is organized and how it is made available to user programs.
Namespace Model#
-
std::is a reserved namespace root. -
The standard library is a distribution of modules whose module names begin with
std::...: -
std::buffer(currently implemented as a module; long-termBuffer(T)intrinsic; see buffer and buffers) -
std::graphics(low-level graphics API bindings; see graphics) -
std::window(opt-in high-level window application facade; see window) -
std::image(image codecs + color utilities; see image) -
std::gpu(pure-Silk host GPU facade) -
std::gpu::device(register-independent GPU device operations) -
std::gpu::isa(low-level AMDGPU device instruction surface) -
std::protobuf(Protocol Buffers wire helpers andsilk protoruntime support; see protobuf) -
std::xml(XML parsing; see xml) -
std::idl::web(current Web IDL parser; see idl web) -
std::js::ecma(current ECMAScript FFI surface; see js ecma) -
std::wasm(WebAssembly runtime API; see wasm) -
std::stream(Web Streams-inspired byte streams; see stream) -
std::runtime(runtime interface layer used by OS-facingstd::...modules; see runtime) -
Each source file in the stdlib declares which module it defines using a
moduledeclaration:module std::strings;
The compiler treats module/package names (including std::...) as part of the
module set dependency graph, as specified in packages imports exports.
std::runtime (Runtime Interface Layer)#
std::runtime is a dedicated namespace under std:: that defines low-level,
platform/environment primitives in a pluggable way.
Design intent:
- Higher-level
std::...modules (likestd::fs,std::task,std::sync) are written againststd::runtime::...interfaces. - The shipped stdlib provides a default hosted POSIX backend under
std::runtime::posix::...and the correspondingstd::runtime::...modules delegate to it. - Alternative stdlib roots can provide different runtime implementations (for
example Windows or embedded) without changing the public
std::...surface.
This layering is specified in runtime.
Linking by Default (Requirement)#
std:: must be linked by default for normal silk build workflows:
-
The compiler provides a default stdlib root (an implementation-defined directory shipped with the compiler distribution).
-
That root is automatically included in the compiler’s package/module search path during builds, so that:
import std::strings;
resolves without the user having to explicitly pass the stdlib source files on the command line.
Notes:
- This does not imply an implicit
import std::...;of all std modules; importing remains explicit. Linking-by-default means “std::is available to import”. - When the standard library is enabled (the default), the compiler provides a
small implicit std prelude of selected symbols (for example
Resultand thestd::interfacesinterface names) as specified bystd::runtime::globals. Use--nostdto disable this behavior. - The compiler should only compile/link the std modules that are reachable from
the user’s imports (and any internal dependencies), rather than eagerly
compiling all of
std::.
Swappability (Requirement)#
The default stdlib must be replaceable by an alternate implementation:
- The build configuration may override the stdlib root used for resolving
std::...imports. - A replacement stdlib is expected to provide compatible packages and exported
APIs under the same
std::...names. - The language and C ABI remain stable regardless of stdlib choice;
std::is ordinary Silk code and does not change core semantics.
The concrete selection mechanism is a compiler/driver responsibility and must be documented in the CLI (cli silk) and embedding ABI (abi libsilk) once implemented.
Current toolchain behavior (first slice):
- Both the
silkCLI and thelibsilk.aembedding build path resolvestd::...imports from a stdlib root selected by: - an explicit override (
--std-rootforsilk, orsilk_compiler_set_std_rootfor embedders), otherwise SILK_STD_ROOT(environment variable) when set, otherwise- a
std/directory in the current working directory (development default), otherwise ../share/silk/stdrelative to the current executable (installed default).- Mapping is deterministic:
std::foo::barresolves to<std_root>/foo/bar.slk.
Static Archive Distribution#
For distribution and incremental development, the stdlib can be built into a static archive for a specific target ABI:
make stdlibcompiles eachstd/**/*.slkmodule (includingstd/runtime/...) to a target object viasilk build --kind objectand archives the objects with defined external symbols intobuild/lib/silk/std/libsilk_std.a. Type-only, documentation-only, or inactive platform shim modules may still produce valid symbol-empty object files; those files are kept underbuild/lib/silk/std/obj/for object-generation coverage but are omitted from the archive because they cannot satisfy link-time references.- This archive is target-specific (for example ELF objects on
linux/x86_64or Mach-O objects onmacos/aarch64) and should be treated as one artifact per supported target triple/ABI, not as a universally portable library.
Current toolchain behavior (linux/x86_64):
- The compiler still loads stdlib Silk sources from the configured stdlib root
for parsing/type-checking (so the language-level package graph is validated),
but executable code generation treats auto-loaded
std::...modules as external and resolves their exported functions from the prebuilt archive when one is available. - Archive discovery (in order):
--std-lib <path>(or--std <path>.a/-std <path>.a) when provided, otherwiseSILK_STD_LIB(environment variable) when set,build/lib/silk/std/libsilk_std.awhen using the in-repostd/root (development),../lib/silk/std/libsilk_std.arelative to the installedsilkexecutable,../lib/libsilk_std.arelative to the installedsilkexecutable (legacy installed layout),- common installed-layout heuristics derived from the selected stdlib root.
Archive member naming (scheme):
- to avoid basename collisions (for example
std/task.slkandstd/runtime/posix/task.slk), archive member names are based on the std-root relative path with/replaced by_, and.slkreplaced by.o, - for example:
std/runtime/posix/task.slk→runtime_posix_task.o. - When no suitable archive is found (or on unsupported targets), the compiler falls back to compiling the reachable std sources into the build as part of module-set code generation.
--nostddisables stdlib auto-loading and therefore also avoids linking the default std archive; users may still explicitly provide their ownstd::...modules as ordinary inputs when desired.--std-root <path>(or--std <path>/-std <path>when<path>does not end in.a) selects an alternate stdlib root, and the corresponding archive is discovered via the same--std-lib/SILK_STD_LIBand installed-layout rules.
Hosted vs Freestanding#
The stdlib should be layered:
- A “core” subset that does not require OS services (collections, algorithms, string utilities, formatting, etc.).
- Hosted modules (
std::fs,std::net, parts ofstd::temporalandstd::io) that rely on POSIX syscalls or POSIX-like APIs.
This layering allows std:: to be used in freestanding environments while
still offering a full POSIX-oriented API when available.
Versioning and Compatibility#
The standard library is shipped with the compiler and should be versioned:
- Public, exported APIs under
std::...should follow semantic versioning. - A compiler may require a minimum stdlib version, and should report a clear error when an incompatible stdlib root is selected.
Source repository · Edit this page · View Markdown