Browse Source

G-140 achieved: linux lib-tier emission - cross-built tcllibc for punk9linux (punkshell 0.32.2)

suite_tcl90: critcl_zig.config gains the linux-x86_64-zig cross target
(zig cc -target x86_64-linux-gnu.2.17 - the dynamic-glibc floor decision,
recorded in the goal file and fed to G-105). build905.zig gains the
tcllibc-linux step (critcl driver on the windows suite shell, stubs
linkage, no linux host; uuid.tcl excluded matching upstream's own
native-linux package shape) gated by the new tools/elf_gate.tcl
(G-133-equivalent ELF64/LSB/ET_DYN/x86_64 structural check - the
load-smoke stand-in for cross lanes). library-artifacts emits
lib/linux-x86_64/tcllibc-tcl9-r<N>.zip in the same run: target =
linux-x86_64, build_host_platform = win32-x86_64, full provenance set,
deliberately no [tests] section. build_id seeds now include the tier
path so same-named artifacts in different target tiers get distinct
identity digests (both suites' tool copies kept byte-identical). Step
lists (build905.zig -Dsteps default, suite.tcl) and README document the
lane and invocation.

Consumption: libpackages.toml declares tcllibc-tcl9-linux (target
linux-x86_64); vendorlib_vfs.toml install.tcllibc_tcl9_linux switches
punk9linux.vfs/lib_tcl9 - replace retires the hand-dropped tcllibc,
supersedes removes the stray tcllibc2.0 - so the last provenance-less
accelerator hand-drops in any kit payload are gone. punkshell902 baked
(G-133 payload arch scan: 6/6 match target linux-x86_64) and
WSL-verified: materialized-tier accel smoke plus baked-kit smokes
(default paths + a pinned variant proving the kit's own lib_tcl9
artifact tree loads with the accelerator engaged). Finding recorded:
the tclkit-902 runtime bundles its own lib/tcllibc2.0 which wins
default precedence - the origin of the retired stray folder name.

Determinism: back-to-back re-emission byte-identical for all three
artifacts; the zig Run session-env cache finding extended (FOSSIL_HOME
and invocation mode churn the key; the linux ELF .so observed
bit-stable across critcl re-runs, unlike the windows PE). Goal flipped
achieved with evidence in the detail file; G-105 notes carry the libc
decision as prior art. Docs: buildsuites AGENTS.md child index,
ARCHITECTURE.md buildsuites paragraph, CHANGELOG + punkproject 0.32.2.

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 2 days ago
parent
commit
7fc15cd5ad
  1. 2
      ARCHITECTURE.md
  2. 16
      CHANGELOG.md
  3. 4
      GOALS-archive.md
  4. 3
      GOALS.md
  5. 22
      goals/G-105-buildsuite-cross-target.md
  6. 171
      goals/G-140-linux-lib-tier-emission.md
  7. 2
      punkproject.toml
  8. 6
      src/buildsuites/AGENTS.md
  9. 8
      src/buildsuites/suite_tcl86/tools/library_artifacts.tcl
  10. 36
      src/buildsuites/suite_tcl90/README.md
  11. 80
      src/buildsuites/suite_tcl90/build905.zig
  12. 53
      src/buildsuites/suite_tcl90/critcl_zig.config
  13. 22
      src/buildsuites/suite_tcl90/suite.tcl
  14. 93
      src/buildsuites/suite_tcl90/tools/elf_gate.tcl
  15. 8
      src/buildsuites/suite_tcl90/tools/library_artifacts.tcl
  16. 7
      src/runtime/libpackages.toml
  17. 20
      src/runtime/vendorlib_vfs.toml
  18. 767
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/critcl-rt.tcl
  19. 2
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms
  20. BIN
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so
  21. 4
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/pkgIndex.tcl
  22. 53
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/punkbin-artifact.toml
  23. 42
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/teapot.txt
  24. 381
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/critcl-rt.tcl
  25. 1
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/license.terms
  26. BIN
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/linux-x86_64/tcllibc.so
  27. 2
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/pkgIndex.tcl
  28. 21
      src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/teapot.txt

2
ARCHITECTURE.md

@ -94,7 +94,7 @@ Two layers with a deliberate dependency direction (the class never depends on th
- **Boot-precondition gate (G-125).** A bake refuses a kit whose merged `.vfs` supplies no tcl library rather than deploying an artifact that cannot initialise: the kit lands in `FAILED KITS` and nothing is written, so the previously deployed `bin/<kit>` survives. Structural and non-executing (so cross-target kits are covered), reading the merged tree rather than the extraction outcome. The predicate is `punkboot::utils::vfs_boot_library_report`, called through the same guarded require as the provenance check so a stale bootsupport snapshot degrades it to a notice; `make.tcl check` reports ACTIVE/UNAVAILABLE. Sources: `src/AGENTS.md`, `src/modules/punkboot/utils-999999.0a1.0.tm`.
- **Payload/target consistency checks (G-133 + G-134), all advisory.** At the same post-merge seam, a bake classifies each binary library in the merged tree by header (`punkboot::utils::binary_arch_classify` - PE/ELF/Mach-O, honest unknowns) against the kit's target platform; wrong-arch libraries outside platform-discriminated subdirs (canonical `<os>-<cpu>` names, vendor spellings like `win-x64`) earn recapped `BUILD-WARNING`s. After assembly, a kit declaring smoke-require packages (`mapvfs.config` 5th entry element) has each one plain-`package require`d inside the freshly built artifact via its tclsh subcommand - the only check that sees resolution-order defects (wrong-arch version shadowing); cross-target kits skip with a stated reason. The assembled image is also probed for its zip offset convention (G-134, `punkboot::utils::kit_offsetstyle_report` over `punk::zip::archive_info`): a FILE-relative attached payload warns (the pipeline emits archive-relative; the G-128 stamper refuses file-relative by default), no-zip/plain results stay silent. Same guarded-require degradation; `make.tcl check` reports all three. None guarantees statics, pure-tcl packages with binary deps, or version preference beyond the declared smoke set. Sources: `src/AGENTS.md`, `src/runtime/AGENTS.md`, `src/modules/punkboot/utils-999999.0a1.0.tm`.
- **Kit icon step (G-057 + G-128).** Every kit a bake builds gets a `<kitname>.resources.toml` sidecar (deployed beside `bin/<kit>`) recording the build-time icon choice - default `src/runtime/punkshell.ico`, overridable by a root `punkshell.ico` in the kit's own custom `.vfs` folder (pre-merge) - with sha256 identity and provenance lifted from the icon's G-135 assetorigin record. win32-target kits get the icon embedded as PE `RT_ICON`/`RT_GROUP_ICON` behind a single seam (`::punkboot::kit_icon_process`): the vendored punkres portable stamper (`src/tools/punkres`, built to `bin/punkres(.exe)` by the make.tcl tool step) is selected when present and works from any build host; otherwise the twapi arm (tcl-sfe mechanism) serves windows hosts with nothing built. Both arms share one semantic (delete all icon/group entries, write ids 1..N; the group is NAMED from the icon file's uppercased rootname - `PUNKSHELL` - with language adopted from the replaced group) and stamp a per-kit copy of the payload-free raw runtime prefix BEFORE payload attach; punkres can also stamp a FINISHED kit post-hoc, preserving an appended zip payload (archive-relative moved verbatim; file-relative refused by default, shifted with a consent flag). Non-PE targets skip as not applicable; a host where neither mechanism serves skips with a combined notice naming the punkres build remedy; the sidecar is written in every case. Sources: `src/AGENTS.md`, `bin/AGENTS.md`, `src/vfs/AGENTS.md`, `src/tools/AGENTS.md`.
- **Buildsuites and the kit family.** `src/buildsuites/suite_tcl90/` builds Tcl/Tk/tcllib from source with a pinned zig toolchain and produces the runtime kit family (plain / punk / bi) plus artifact metadata (G-096-G-117 era: see archived goals G-096, G-098, G-102, G-103, G-107); artifacts publish to the punkbin repo that `bin/punk-runtime.cmd` fetches from. Both suites also emit the punkbin LIBRARY tier (G-138, achieved): verified tcllib/tcllibc installs as generation-tagged immutable zips (`lib/allplatforms` + `lib/<target>`, embedded schema-v2 class=library records, punkzip-deterministic) - the `library-artifacts` step in each recipe. Consumption (G-139, achieved): `make.tcl libfetch` materializes declared artifacts into the untracked `bin/packages/<target>` tier with server-trust consent, and the PACKAGES_tcl<N> libs phase + vfslibs packages-root declarations feed the deployed `lib_tcl<N>` trees and kit vfs payloads - the vendored tcllib trees are retired, and embedded records ride into baked kits. `src/buildsuites/suite_tcl86/` is the 8.6 sibling (G-099 + G-100, both achieved): a Tcl 8.6 windows runtime (static + dynamic shells, `tcl86t.dll`, on-disk lib tree - no zipfs, so no self-contained kit) with thread 2.8 + tclvfs + Tk 8.6 + tklib + tcllib(+tcllibc critcl accelerators) companions, gated against the 8.6 core/thread/tclvfs testsuites with tcllib/tklib on a record tier and an opt-in `test-tk`; punkshell's own runtests is censused on that runtime at parity with a same-day native-8.6 baseline. Suite child shells scrub `TCL<major>_<minor>_TM_PATH` as well as TCLLIBPATH/TCL_LIBRARY/TK_LIBRARY - without it a census measures the machine's module trees. The 8.6 kit container strategy remains in-flux - see "In-flux areas".
- **Buildsuites and the kit family.** `src/buildsuites/suite_tcl90/` builds Tcl/Tk/tcllib from source with a pinned zig toolchain and produces the runtime kit family (plain / punk / bi) plus artifact metadata (G-096-G-117 era: see archived goals G-096, G-098, G-102, G-103, G-107); artifacts publish to the punkbin repo that `bin/punk-runtime.cmd` fetches from. Both suites also emit the punkbin LIBRARY tier (G-138, achieved): verified tcllib/tcllibc installs as generation-tagged immutable zips (`lib/allplatforms` + `lib/<target>`, embedded schema-v2 class=library records, punkzip-deterministic) - the `library-artifacts` step in each recipe. The tier's `<target>` axis includes cross-built lanes: suite_tcl90's `tcllibc-linux` step (G-140, achieved) cross-builds the critcl accelerators for linux-x86_64 via critcl driving `zig cc -target` (stubs linkage - no linux host involved), structurally ELF-gated on the build host and consumed by the punk9linux kit payload. Consumption (G-139, achieved): `make.tcl libfetch` materializes declared artifacts into the untracked `bin/packages/<target>` tier with server-trust consent, and the PACKAGES_tcl<N> libs phase + vfslibs packages-root declarations feed the deployed `lib_tcl<N>` trees and kit vfs payloads - the vendored tcllib trees are retired, and embedded records ride into baked kits. `src/buildsuites/suite_tcl86/` is the 8.6 sibling (G-099 + G-100, both achieved): a Tcl 8.6 windows runtime (static + dynamic shells, `tcl86t.dll`, on-disk lib tree - no zipfs, so no self-contained kit) with thread 2.8 + tclvfs + Tk 8.6 + tklib + tcllib(+tcllibc critcl accelerators) companions, gated against the 8.6 core/thread/tclvfs testsuites with tcllib/tklib on a record tier and an opt-in `test-tk`; punkshell's own runtests is censused on that runtime at parity with a same-day native-8.6 baseline. Suite child shells scrub `TCL<major>_<minor>_TM_PATH` as well as TCLLIBPATH/TCL_LIBRARY/TK_LIBRARY - without it a census measures the machine's module trees. The 8.6 kit container strategy remains in-flux - see "In-flux areas".
- **Project generation.** `dev project.new` composes thin layouts from `src/project_layouts/` (overlay chain with `.anti` deletion markers and `name@base` derivation - G-087, achieved) and injects bootsupport modules from the generating shell at generation time.
- **Workflow overview.** `tclsh src/make.tcl workflow` prints the embedded ASCII data-flow overview of the build/release pipeline, with its own update contract in `src/AGENTS.md`. This section deliberately summarises rather than copies it.

16
CHANGELOG.md

@ -5,6 +5,22 @@ The latest `## [X.Y.Z]` header must match the `version` field in `punkproject.to
Entries are newest-first; one bullet per notable change. See the root `AGENTS.md`
"Project Versioning" section for the bump policy.
## [0.32.2] - 2026-07-30
- Linux lib-tier emission (G-140, achieved): suite_tcl90 gains a `tcllibc-linux`
step cross-building the tcllib critcl accelerators for linux-x86_64 (critcl
driving `zig cc -target x86_64-linux-gnu.2.17` - dynamic-glibc floor, stubs
linkage, no linux build host), structurally ELF-gated on the build host
(`tools/elf_gate.tcl`) and emitted as `lib/linux-x86_64/tcllibc-tcl9-r<N>.zip`
by the `library-artifacts` step. The punkshell902 (punk9linux) kit payload now
ships this artifact-fed tcllibc with its embedded punkbin record - the
hand-dropped tcllibc + stray tcllibc2.0 folders are retired
(`libpackages.toml` + `vendorlib_vfs.toml` declarations; accelerator engage
verified under WSL for both the materialized tier and the baked kit).
- library_artifacts build_id seeds now include the tier path so same-named
artifacts in different target tiers (win32/linux tcllibc) get distinct
identity digests.
## [0.32.1] - 2026-07-30
- `make.tcl libfetch` gains env-only isolation seams: `PUNK_LIBFETCH_CONFIG`

4
GOALS-archive.md

@ -246,3 +246,7 @@ Acceptance: an emission step produces punkbin-layout library artifacts from veri
### G-139 [achieved 2026-07-30] Consume punkbin library artifacts: fetch/materialize tier replacing vendored tcllib/tcllibc → detail: goals/archive/G-139-punkbin-library-consumption.md
Scope: src/make.tcl (consent-gated library fetch entrypoint; libs step consuming the packages tier; vfslibs as touched); bin/packages/<target>/ (new untracked materialization tier mirroring bin/runtime/<tier>/); src/runtime/vendorlib_vfs.toml (tcllib/tcllibc kit-vfs declarations with supersedes removal of the legacy versions); src/vendorlib_tcl8/win32-x86_64/tcllib1.21 + src/vendorlib_tcl9/win32-x86_64/tcllib2.0 (retirement targets); src/vfs/*.vfs lib_tcl<N> trees (kit payload switchover incl. the punk86-family tcllib 2.0 upgrade); lib_tcl8/ + lib_tcl9/ (deployed-tree materialization targets); user-config consent (server-trust pattern shared with G-123/G-006)
Acceptance: a make.tcl entrypoint fetches declared library artifacts from the punkbin lib tier into bin/packages/<target>/ with sha1 verification and beside-toml metadata (consent keyed to server trust per the G-123 posture - fetches from the canonical origin prompt nothing new); the libs step materializes lib_tcl<N>/allplatforms and lib_tcl<N>/<platform> from that tier with punkcheck-tracked provenance; tcllib and tcllibc enter src/runtime/vendorlib_vfs.toml (or its G-115/G-024 successor) declarations so the declared kit vfs trees receive them, with supersedes removing tcllib1.21 (including its nested tcllibc 0.4 and md5c) from the 8.6-family kits; the punk86-family upgrade to tcllib 2.0 + a current tcllibc is validated by kit-hosted runtests against a same-day baseline with every difference dispositioned; the vendored src/vendorlib_tcl8/win32-x86_64/tcllib1.21 and src/vendorlib_tcl9/win32-x86_64/tcllib2.0 trees are removed from the tracked tree once a bake fed from the artifact path reproduces working kits; a bake on a checkout without those trees (fetch consented or bin/packages pre-populated) ships kits whose tcllib/tcllibc provenance is verifiable from the embedded records; the derived-project decision is recorded in this file (fetch via the same entrypoint as the default - the copy-and-tweak in-project suite build per G-104's self-description contract remains the documented alternative).
### G-140 [achieved 2026-07-30] Linux lib-tier emission: cross-built tcllibc (zig cc -target) for the punk9linux payload → detail: goals/archive/G-140-linux-lib-tier-emission.md
Scope: src/buildsuites/suite_tcl90/ (critcl_zig.config linux target section; build905.zig cross-target library-artifacts lane; tools as touched); src/runtime/libpackages.toml + src/runtime/vendorlib_vfs.toml (linux-x86_64 artifact + kit-vfs declarations); src/vfs/punk9linux.vfs/lib_tcl9 (hand-dropped tcllibc + stray tcllibc2.0 - retirement targets); punkbin artifact repo (external, c:/repo/jn/punkbin - new lib/linux-x86_64 target folder); bin/packages/linux-x86_64/ (tier target as materialized); WSL verification (testsupport/wslprobe.tcl patterns + a punkbin linux-x86_64 Tcl 9 runtime as the smoke interpreter)
Acceptance: a documented suite_tcl90 invocation produces lib/linux-x86_64/tcllibc-tcl9-r<N>.zip from a critcl build driving zig cc via an explicit linux target section in critcl_zig.config (the win32-x86_64-zig pin pattern; no linux host in the build path), with the embedded record carrying target = linux-x86_64, build_host_platform = the actual build host, and the G-138 provenance set (checkout uuids, critcl version, zig version, optimize mode, driving-shell patchlevel); the contained shared library classifies as ELF x86-64 by a host-side structural check (the G-133 classifier or equivalent, recorded here); re-emission over an unchanged build is byte-identical; the libc/triple decision (dynamic glibc with a pinned version floor vs musl-dynamic - the .so must dlopen into existing glibc-dynamic linux tclsh builds without mixing libcs) is made and recorded here with rationale, explicitly feeding the G-105 decision item rather than re-deciding it later; a WSL (or native linux) smoke on the MATERIALIZED artifact tree under a linux-x86_64 Tcl 9 runtime (e.g. the punkbin tclkit-902 artifact) proves package require md5 engages the critcl accelerator from the tree (evidence recorded here); consumption lands via libpackages.toml (target linux-x86_64) and a vendorlib_vfs.toml entry switching punk9linux.vfs/lib_tcl9 with supersedes/replace retiring the hand-dropped tcllibc and tcllibc2.0; a punkshell902 bake ships the artifact-fed tree with its embedded record present in the kit payload, and a WSL run of the baked kit loading md5 with the accelerator engaged is recorded; publication to the real punkbin repo remains a deliberate user step (build_sha1sums.tcl already handles arbitrary lib/<target> folders); the tcl8-generation question is dispositioned (no linux tcl8 kit exists - recorded as out of the committed set, with the mechanism staying package-generic and generation-generic by construction).

3
GOALS.md

@ -407,6 +407,3 @@ Detail: goals/G-136-generated-project-icon-seeding.md
Scope: src/tools/punkres/ (VS_VERSIONINFO construction, set-version + field-level read-back - upstream at c:/repo/jn/zig/punkres); src/make.tcl (version stamping at the G-057/G-128 kit-icon seam, punkres arm); bin/*.resources.toml sidecar format + bin/AGENTS.md (version fields and status vocabulary); punkproject.toml (field source - configurable overrides); src/tests/ (characterization)
Detail: goals/G-137-kit-version-resources.md
### G-140 [proposed] Linux lib-tier emission: cross-built tcllibc (zig cc -target) for the punk9linux payload
Scope: src/buildsuites/suite_tcl90/ (critcl_zig.config linux target section; build905.zig cross-target library-artifacts lane; tools as touched); src/runtime/libpackages.toml + src/runtime/vendorlib_vfs.toml (linux-x86_64 artifact + kit-vfs declarations); src/vfs/punk9linux.vfs/lib_tcl9 (hand-dropped tcllibc + stray tcllibc2.0 - retirement targets); punkbin artifact repo (external, c:/repo/jn/punkbin - new lib/linux-x86_64 target folder); bin/packages/linux-x86_64/ (tier target as materialized); WSL verification (testsupport/wslprobe.tcl patterns + a punkbin linux-x86_64 Tcl 9 runtime as the smoke interpreter)
Detail: goals/G-140-linux-lib-tier-emission.md

22
goals/G-105-buildsuite-cross-target.md

@ -138,10 +138,18 @@ goals/archive/G-100-suite-tcl86-tk-tcllib.md), G-102 (achieved 2026-07-21 - driv
- G-110 relationship: its extraction-cache decision determines whether the
per-platform temp-copy cleanup characterized in these notes stays a wart or
gets replaced - the linux leg of this goal's verification feeds its evidence.
- G-140 relationship (drafted 2026-07-30): a deliberately narrower zig
-target lane landing first - cross-built linux-x86_64 tcllibc via the
library-artifacts machinery (stubs linkage, no cross-built runtime
needed). Its recorded libc/triple decision (dynamic glibc floor vs
musl-dynamic for a dlopen-able .so) is direct input to this goal's
dynamic-libc and triple<->canon items - take it as prior art at
activation rather than re-deciding.
- G-140 relationship (achieved 2026-07-30 - see
goals/archive/G-140-linux-lib-tier-emission.md): a
deliberately narrower zig -target lane that landed first - cross-built
linux-x86_64 tcllibc via the library-artifacts machinery (stubs
linkage, no cross-built runtime needed). Its libc/triple decision is
DECIDED and recorded there: dynamic glibc, zig triple
x86_64-linux-gnu.2.17 (musl rejected - a musl .so inside the
glibc-dynamic consumer runtimes mixes libcs; 2.17 = conservative
CentOS7-era floor, in zig 0.16.0's bundled stub list, verified under
WSL glibc 2.39). Direct prior art for this goal's dynamic-libc and
triple<->canon items - take it at activation rather than re-deciding.
Also relevant: the critcl config 'platform' identifier must stay
platform::generic-shaped (linux-x86_64) for critcl's MapPlatform
loader, with the glibc floor riding only the triple - see the G-140
detail file's mechanism notes.

171
goals/G-140-linux-lib-tier-emission.md

@ -1,6 +1,6 @@
# G-140 Linux lib-tier emission: cross-built tcllibc (zig cc -target) for the punk9linux payload
Status: proposed
Status: achieved 2026-07-30
Scope: src/buildsuites/suite_tcl90/ (critcl_zig.config linux target section; build905.zig cross-target library-artifacts lane; tools as touched); src/runtime/libpackages.toml + src/runtime/vendorlib_vfs.toml (linux-x86_64 artifact + kit-vfs declarations); src/vfs/punk9linux.vfs/lib_tcl9 (hand-dropped tcllibc + stray tcllibc2.0 - retirement targets); punkbin artifact repo (external, c:/repo/jn/punkbin - new lib/linux-x86_64 target folder); bin/packages/linux-x86_64/ (tier target as materialized); WSL verification (testsupport/wslprobe.tcl patterns + a punkbin linux-x86_64 Tcl 9 runtime as the smoke interpreter)
Goal: the punkbin lib tier serves a linux-x86_64 tcllibc built by the existing
windows suite - critcl driving zig cc with an explicit linux target (stubs
@ -122,6 +122,43 @@ linux runtime punkbin already hosts.
reviewed at landing - a library cross-build does not flip the runtime
buildsuite axis ('planned' per G-105); whether the lib tier axis needs a
value update is settled in the work.
- Related: G-127 - cross-target bake output goal; its acceptance names
punk9linux.vfs migration to declarations and the linux punkshell902 kit's
intended move to bin/kits/linux-x86_64/. This goal's punkshell902 bake
rides today's output layout; G-127 owns relocating it.
- Related: G-115 - vendorlib_vfs.toml successor surface (declarative .vfs
composition); the consumption declarations here ride whichever surface is
current, per the G-139 precedent.
- Activation survey 2026-07-30: goals_xref score G-140 re-run at activation
(user-directed, same day as drafting): two real overlaps beyond the
drafting survey recorded above (G-127, G-115 - both vendorlib_vfs.toml /
punk9linux.vfs surfaces); remaining unlinked pairs (G-023/G-016/G-022/
G-006/G-005) share only ubiquitous anchors, no contract relationship.
- LIBC/TRIPLE DECISION (2026-07-30, the acceptance's recorded decision -
feeds G-105's dynamic-libc analysis): dynamic glibc via zig triple
x86_64-linux-gnu.2.17. Rationale: the concrete consumers (punkbin
tclkit-902-Linux64-intel-dyn - verified ELF x86-64 with interpreter
/lib64/ld-linux-x86-64.so.2, i.e. glibc-dynamic - and any suite-family
linux runtime G-105 later produces) are glibc processes, so a musl .so
would mix two libcs in one process (rejected); static-musl is not an
option for a dlopen'd extension anyway. 2.17 is the conservative
CentOS7-era floor: comfortably below every candidate consumer distro
(WSL Ubuntu 22.04/24.04 = glibc 2.35/2.39, AlmaLinux 9 = 2.34) and
present in the pinned zig 0.16.0's bundled glibc-stub list (verified via
'zig targets'). The floor rides ONLY the zig triple; the in-package
platform folder stays glibc-agnostic (next note).
- critcl cross-target mechanism (2026-07-30 finding): the config section's
'platform' value becomes critcl's targetplatform/actualtarget, which
names BOTH the in-package shared-lib folder and teapot's 'Meta platform'
on cross builds (TeapotPlatform upgrades to platform::identify - the
glibc-versioned form - only when building natively). The generated
loader resolves the folder via ::critcl::runtime::MapPlatform =
platform::generic, so the folder must be 'linux-x86_64', NOT a
glibc-versioned name. The retired hand-drop confirms the shape: folder
linux-x86_64 with teapot 'Meta platform linux-glibc2.22-x86_64' (a
native linux critcl 3.3 build, 2025-08-20 vintage). Our cross build
records teapot 'Meta platform linux-x86_64' - truthful (any glibc >=
floor), with the exact floor in the artifact record + this file.
- Overlap survey 2026-07-30 (drafting): goals_xref paths
src/buildsuites/suite_tcl90, src/vfs/punk9linux.vfs,
src/runtime/libpackages.toml, src/runtime/vendorlib_vfs.toml,
@ -130,3 +167,135 @@ linux runtime punkbin already hosts.
G-108/G-110/G-131 (suite-tree co-location only, no contract
relationship), G-004/G-065/G-025 (posture, carried or not applicable);
no live goal owns the punk9linux tcllibc hand-drops.
## Progress
- 2026-07-30 activated (user-directed); emission side LANDED and verified:
- critcl_zig.config linux-x86_64-zig section (zig cc -target
x86_64-linux-gnu.2.17, sharedlibext .so, platform identifier
linux-x86_64 - mechanism + libc decision notes above).
- build905.zig `tcllibc-linux` step (in the default step lists,
suite.tcl + -Dsteps parity): the native critcl invocation with
-target linux-x86_64-zig, own cache/libdir outputs, installed to
out/lib-linux-x86_64/tcllibc; gated by tools/elf_gate.tcl (new,
self-contained: the G-133 classifier's ELF checks - magic, EI_CLASS
64, EI_DATA LSB, e_machine x86_64 - plus e_type ET_DYN; an empty tree
fails). Gate PASS: linux-x86_64/tcllibc.so ELF64 LSB ET_DYN x86_64.
- uuid finding: tcllib uuid.tcl's accelerator is WINDOWS-ONLY C (rpcrt4
UuidCreate behind a tcl_platform(platform)=="windows" guard evaluated
in the critcl DRIVER) - first cross attempt failed on windows.h. The
lane EXCLUDES uuid/uuid.tcl, reproducing upstream's own native-linux
package shape (the guard is false there; uuid rides its pure-tcl path
which uses the md5 accelerator). Installed shape verified identical
to the hand-drop's (folder set + linux-x86_64/tcllibc.so + teapot
'Meta platform linux-x86_64').
- library-artifacts emission extended with the third 5-tuple: emitted
lib/linux-x86_64/tcllibc-tcl9-r1.zip (8 members, ~139KB) beside the
native artifacts, per-tier sha1sums incl. the new linux-x86_64 tier.
Record verified: target=linux-x86_64, build_host_platform=
win32-x86_64, tcllib+critcl checkout uuids, critcl 3.3.1 (from the
cross build's own teapot.txt), zig 0.16.0, ReleaseFast,
driving_tcl_patchlevel 9.0.5; NO [tests] section (the G-107 evidence
(achieved - goals/archive/G-107-buildsuite-library-tests.md) attaches
to the win32 accelerators the tests exercised - the linux functional
evidence is the WSL smoke below).
- build_id seed fix (both suites' library_artifacts.tcl copies, kept
byte-identical): the seed now includes the tier path
(lib/<tier>/<artifact>) - same-named artifacts in different target
tiers (the win32/linux tcllibc pair) previously would have shared an
identity digest. Published r1 records keep their build_ids
(immutable); local re-emissions at r1 now differ from published r1
bytes in that field - immaterial: revisions never re-publish.
- Determinism VERIFIED: two direct back-to-back `zig build
library-artifacts` runs over the unchanged build produced
byte-identical zips for ALL THREE artifacts (linux e5e7bb0c...
twice). Session-env finding EXTENDED: the zig Run cache keys the
inherited env - beyond PATH (the recorded G-138 trap), suite.tcl
itself sets FOSSIL_HOME, so a suite.tcl-driven emission and a direct
`zig build` emission are DIFFERENT cache sessions; the first
invocation in a new env re-runs critcl/installers and drifts the
native (non-bit-reproducible) dll bytes and install mtimes. The
linux ELF .so was observed BIT-STABLE across such re-runs (sha
96843110... constant) - windows PE non-reproducibility does not
carry over; the zip-level drift across env changes comes from
re-install mtimes. Publish discipline unchanged.
- Documented invocation (also in the suite README "Linux cross lane"
section): `tclsh suite.tcl build` (defaults) or explicit -steps
including tcllibc-linux + library-artifacts.
- 2026-07-30 consumption phase 1 + WSL MATERIALIZED-TREE SMOKE (the
acceptance's functional evidence):
- libpackages.toml gained [artifact.tcllibc-tcl9-linux] (name
tcllibc-tcl9-r1.zip, target linux-x86_64). libfetch is
target-generic; materialized via the PUNK_LIBFETCH_CONFIG seam
(linux-only declarations) from a file:// mirror of the suite staging
with -trust-server -> bin/packages/linux-x86_64/tcl9/tcllibc
(fetched + sha1-verified + materialized; the published-r1-matching
allplatforms/win32 tier copies deliberately untouched).
- WSL smoke PASS (default distro Ubuntu 24.04, glibc 2.39; runtime
bin/runtime/linux-x86_64/tclkit-902-Linux64-intel-dyn = Tcl 9.0.2):
staged the materialized tcllibc + tcllib2.0 trees to WSL-native
/tmp (wslprobe staging pattern - one-way copy-in, never operating
on the checkout), auto_path with the staged lib prepended;
`package require md5` -> md5 2.0.9 from the staged tcllib2.0,
tcllibc 2.0 loaded from
.../lib/tcllibc/linux-x86_64/tcllibc.so (MapPlatform resolved the
linux-x86_64 folder), accel(critcl)=1, md5 -hex correct
(5EB63BBB...); self-gating assertions on all resolution paths
passed (SMOKE-OK). Note: wholesale auto_path REPLACEMENT breaks the
kit's own auto_load/tm chain (::tcl::tm::UnknownHandler resolves via
auto_index) - prepend + path assertions is the working pattern.
- 2026-07-30 consumption phase 2: kit switchover + BAKE + BAKED-KIT WSL
SMOKES:
- vendorlib_vfs.toml [install.tcllibc_tcl9_linux]: source_root=packages,
source linux-x86_64/tcl9/tcllibc, target punk9linux.vfs/lib_tcl9,
replace=true + supersedes tcllibc2.0. vfslibs run: superseded
'tcllibc2.0' REMOVED, hand-dropped 'tcllibc' clean-slate REPLACED by
the artifact-fed tree (embedded record present; .so byte-identical to
the tier copy, sha 96843110...). The last provenance-less accelerator
hand-drops in any kit payload are retired.
- Selective bake punkshell902 (tclkit-902-Linux64-intel-dyn +
punk9linux.vfs, metakit container): shipped bin/punkshell902. The
bake's own G-133 payload binary-arch scan for target linux-x86_64: OK
- 6 binary libraries scanned, 6 match target, 3 exempt under platform
subdirs, 0 unclassifiable (our tcllibc.so among the scanned). G-122
cross-target handling engaged (icon N/A for non-PE, process sweep and
smoke-require skipped as cross-target).
- WSL baked-kit smoke A (default paths): './punkshell902 script ...'
under the default WSL distro - md5 2.0.9 + tcllibc 2.0,
accel(critcl)=1, correct digest; embedded record read from the kit
payload's lib_tcl9/tcllibc/punkbin-artifact.toml and field-checked
(name/target/build_id/build_host_platform). FINDING: the loaded .so
was the RUNTIME's own bundled copy at lib/tcllibc2.0/ - the
tclkit-902 runtime carries tcllibc inside its attached vfs under the
stray-versioned folder name, which explains where the retired
punk9linux tcllibc2.0 hand-drop name CAME from, and that copy wins
default package-path precedence over the kit tree's lib_tcl9.
- WSL baked-kit smoke B (pinned): fresh kit process, package forget +
auto_path pinned to the kit's OWN lib_tcl9 - the artifact-fed
<kit>/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so LOADED (info loaded
path assertion), accel(critcl)=1, md5 correct, md5 resolved from the
kit tree (SMOKE-OK-PINNED). So the shipped artifact tree is proven
functional from inside the baked kit, while the runtime's bundled
copy shadows it on default paths - relevant when pairing the _basic
runtime variant (no bundled batteries), where the kit tree is the
only provider.
- 2026-07-30 dispositions + reviews (acceptance items):
- tcl8 generation: OUT of the committed set - no linux tcl8 kit exists
(no mapvfs entry pairs a linux runtime with a tcl8 vfs). The
mechanism stays package-generic and generation-generic by
construction: suite_tcl86 shares the byte-identical
library_artifacts.tcl (including the tier-in-build_id-seed change),
and a future linux tcl8 lane would be the same config-section +
critcl-step + 5-tuple pattern.
- punk::platform axes review: NO value changes needed. linux-x86_64
already carries tiers {runtime lib} (the lib axis covers
lib_tclX/<platform> trees - now artifact-fed); buildsuite stays
'planned' - that axis describes RUNTIME production (G-105), which a
library cross-build deliberately does not flip.
- Publication: remains the deliberate user step. The emitted artifacts
sit in suite staging out/library/punkbin/lib/linux-x86_64/ (zip +
sidecar + per-tier sha1sums; revision r1 unbumped - nothing new
published this goal). punkbin's build_sha1sums.tcl already handles
arbitrary lib/<target> folders (G-138). After publication, the
already-declared libpackages.toml entry serves plain canonical
'make.tcl libfetch' with no further edits.

2
punkproject.toml

@ -1,4 +1,4 @@
[project]
name = "punkshell"
version = "0.32.1"
version = "0.32.2"
license = "BSD-2-Clause"

6
src/buildsuites/AGENTS.md

@ -39,8 +39,10 @@ this project's `src/` tree.
## Child DOX Index
- `suite_tcl90/` - Tcl 9.0 suite (its README.md carries lineage/detail,
including the G-138 `library-artifacts` punkbin lib-tier emission; no
child AGENTS.md yet)
including the G-138 `library-artifacts` punkbin lib-tier emission and the
G-140 `tcllibc-linux` cross lane - critcl driving zig cc -target for the
linux-x86_64 lib tier, ELF-gated on the windows host; no child AGENTS.md
yet)
- `suite_tcl86/` - Tcl 8.6 suite (G-099 achieved 2026-07-26: tclsh86ts/tclsh86t
+ tcl86t.dll + lib tree, thread 2.8.13 + tclvfs 1.4.2, core/thread/tclvfs
gates; G-100 achieved 2026-07-26: Tk 8.6.17 + tklib 0.9 + tcllib 2.0/tcllibc,

8
src/buildsuites/suite_tcl86/tools/library_artifacts.tcl

@ -314,8 +314,12 @@ foreach {folder tier license testlibs pkgpath} $opt(-packages) {
#deterministic build_id (uuid-shaped sha1 digest of stable identity inputs -
#same input family as the runtime records: name, toolchain/optimize, driving
#patchlevel, per-member source checkout uuids)
set idseed "punkbin-artifact|$artifact|zig $opt(-zig)|$opt(-optimize)|tcl$opt(-tclpatch)|$provpairs"
#patchlevel, per-member source checkout uuids). The tier rides the seed as
#the artifact's repo path: same-NAMED artifacts exist in different target
#tiers (win32/linux tcllibc pairs, G-140) and must not share an identity
#digest. (Seed change 2026-07-30: pre-G-140 emissions seeded on the bare
#name - published r1 records keep their build_ids; revisions are immutable.)
set idseed "punkbin-artifact|lib/$tier/$artifact|zig $opt(-zig)|$opt(-optimize)|tcl$opt(-tclpatch)|$provpairs"
set ihex [sha1::sha1 -hex $idseed]
set build_id "[string range $ihex 0 7]-[string range $ihex 8 11]-[string range $ihex 12 15]-[string range $ihex 16 19]-[string range $ihex 20 31]"

36
src/buildsuites/suite_tcl90/README.md

@ -29,7 +29,8 @@ run from THIS directory with the pinned zig. Sources come from `build.zig.zon` -
content-hashed per-checkin tarball pins ('refresh' = bump a pin; `zig fetch
--save=<name> <url>` edits the manifest). Steps for the nested staged build:
`-Dsteps=...` (repeat the flag), default install install-libraries make-zipfs smoke
tklib tcllib tcllibc kit-family kit-family-artifacts library-artifacts. The test gate:
tklib tcllib tcllibc tcllibc-linux kit-family kit-family-artifacts
library-artifacts. The test gate:
`zig build bootstrap -Dsteps=test-gate` (or
invoke the staged build file directly, as suite.tcl does). zig extracts fetched
packages into `zig-pkg/` beside the manifest and `.zig-cache/` for the outer
@ -176,6 +177,8 @@ package folders -
- `lib/allplatforms/tcllib2.0-tcl9-r1.zip` - platform-neutral (pure-tcl)
- `lib/win32-x86_64/tcllibc-tcl9-r1.zip` - per-platform binary (critcl
accelerators)
- `lib/linux-x86_64/tcllibc-tcl9-r1.zip` - the G-140 CROSS-built accelerators
for the punk9linux kit payload (below)
plus per-artifact `<name>.toml` sidecars and per-tier punkbin-format
`sha1sums.txt`. Names carry the GENERATION tag (`-tcl9-`; suite_tcl86 emits
@ -183,6 +186,37 @@ plus per-artifact `<name>.toml` sidecars and per-tier punkbin-format
tcllibc), so the tag keeps the artifacts distinct server-side. Revision via
`-Dlibrev=N` (suite.tcl `-zigargs {-Dlibrev=N}`; default 1).
### Linux cross lane (G-140)
The `tcllibc-linux` step (default) cross-builds the same critcl accelerators
for linux-x86_64 on the windows build host: critcl runs under the suite-built
windows shell with `-target linux-x86_64-zig` (critcl_zig.config; `zig cc
-target x86_64-linux-gnu.2.17` - dynamic glibc with a conservative
CentOS7-era version floor, rationale in
`goals/G-140-linux-lib-tier-emission.md`). Stubs linkage means no linux build
host and no cross-built Tcl runtime is involved. The install lands at
`out/lib-linux-x86_64/tcllibc` (never on a native package path) with the
shared lib under the `linux-x86_64/` in-package platform folder
(platform::generic vocabulary - what critcl's generated loader resolves on
any linux host).
The build host cannot dlopen a linux `.so`, so the step gates on a structural
check instead of a load smoke: `tools/elf_gate.tcl` (the G-133 classifier's
ELF checks + ET_DYN) requires every member to classify as ELF64 LSB ET_DYN
x86-64. Functional verification (accelerator engaged under a linux Tcl 9
runtime in WSL) is out-of-band evidence recorded in the goal file. The
`library-artifacts` step emits this install as
`lib/linux-x86_64/tcllibc-tcl9-r<N>.zip` in the same run as the native
artifacts - same embedded-record shape with `target = "linux-x86_64"` and
`build_host_platform = "win32-x86_64"`, and NO `[tests]` section (the G-107
suite evidence attaches to the win32 accelerators the tests exercised).
Documented emission invocation:
tclsh suite.tcl build -steps {install install-libraries make-zipfs smoke tcllib tcllibc tcllibc-linux kit-family library-artifacts}
(or any invocation whose steps include the defaults; `tcllibc-linux` alone
builds and gates the cross install without emitting).
Each zip embeds a schema-v2 `punkbin-artifact.toml` at the package root (beside
pkgIndex.tcl - inert to package loading; `[artifact] class = "library"`,
`[provenance] class = "suite-built"` with tcllib/critcl checkout uuids, critcl

80
src/buildsuites/suite_tcl90/build905.zig

@ -2332,6 +2332,65 @@ pub fn build(b: *std.Build) !void {
tcllibc_smoke.step.dependOn(b.getInstallStep());
tcllibc_step.dependOn(&tcllibc_smoke.step);
//-- tcllibc-linux (G-140): the same critcl accelerators CROSS-built for
//linux-x86_64 through the config's linux-x86_64-zig section (zig cc
//-target x86_64-linux-gnu.2.17 - the dynamic-glibc floor decision
//recorded in goals/G-140-linux-lib-tier-emission.md). Stubs linkage:
//critcl bundles its own Tcl headers and links no Tcl runtime, so no
//linux build host or cross-built tclsh is involved - the critcl DRIVER
//runs under the suite-built windows shell exactly as the native step.
//Installs beside the native prefix lib as lib-linux-x86_64/ (never on a
//native package path). The build host cannot dlopen a linux .so, so a
//structural ELF gate (tools/elf_gate.tcl - the G-133 classifier checks
//+ ET_DYN) stands in for the load smoke; functional verification is the
//out-of-band WSL accelerator smoke recorded in the goal file.
const tcllibc_linux_step = b.step("tcllibc-linux", "cross-build+install tcllibc for linux-x86_64 (critcl accelerators, zig cc -target; +structural ELF gate)");
const critcl_linux_run = b.addRunArtifact(tclsh_exe);
common.scrubTclEnv(critcl_linux_run);
critcl_linux_run.setEnvironmentVariable("TCL_LIBRARY", tcl_library_src);
//cached (non-side-effect) Runs spawn with stdout IGNORED - on windows the
//child then has no stdout handle and tcl errors on any puts ('can not find
//channel named "stdout"', critcl's logging). Capturing gives it a real pipe.
_ = critcl_linux_run.captureStdOut(.{});
critcl_linux_run.setCwd(b.path("../tcllib"));
critcl_linux_run.addFileArg(b.path("../critcl/main.tcl"));
critcl_linux_run.addArg("-config");
critcl_linux_run.addFileArg(b.path("critcl_zig.config"));
critcl_linux_run.addArgs(&.{ "-target", "linux-x86_64-zig" });
critcl_linux_run.addArg("-cache");
_ = critcl_linux_run.addOutputDirectoryArg("critcl-cache-linux");
critcl_linux_run.addArg("-force");
critcl_linux_run.addArg("-libdir");
const critcl_linux_libout = critcl_linux_run.addOutputDirectoryArg("critcl-lib-linux");
critcl_linux_run.addArgs(&.{ "-pkg", "tcllibc" });
for (common.tcllibCritclFiles(b, "../tcllib")) |cf| {
//uuid's accelerator is WINDOWS-ONLY C (rpcrt4 UuidCreate behind a
//tcl_platform(platform)=="windows" guard evaluated in the critcl
//DRIVER - which is the windows suite shell here, so it would emit
//windows.h includes into the linux compile). A native linux critcl
//build emits NO uuid C code (the guard is false there), so
//excluding the file reproduces upstream's own linux package shape:
//uuid rides its pure-tcl path, which uses the md5 accelerator this
//package does carry.
if (std.mem.eql(u8, cf, "uuid/uuid.tcl")) continue;
critcl_linux_run.addFileArg(b.path(b.pathJoin(&.{ "../tcllib/modules", cf })));
}
critcl_linux_run.setEnvironmentVariable("PATH", b.fmt("{s}{c}{s}", .{ zigdir, std.fs.path.delimiter, inherited_path }));
const tcllibc_linux_install = b.addInstallDirectory(.{
.source_dir = critcl_linux_libout,
.install_dir = .prefix,
.install_subdir = "lib-linux-x86_64",
});
const tcllibc_linux_gate = b.addRunArtifact(tclsh_exe);
common.scrubTclEnv(tcllibc_linux_gate);
tcllibc_linux_gate.setEnvironmentVariable("TCL_LIBRARY", tcl_library_src);
tcllibc_linux_gate.has_side_effects = true;
tcllibc_linux_gate.addFileArg(b.path("tools/elf_gate.tcl"));
tcllibc_linux_gate.addArgs(&.{ "-expect", "x86_64", "-root" });
tcllibc_linux_gate.addArg(common.replaceAll(b, b.pathJoin(&.{ b.install_path, "lib-linux-x86_64", "tcllibc" }), "\\", "/"));
tcllibc_linux_gate.step.dependOn(&tcllibc_linux_install.step);
tcllibc_linux_step.dependOn(&tcllibc_linux_gate.step);
const testreports_dir = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "testreports" }), "\\", "/");
// ================== G-103 runtime kit family ==================
@ -2609,7 +2668,7 @@ pub fn build(b: *std.Build) !void {
//FAMILY KIT (kit-family-artifacts' proof-doubling rationale: the kit's
//attached tcllib/tcllibc hash the very zips being published).
//Publication to the real punkbin repo stays a deliberate user step.
const library_artifacts_step = b.step("library-artifacts", "emit punkbin lib-tier artifacts (<pkg>-tcl9-r<N>.zip + toml + sha1sums) from the verified tcllib/tcllibc installs -> <prefix>/library/punkbin/lib");
const library_artifacts_step = b.step("library-artifacts", "emit punkbin lib-tier artifacts (<pkg>-tcl9-r<N>.zip + toml + sha1sums) from the verified tcllib/tcllibc installs incl. the linux-x86_64 cross build -> <prefix>/library/punkbin/lib");
const librev = b.option(u32, "librev", "assembly revision N for the -r<N> library artifact names (library-artifacts; default 1 - nothing published yet)") orelse 1;
//punkzip: staged upstream checkout (sources.config 'punkzip' record /
//build.zig.zon pin), compiled for the build host - a build tool, not a
@ -2638,6 +2697,7 @@ pub fn build(b: *std.Build) !void {
const libart_outdir = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "library", "punkbin" }), "\\", "/");
const tcllib_installed = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "lib", b.fmt("tcllib{s}", .{tcllib_ver}) }), "\\", "/");
const tcllibc_installed = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "lib", "tcllibc" }), "\\", "/");
const tcllibc_linux_installed = common.replaceAll(b, b.pathJoin(&.{ b.install_path, "lib-linux-x86_64", "tcllibc" }), "\\", "/");
const lib_emit = b.addSystemCommand(&.{family_installed[0]});
common.scrubTclEnv(lib_emit);
lib_emit.has_side_effects = true;
@ -2652,13 +2712,19 @@ pub fn build(b: *std.Build) !void {
lib_emit.addArgs(&.{ "-testreports", testreports_dir });
//5-tuples: folder tier license testlibs {path} - tcllibc's [tests]
//evidence is the tcllib suite run (it IS tcllib's accelerators; the
//accel smoke at build proved the bundled md5 accelerator loads)
lib_emit.addArgs(&.{ "-packages", b.fmt("tcllib{s} allplatforms BSD tcllib {{{s}}} tcllibc win32-x86_64 BSD tcllib {{{s}}}", .{ tcllib_ver, tcllib_installed, tcllibc_installed }) });
//verified inputs only: the pure-tcl + accelerator smokes, and the
//plain family kit's own self-containment check (the emission runs
//under that kit)
//accel smoke at build proved the bundled md5 accelerator loads).
//The linux-x86_64 tcllibc (G-140) carries NO testlibs: the G-107
//suite evidence attaches to the WIN32 accelerators the tests
//actually exercised - the cross .so's functional evidence is the
//WSL accelerator smoke recorded in the goal file, its build-time
//verification the structural ELF gate below.
lib_emit.addArgs(&.{ "-packages", b.fmt("tcllib{s} allplatforms BSD tcllib {{{s}}} tcllibc win32-x86_64 BSD tcllib {{{s}}} tcllibc linux-x86_64 BSD {{}} {{{s}}}", .{ tcllib_ver, tcllib_installed, tcllibc_installed, tcllibc_linux_installed }) });
//verified inputs only: the pure-tcl + accelerator smokes, the linux
//cross build's structural ELF gate, and the plain family kit's own
//self-containment check (the emission runs under that kit)
lib_emit.step.dependOn(&tcllib_smoke.step);
lib_emit.step.dependOn(&tcllibc_smoke.step);
lib_emit.step.dependOn(&tcllibc_linux_gate.step);
lib_emit.step.dependOn(family_checks[0]);
library_artifacts_step.dependOn(&lib_emit.step);
}
@ -2884,7 +2950,7 @@ fn bootstrapMode(b: *std.Build) !void {
//suite.tcl performs after its fossil staging. Per-zig-version cache dir (object
//caches must never be shared across zig versions - user-confirmed hazard), same
//name suite.tcl derives so both flows share the staged cache.
const steps_opt = b.option([]const []const u8, "steps", "steps for the staged build (repeat the flag; default: install install-libraries make-zipfs smoke tklib tcllib tcllibc kit-family kit-family-artifacts library-artifacts - the full pipeline short of test-gate)") orelse @as([]const []const u8, &.{ "install", "install-libraries", "make-zipfs", "smoke", "tklib", "tcllib", "tcllibc", "kit-family", "kit-family-artifacts", "library-artifacts" });
const steps_opt = b.option([]const []const u8, "steps", "steps for the staged build (repeat the flag; default: install install-libraries make-zipfs smoke tklib tcllib tcllibc tcllibc-linux kit-family kit-family-artifacts library-artifacts - the full pipeline short of test-gate)") orelse @as([]const []const u8, &.{ "install", "install-libraries", "make-zipfs", "smoke", "tklib", "tcllib", "tcllibc", "tcllibc-linux", "kit-family", "kit-family-artifacts", "library-artifacts" });
var cachever: []const u8 = builtin.zig_version_string;
cachever = common.replaceAll(b, cachever, "+", "_");
cachever = common.replaceAll(b, cachever, "/", "_");

53
src/buildsuites/suite_tcl90/critcl_zig.config

@ -1,14 +1,30 @@
# suite_tcl90 critcl configuration: zig cc as the C toolchain (G-098, G-102).
# 'zig' is resolved from PATH - the suite recipe prepends the pinned bin/tools zig
# dir for the critcl invocation. Target is the native windows-gnu triple (matches
# the suite's tcl runtime ABI).
# dir for the critcl invocation.
#
# The settings live under an EXPLICIT target, win32-x86_64-zig, and the recipe
# invokes critcl with '-target win32-x86_64-zig': critcl otherwise chooses its
# build target by PROBING the environment for compilers, which made the selection
# depend on what happened to be on PATH (a visible gcc landed on the config
# defaults; a scrubbed environment fell back to critcl's builtin msvc 'cl'
# target and never used these settings - G-102 finding).
# Settings live under EXPLICIT targets and the recipe invokes critcl with
# '-target <section>': critcl otherwise chooses its build target by PROBING the
# environment for compilers, which made the selection depend on what happened to
# be on PATH (a visible gcc landed on the config defaults; a scrubbed
# environment fell back to critcl's builtin msvc 'cl' target and never used
# these settings - G-102 finding).
#
# win32-x86_64-zig: the native windows-gnu triple (matches the suite's tcl
# runtime ABI).
#
# linux-x86_64-zig (G-140): CROSS target for the punk9linux kit payload -
# stubs-linked extensions only (critcl bundles its own Tcl headers and links no
# Tcl runtime, so no linux build host or cross-built tclsh is involved). The
# triple pins a dynamic-glibc floor, x86_64-linux-gnu.2.17: the consuming linux
# runtimes (punkbin tclkit-902 family) are glibc-dynamic, so a musl .so would
# mix libcs inside one process; 2.17 is the conservative CentOS7-era floor,
# supported by the pinned zig's bundled glibc stubs and far below any current
# consumer distro. The section's 'platform' identifier is linux-x86_64
# (platform::generic vocabulary): critcl places the shared lib under
# <pkg>/<identifier>/ and its generated loader resolves that folder via
# ::critcl::runtime::MapPlatform (= platform::generic) on the target host -
# glibc detail stays out of the folder name, recorded instead in the punkbin
# artifact record and goals/G-140-linux-lib-tier-emission.md.
platform win32-x86_64
@ -32,3 +48,24 @@ win32-x86_64-zig embed_manifest
win32-x86_64-zig ldoutput
win32-x86_64-zig link_preload
win32-x86_64-zig sharedlibext .dll
linux-x86_64-zig platform linux-x86_64
linux-x86_64-zig compile zig cc -target x86_64-linux-gnu.2.17 -c -fPIC
linux-x86_64-zig version zig version
linux-x86_64-zig link zig cc -target x86_64-linux-gnu.2.17 -shared
linux-x86_64-zig include -I
linux-x86_64-zig libinclude -L
linux-x86_64-zig object .o
linux-x86_64-zig output -o [list $outfile]
linux-x86_64-zig optimize -O2
linux-x86_64-zig noassert -DNDEBUG
linux-x86_64-zig tclstubs -DUSE_TCL_STUBS
linux-x86_64-zig tkstubs -DUSE_TK_STUBS
linux-x86_64-zig debug_symbols -g
linux-x86_64-zig strip -Wl,-s
linux-x86_64-zig link_debug
linux-x86_64-zig link_release
linux-x86_64-zig embed_manifest
linux-x86_64-zig ldoutput
linux-x86_64-zig link_preload
linux-x86_64-zig sharedlibext .so

22
src/buildsuites/suite_tcl90/suite.tcl

@ -22,15 +22,17 @@
# -seedfossils <dir> read-only seed collection for missing clones (default ~/.fossils; "" disables)
# -all <0|1> with 'clean': reserved (the clone store lives outside the stage)
# -steps <list> zig build steps. 'build' default: {install install-libraries
# make-zipfs smoke tklib tcllib tcllibc kit-family
# kit-family-artifacts library-artifacts} - the full pipeline
# short of the test steps: the G-103 runtime kit family
# (verified self-contained plain/punk/punk-bi shells ->
# out/family plus punkbin-layout -r<N> artifacts + toml
# metadata; artifact revision via -zigargs {-Dfamilyrev=N})
# then the G-138 punkbin lib-tier library artifacts
# (tcllib/tcllibc zips -> out/library/punkbin/lib; revision
# via -zigargs {-Dlibrev=N}).
# make-zipfs smoke tklib tcllib tcllibc tcllibc-linux
# kit-family kit-family-artifacts library-artifacts} - the
# full pipeline short of the test steps: the G-103 runtime
# kit family (verified self-contained plain/punk/punk-bi
# shells -> out/family plus punkbin-layout -r<N> artifacts
# + toml metadata; artifact revision via -zigargs
# {-Dfamilyrev=N}) then the G-138 punkbin lib-tier library
# artifacts (tcllib/tcllibc zips incl. the G-140
# linux-x86_64 cross-built tcllibc ->
# out/library/punkbin/lib; revision via -zigargs
# {-Dlibrev=N}).
# 'test' default: {test-gate} (the
# core suite gate); other test steps (G-107 library runs):
# test-libraries (thread+tclvfs gated, tcllib+tklib recorded),
@ -140,7 +142,7 @@ array set opt {
-optimize ReleaseFast
-tclbranch {}
-refresh 0
-steps {install install-libraries make-zipfs smoke tklib tcllib tcllibc kit-family kit-family-artifacts library-artifacts}
-steps {install install-libraries make-zipfs smoke tklib tcllib tcllibc tcllibc-linux kit-family kit-family-artifacts library-artifacts}
-testargs {}
-zigargs {}
-repofolder {}

93
src/buildsuites/suite_tcl90/tools/elf_gate.tcl

@ -0,0 +1,93 @@
#elf_gate.tcl (G-140): structural gate for cross-built ELF shared libraries on a
#build host that cannot dlopen them (a linux .so on windows) - the load-smoke
#stand-in for cross lanes; functional verification happens out-of-band on a
#matching host (WSL/native-linux accelerator smokes, recorded in the goal file).
#
#The checks mirror the G-133 classifier's ELF branch (punkboot::utils
#binary_arch_classify: ELF magic, EI_CLASS, EI_DATA, e_machine honouring
#endianness) plus e_type == ET_DYN - a dlopen'd extension must be a shared
#object. Self-contained plain Tcl (suite tools run under the suite-built shell,
#no punkshell modules).
#
#args: -root <dir> scanned recursively for *.so / *.so.N members; at least
# one member is required (an empty tree means the cross
# build produced nothing - a failure, not a pass)
# -expect <arch> required architecture: x86_64 | arm64 | i386
#exit 0: every member classifies as ELF64 LSB ET_DYN <arch>; exit 1 otherwise
proc fail {msg} {puts stderr "elf_gate FAIL: $msg"; flush stderr; exit 1}
proc note {msg} {puts stdout "elf_gate: $msg"; flush stdout}
array set opt {-root {} -expect x86_64}
foreach {k v} $argv {
if {![info exists opt($k)]} {fail "unknown option '$k'"}
set opt($k) $v
}
if {$opt(-root) eq ""} {fail "missing required option -root"}
set root [file normalize $opt(-root)]
if {![file isdirectory $root]} {fail "-root directory not found: $root"}
#e_machine values per the G-133 classifier map (subset; extend as cross lanes appear)
array set machine_of {x86_64 62 arm64 183 i386 3}
if {![info exists machine_of($opt(-expect))]} {
fail "-expect '$opt(-expect)' not one of: [lsort [array names machine_of]]"
}
set want $machine_of($opt(-expect))
proc so_files {dir} {
set res {}
foreach f [lsort [glob -nocomplain -directory $dir -types f *]] {
set tail [file tail $f]
if {[string match *.so $tail] || [regexp {\.so\.[0-9]} $tail]} {
lappend res $f
}
}
foreach d [lsort [glob -nocomplain -directory $dir -types d *]] {
lappend res {*}[so_files $d]
}
return $res
}
set sofiles [so_files $root]
if {![llength $sofiles]} {fail "no .so members found under $root"}
set failures {}
foreach so $sofiles {
set rel [string range $so [string length $root]+1 end]
set fd [open $so r]
chan configure $fd -translation binary
set head [read $fd 20]
close $fd
if {[string length $head] < 20} {
lappend failures "$rel: too short for an ELF header ([string length $head] bytes)"
continue
}
binary scan $head a4cucu magic eclass edata
if {$magic ne "\x7fELF"} {
lappend failures "$rel: not ELF (magic [binary encode hex [string range $head 0 3]])"
continue
}
if {$eclass != 2} {
lappend failures "$rel: EI_CLASS $eclass (want 2 = ELF64)"
continue
}
if {$edata != 1} {
lappend failures "$rel: EI_DATA $edata (want 1 = little-endian)"
continue
}
binary scan $head @16susu etype emachine
if {$etype != 3} {
lappend failures "$rel: e_type $etype (want 3 = ET_DYN shared object)"
continue
}
if {$emachine != $want} {
lappend failures "$rel: e_machine $emachine (want $want = $opt(-expect))"
continue
}
note "OK $rel (ELF64 LSB ET_DYN $opt(-expect), [file size $so] bytes)"
}
if {[llength $failures]} {
fail "[llength $failures] of [llength $sofiles] members failed:\n [join $failures "\n "]"
}
puts "elf_gate OK: [llength $sofiles] ELF64 $opt(-expect) shared object(s) under $root"
exit 0

8
src/buildsuites/suite_tcl90/tools/library_artifacts.tcl

@ -314,8 +314,12 @@ foreach {folder tier license testlibs pkgpath} $opt(-packages) {
#deterministic build_id (uuid-shaped sha1 digest of stable identity inputs -
#same input family as the runtime records: name, toolchain/optimize, driving
#patchlevel, per-member source checkout uuids)
set idseed "punkbin-artifact|$artifact|zig $opt(-zig)|$opt(-optimize)|tcl$opt(-tclpatch)|$provpairs"
#patchlevel, per-member source checkout uuids). The tier rides the seed as
#the artifact's repo path: same-NAMED artifacts exist in different target
#tiers (win32/linux tcllibc pairs, G-140) and must not share an identity
#digest. (Seed change 2026-07-30: pre-G-140 emissions seeded on the bare
#name - published r1 records keep their build_ids; revisions are immutable.)
set idseed "punkbin-artifact|lib/$tier/$artifact|zig $opt(-zig)|$opt(-optimize)|tcl$opt(-tclpatch)|$provpairs"
set ihex [sha1::sha1 -hex $idseed]
set build_id "[string range $ihex 0 7]-[string range $ihex 8 11]-[string range $ihex 12 15]-[string range $ihex 16 19]-[string range $ihex 20 31]"

7
src/runtime/libpackages.toml

@ -45,6 +45,13 @@ target = "allplatforms"
name = "tcllibc-tcl9-r1.zip"
target = "win32-x86_64"
# G-140: the linux-x86_64 cross-built accelerators (suite_tcl90 tcllibc-linux
# lane) consumed by punk9linux.vfs. Same immutable name in its own target
# folder; the generation+revision grammar keys the entry name instead.
[artifact.tcllibc-tcl9-linux]
name = "tcllibc-tcl9-r1.zip"
target = "linux-x86_64"
[artifact.tcllib-tcl8]
name = "tcllib2.0-tcl8-r1.zip"
target = "allplatforms"

20
src/runtime/vendorlib_vfs.toml

@ -51,11 +51,12 @@ supersedes = ["udp1.0.12", "tcludp1.0.12"]
# blanket. replace=true because the old tcl9 hand-drops nested md5c + tcllibc
# INSIDE tcllib2.0 (same folder name as the new install - supersedes cannot
# touch it). The tcl8 kits upgrade tcllib1.21 (+nested tcllibc 0.4 + md5c) ->
# tcllib 2.0 via supersedes. tcllibc is the win32-x86_64 build: punk9linux
# (linux target) deliberately gets only the platform-neutral tcllib2.0 - its
# linux-built tcllibc/tcllibc2.0 sibling folders are left as-is (a linux
# lib-tier emission is future work). punk86bawt carried a bare tcllibc only -
# it gets the tcllibc refresh and no tcllib entry.
# tcllib 2.0 via supersedes. tcllibc_tcl9 is the win32-x86_64 build for the
# windows kits; punk9linux (linux target) gets the platform-neutral tcllib2.0
# plus its OWN tcllibc from the linux-x86_64 tier (G-140: the suite_tcl90
# tcllibc-linux cross build - replace retires the provenance-less hand-dropped
# tcllibc, supersedes the stray-named tcllibc2.0). punk86bawt carried a bare
# tcllibc only - it gets the tcllibc refresh and no tcllib entry.
[install.tcllib_tcl9]
source_root = "packages"
@ -89,6 +90,15 @@ targets = [
]
supersedes = ["tcllibc2.0"]
[install.tcllibc_tcl9_linux]
source_root = "packages"
source = "linux-x86_64/tcl9/tcllibc"
replace = true
targets = [
"punk9linux.vfs/lib_tcl9",
]
supersedes = ["tcllibc2.0"]
[install.tcllib_tcl8]
source_root = "packages"
source = "allplatforms/tcl8/tcllib2.0"

767
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/critcl-rt.tcl

@ -1,381 +1,386 @@
#
# Critcl - build C extensions on-the-fly
#
# Copyright (c) 2001-2007 Jean-Claude Wippler
# Copyright (c) 2002-2007 Steve Landers
#
# See http://wiki.tcl.tk/critcl
#
# This is the Critcl runtime that loads the appropriate
# shared library when a package is requested
#
namespace eval ::critcl::runtime {}
proc ::critcl::runtime::loadlib {dir package version libname initfun tsrc mapping args} {
# XXX At least parts of this can be done by the package generator,
# XXX like listing the Tcl files to source. The glob here allows
# XXX code-injection after-the-fact, by simply adding a .tcl in
# XXX the proper place.
set path [file join $dir [MapPlatform $mapping]]
set ext [info sharedlibextension]
set lib [file join $path $libname$ext]
set provide [list]
# Now the runtime equivalent of a series of 'preFetch' commands.
if {[llength $args]} {
set preload [file join $path preload$ext]
foreach p $args {
set prelib [file join $path $p$ext]
if {[file readable $preload] && [file readable $prelib]} {
lappend provide [list load $preload];# XXX Move this out of the loop, do only once.
lappend provide [list ::critcl::runtime::preload $prelib]
}
}
}
lappend provide [list load $lib $initfun]
foreach t $tsrc {
lappend loadcmd "::critcl::runtime::Fetch \$dir [list $t]"
}
lappend provide "package provide $package $version"
package ifneeded $package $version [join $provide "\n"]
return
}
proc ::critcl::runtime::preFetch {path ext dll} {
set preload [file join $path preload$ext]
if {![file readable $preload]} return
set prelib [file join $path $dll$ext]
if {![file readable $prelib]} return
load $preload ; # Defines next command.
::critcl::runtime::preload $prelib
return
}
proc ::critcl::runtime::Fetch {dir t} {
# The 'Ignore' disables compile & run functionality.
# Background: If the regular critcl package is already loaded, and
# this prebuilt package uses its defining .tcl file also as a
# 'tsources' then critcl might try to collect data and build it
# because of the calls to its API, despite the necessary binaries
# already being present, just not in the critcl cache. That is
# redundant in the best case, and fails in the worst case (no
# compiler), preventing the use o a perfectly fine package. The
# 'ignore' call now tells critcl that it should ignore any calls
# made to it by the sourced files, and thus avoids that trouble.
# The other case, the regular critcl package getting loaded after
# this prebuilt package is irrelevant. At that point the tsources
# were already run, and used the dummy procedures defined in the
# critcl-rt.tcl, which ignore the calls by definition.
set t [file join $dir tcl $t]
::critcl::Ignore $t
uplevel #0 [list source $t]
return
}
proc ::critcl::runtime::precopy {dll} {
# This command is only used on Windows when preloading out of a
# VFS that doesn't support direct loading (usually, a Starkit)
# - we preserve the dll name so that dependencies are satisfied
# - The critcl::runtime::preload command is defined in the supporting
# "preload" package, implemented in "critcl/lib/critcl/critcl_c/preload.c"
global env
if {[info exists env(TEMP)]} {
set dir $env(TEMP)
} elseif {[info exists env(TMP)]} {
set dir $env(TMP)
} elseif {[file exists $env(HOME)]} {
set dir $env(HOME)
} else {
set dir .
}
set dir [file join $dir TCL[pid]]
set i 0
while {[file exists $dir]} {
append dir [incr i]
}
set new [file join $dir [file tail $dll]]
file mkdir $dir
file copy $dll $new
return $new
}
proc ::critcl::runtime::MapPlatform {{mapping {}}} {
# A sibling of critcl::platform that applies the platform mapping
set platform [::platform::generic]
set version $::tcl_platform(osVersion)
if {[string match "macosx-*" $platform]} {
# "normalize" the osVersion to match OSX release numbers
set v [split $version .]
set v1 [lindex $v 0]
set v2 [lindex $v 1]
incr v1 -4
set version 10.$v1.$v2
} else {
# Strip trailing non-version info
regsub -- {-.*$} $version {} version
}
foreach {config map} $mapping {
if {![string match $config $platform]} continue
set minver [lindex $map 1]
if {[package vcompare $version $minver] < 0} continue
set platform [lindex $map 0]
break
}
return $platform
}
# Dummy implementation of the critcl package, if not present
if {![llength [info commands ::critcl::Ignore]]} {
namespace eval ::critcl {}
proc ::critcl::Ignore {args} {
namespace eval ::critcl::v {}
set ::critcl::v::ignore([file normalize [lindex $args 0]]) .
}
}
if {![llength [info commands ::critcl::api]]} {
namespace eval ::critcl {}
proc ::critcl::api {args} {}
}
if {![llength [info commands ::critcl::at]]} {
namespace eval ::critcl {}
proc ::critcl::at {args} {}
}
if {![llength [info commands ::critcl::cache]]} {
namespace eval ::critcl {}
proc ::critcl::cache {args} {}
}
if {![llength [info commands ::critcl::ccode]]} {
namespace eval ::critcl {}
proc ::critcl::ccode {args} {}
}
if {![llength [info commands ::critcl::ccommand]]} {
namespace eval ::critcl {}
proc ::critcl::ccommand {args} {}
}
if {![llength [info commands ::critcl::cdata]]} {
namespace eval ::critcl {}
proc ::critcl::cdata {args} {}
}
if {![llength [info commands ::critcl::cdefines]]} {
namespace eval ::critcl {}
proc ::critcl::cdefines {args} {}
}
if {![llength [info commands ::critcl::cflags]]} {
namespace eval ::critcl {}
proc ::critcl::cflags {args} {}
}
if {![llength [info commands ::critcl::cheaders]]} {
namespace eval ::critcl {}
proc ::critcl::cheaders {args} {}
}
if {![llength [info commands ::critcl::check]]} {
namespace eval ::critcl {}
proc ::critcl::check {args} {return 0}
}
if {![llength [info commands ::critcl::cinit]]} {
namespace eval ::critcl {}
proc ::critcl::cinit {args} {}
}
if {![llength [info commands ::critcl::clibraries]]} {
namespace eval ::critcl {}
proc ::critcl::clibraries {args} {}
}
if {![llength [info commands ::critcl::compiled]]} {
namespace eval ::critcl {}
proc ::critcl::compiled {args} {return 1}
}
if {![llength [info commands ::critcl::compiling]]} {
namespace eval ::critcl {}
proc ::critcl::compiling {args} {return 0}
}
if {![llength [info commands ::critcl::config]]} {
namespace eval ::critcl {}
proc ::critcl::config {args} {}
}
if {![llength [info commands ::critcl::cproc]]} {
namespace eval ::critcl {}
proc ::critcl::cproc {args} {}
}
if {![llength [info commands ::critcl::csources]]} {
namespace eval ::critcl {}
proc ::critcl::csources {args} {}
}
if {![llength [info commands ::critcl::debug]]} {
namespace eval ::critcl {}
proc ::critcl::debug {args} {}
}
if {![llength [info commands ::critcl::done]]} {
namespace eval ::critcl {}
proc ::critcl::done {args} {return 1}
}
if {![llength [info commands ::critcl::failed]]} {
namespace eval ::critcl {}
proc ::critcl::failed {args} {return 0}
}
if {![llength [info commands ::critcl::framework]]} {
namespace eval ::critcl {}
proc ::critcl::framework {args} {}
}
if {![llength [info commands ::critcl::include]]} {
namespace eval ::critcl {}
proc ::critcl::include {args} {}
}
if {![llength [info commands ::critcl::ldflags]]} {
namespace eval ::critcl {}
proc ::critcl::ldflags {args} {}
}
if {![llength [info commands ::critcl::license]]} {
namespace eval ::critcl {}
proc ::critcl::license {args} {}
}
if {![llength [info commands ::critcl::load]]} {
namespace eval ::critcl {}
proc ::critcl::load {args} {return 1}
}
if {![llength [info commands ::critcl::make]]} {
namespace eval ::critcl {}
proc ::critcl::make {args} {}
}
if {![llength [info commands ::critcl::meta]]} {
namespace eval ::critcl {}
proc ::critcl::meta {args} {}
}
if {![llength [info commands ::critcl::platform]]} {
namespace eval ::critcl {}
proc ::critcl::platform {args} {}
}
if {![llength [info commands ::critcl::preload]]} {
namespace eval ::critcl {}
proc ::critcl::preload {args} {}
}
if {![llength [info commands ::critcl::source]]} {
namespace eval ::critcl {}
proc ::critcl::source {args} {}
}
if {![llength [info commands ::critcl::tcl]]} {
namespace eval ::critcl {}
proc ::critcl::tcl {args} {}
}
if {![llength [info commands ::critcl::tk]]} {
namespace eval ::critcl {}
proc ::critcl::tk {args} {}
}
if {![llength [info commands ::critcl::tsources]]} {
namespace eval ::critcl {}
proc ::critcl::tsources {args} {}
}
if {![llength [info commands ::critcl::userconfig]]} {
namespace eval ::critcl {}
proc ::critcl::userconfig {args} {}
}
# Define a clone of platform::generic, if needed
if {![llength [info commands ::platform::generic]]} {
namespace eval ::platform {}
proc ::platform::generic {} {
global tcl_platform
set plat [string tolower [lindex $tcl_platform(os) 0]]
set cpu $tcl_platform(machine)
switch -glob -- $cpu {
sun4* {
set cpu sparc
}
intel -
ia32* -
i*86* {
set cpu ix86
}
x86_64 {
if {$tcl_platform(wordSize) == 4} {
# See Example <1> at the top of this file.
set cpu ix86
}
}
ppc -
"Power*" {
set cpu powerpc
}
"arm*" {
set cpu arm
}
ia64 {
if {$tcl_platform(wordSize) == 4} {
append cpu _32
}
}
}
switch -glob -- $plat {
windows {
if {$tcl_platform(platform) == "unix"} {
set plat cygwin
} else {
set plat win32
}
if {$cpu eq "amd64"} {
# Do not check wordSize, win32-x64 is an IL32P64 platform.
set cpu x86_64
}
}
sunos {
set plat solaris
if {[string match "ix86" $cpu]} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
} elseif {![string match "ia64*" $cpu]} {
# sparc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
darwin {
set plat macosx
# Correctly identify the cpu when running as a 64bit
# process on a machine with a 32bit kernel
if {$cpu eq "ix86"} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
}
}
aix {
set cpu powerpc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
hp-ux {
set plat hpux
if {![string match "ia64*" $cpu]} {
set cpu parisc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
osf1 {
set plat tru64
}
default {
set plat [lindex [split $plat _-] 0]
}
}
return "${plat}-${cpu}"
}
}
#
# Critcl - build C extensions on-the-fly
#
# Copyright (c) 2001-2007 Jean-Claude Wippler
# Copyright (c) 2002-2007 Steve Landers
#
# See http://wiki.tcl.tk/critcl
#
# This is the Critcl runtime that loads the appropriate
# shared library when a package is requested
#
namespace eval ::critcl::runtime {}
proc ::critcl::runtime::loadlib {dir package version libname initfun tsrc mapping args} {
# XXX At least parts of this can be done by the package generator,
# XXX like listing the Tcl files to source. The glob here allows
# XXX code-injection after-the-fact, by simply adding a .tcl in
# XXX the proper place.
set path [file join $dir [MapPlatform $mapping]]
set ext [info sharedlibextension]
set lib [file join $path $libname$ext]
set provide [list]
# Now the runtime equivalent of a series of 'preFetch' commands.
if {[llength $args]} {
set preload [file join $path preload$ext]
foreach p $args {
set prelib [file join $path $p$ext]
if {[file readable $preload] && [file readable $prelib]} {
lappend provide [list load $preload];# XXX Move this out of the loop, do only once.
lappend provide [list ::critcl::runtime::preload $prelib]
}
}
}
lappend provide [list load $lib $initfun]
foreach t $tsrc {
lappend loadcmd "::critcl::runtime::Fetch \$dir [list $t]"
}
lappend provide "package provide $package $version"
package ifneeded $package $version [join $provide "\n"]
return
}
proc ::critcl::runtime::preFetch {path ext dll} {
set preload [file join $path preload$ext]
if {![file readable $preload]} return
set prelib [file join $path $dll$ext]
if {![file readable $prelib]} return
load $preload ; # Defines next command.
::critcl::runtime::preload $prelib
return
}
proc ::critcl::runtime::Fetch {dir t} {
# The 'Ignore' disables compile & run functionality.
# Background: If the regular critcl package is already loaded, and
# this prebuilt package uses its defining .tcl file also as a
# 'tsources' then critcl might try to collect data and build it
# because of the calls to its API, despite the necessary binaries
# already being present, just not in the critcl cache. That is
# redundant in the best case, and fails in the worst case (no
# compiler), preventing the use o a perfectly fine package. The
# 'ignore' call now tells critcl that it should ignore any calls
# made to it by the sourced files, and thus avoids that trouble.
# The other case, the regular critcl package getting loaded after
# this prebuilt package is irrelevant. At that point the tsources
# were already run, and used the dummy procedures defined in the
# critcl-rt.tcl, which ignore the calls by definition.
set t [file join $dir tcl $t]
::critcl::Ignore $t
uplevel #0 [list source $t]
return
}
proc ::critcl::runtime::precopy {dll} {
# This command is only used on Windows when preloading out of a
# VFS that doesn't support direct loading (usually, a Starkit)
# - we preserve the dll name so that dependencies are satisfied
# - The critcl::runtime::preload command is defined in the supporting
# "preload" package, implemented in "critcl/lib/critcl/critcl_c/preload.c"
global env
if {[info exists env(TEMP)]} {
set dir $env(TEMP)
} elseif {[info exists env(TMP)]} {
set dir $env(TMP)
} elseif {[file exists $env(HOME)]} {
set dir $env(HOME)
} else {
set dir .
}
set dir [file join $dir TCL[pid]]
set i 0
while {[file exists $dir]} {
append dir [incr i]
}
set new [file join $dir [file tail $dll]]
file mkdir $dir
file copy $dll $new
return $new
}
proc ::critcl::runtime::MapPlatform {{mapping {}}} {
# A sibling of critcl::platform that applies the platform mapping
set platform [::platform::generic]
set version $::tcl_platform(osVersion)
if {[string match "macosx-*" $platform]} {
# "normalize" the osVersion to match OSX release numbers
set v [split $version .]
set v1 [lindex $v 0]
set v2 [lindex $v 1]
incr v1 -4
set version 10.$v1.$v2
} else {
# Strip trailing non-version info
regsub -- {-.*$} $version {} version
}
foreach {config map} $mapping {
if {![string match $config $platform]} continue
set minver [lindex $map 1]
if {[package vcompare $version $minver] < 0} continue
set platform [lindex $map 0]
break
}
return $platform
}
# Dummy implementation of the critcl package, if not present
if {![llength [info commands ::critcl::Ignore]]} {
namespace eval ::critcl {}
proc ::critcl::Ignore {args} {
namespace eval ::critcl::v {}
set ::critcl::v::ignore([file normalize [lindex $args 0]]) .
}
}
if {![llength [info commands ::critcl::api]]} {
namespace eval ::critcl {}
proc ::critcl::api {args} {}
}
if {![llength [info commands ::critcl::at]]} {
namespace eval ::critcl {}
proc ::critcl::at {args} {}
}
if {![llength [info commands ::critcl::cache]]} {
namespace eval ::critcl {}
proc ::critcl::cache {args} {}
}
if {![llength [info commands ::critcl::ccode]]} {
namespace eval ::critcl {}
proc ::critcl::ccode {args} {}
}
if {![llength [info commands ::critcl::ccommand]]} {
namespace eval ::critcl {}
proc ::critcl::ccommand {args} {}
}
if {![llength [info commands ::critcl::cdata]]} {
namespace eval ::critcl {}
proc ::critcl::cdata {args} {}
}
if {![llength [info commands ::critcl::cdefines]]} {
namespace eval ::critcl {}
proc ::critcl::cdefines {args} {}
}
if {![llength [info commands ::critcl::cflags]]} {
namespace eval ::critcl {}
proc ::critcl::cflags {args} {}
}
if {![llength [info commands ::critcl::cheaders]]} {
namespace eval ::critcl {}
proc ::critcl::cheaders {args} {}
}
if {![llength [info commands ::critcl::check]]} {
namespace eval ::critcl {}
proc ::critcl::check {args} {return 0}
}
if {![llength [info commands ::critcl::cinit]]} {
namespace eval ::critcl {}
proc ::critcl::cinit {args} {}
}
if {![llength [info commands ::critcl::clibraries]]} {
namespace eval ::critcl {}
proc ::critcl::clibraries {args} {}
}
if {![llength [info commands ::critcl::compiled]]} {
namespace eval ::critcl {}
proc ::critcl::compiled {args} {return 1}
}
if {![llength [info commands ::critcl::compiling]]} {
namespace eval ::critcl {}
proc ::critcl::compiling {args} {return 0}
}
if {![llength [info commands ::critcl::config]]} {
namespace eval ::critcl {}
proc ::critcl::config {args} {}
}
if {![llength [info commands ::critcl::cproc]]} {
namespace eval ::critcl {}
proc ::critcl::cproc {args} {}
}
if {![llength [info commands ::critcl::csources]]} {
namespace eval ::critcl {}
proc ::critcl::csources {args} {}
}
if {![llength [info commands ::critcl::debug]]} {
namespace eval ::critcl {}
proc ::critcl::debug {args} {}
}
if {![llength [info commands ::critcl::done]]} {
namespace eval ::critcl {}
proc ::critcl::done {args} {return 1}
}
if {![llength [info commands ::critcl::failed]]} {
namespace eval ::critcl {}
proc ::critcl::failed {args} {return 0}
}
if {![llength [info commands ::critcl::framework]]} {
namespace eval ::critcl {}
proc ::critcl::framework {args} {}
}
if {![llength [info commands ::critcl::include]]} {
namespace eval ::critcl {}
proc ::critcl::include {args} {}
}
if {![llength [info commands ::critcl::ldflags]]} {
namespace eval ::critcl {}
proc ::critcl::ldflags {args} {}
}
if {![llength [info commands ::critcl::license]]} {
namespace eval ::critcl {}
proc ::critcl::license {args} {}
}
if {![llength [info commands ::critcl::load]]} {
namespace eval ::critcl {}
proc ::critcl::load {args} {return 1}
}
if {![llength [info commands ::critcl::make]]} {
namespace eval ::critcl {}
proc ::critcl::make {args} {}
}
if {![llength [info commands ::critcl::meta]]} {
namespace eval ::critcl {}
proc ::critcl::meta {args} {}
}
if {![llength [info commands ::critcl::platform]]} {
namespace eval ::critcl {}
proc ::critcl::platform {args} {}
}
if {![llength [info commands ::critcl::preload]]} {
namespace eval ::critcl {}
proc ::critcl::preload {args} {}
}
if {![llength [info commands ::critcl::source]]} {
namespace eval ::critcl {}
proc ::critcl::source {args} {}
}
if {![llength [info commands ::critcl::tcl]]} {
namespace eval ::critcl {}
proc ::critcl::tcl {args} {}
}
if {![llength [info commands ::critcl::tk]]} {
namespace eval ::critcl {}
proc ::critcl::tk {args} {}
}
if {![llength [info commands ::critcl::tsources]]} {
namespace eval ::critcl {}
proc ::critcl::tsources {args} {}
}
if {![llength [info commands ::critcl::userconfig]]} {
namespace eval ::critcl {}
proc ::critcl::userconfig {args} {}
}
# Define a clone of platform::generic, if needed
if {![llength [info commands ::platform::generic]]} {
namespace eval ::platform {}
proc ::platform::generic {} {
global tcl_platform
set plat [string tolower [lindex $tcl_platform(os) 0]]
set cpu $tcl_platform(machine)
switch -glob -- $cpu {
sun4* {
set cpu sparc
}
intel -
ia32* -
i*86* {
set cpu ix86
}
x86_64 {
if {$tcl_platform(wordSize) == 4} {
# See Example <1> at the top of this file.
set cpu ix86
}
}
ppc -
"Power*" {
set cpu powerpc
}
"arm*" {
set cpu arm
}
ia64 {
if {$tcl_platform(wordSize) == 4} {
append cpu _32
}
}
}
switch -glob -- $plat {
windows {
if {$tcl_platform(platform) eq "unix"} {
set plat cygwin
} else {
set plat win32
}
if {$cpu eq "amd64"} {
# Do not check wordSize, win32-x64 is an IL32P64 platform.
set cpu x86_64
}
}
sunos {
set plat solaris
if {[string match "ix86" $cpu]} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
} elseif {![string match "ia64*" $cpu]} {
# sparc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
darwin {
set major [lindex [split $tcl_platform(osVersion) .] 0]
if {$major > 19} {
set plat macos
} else {
set plat macosx
}
# Correctly identify the cpu when running as a 64bit
# process on a machine with a 32bit kernel
if {$cpu eq "ix86"} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
}
}
aix {
set cpu powerpc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
hp-ux {
set plat hpux
if {![string match "ia64*" $cpu]} {
set cpu parisc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
osf1 {
set plat tru64
}
default {
set plat [lindex [split $plat _-] 0]
}
}
return "${plat}-${cpu}"
}
}

2
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms

@ -1 +1 @@
<<Undefined>>
<<Undefined>>

BIN
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so

Binary file not shown.

4
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/pkgIndex.tcl

@ -1,2 +1,2 @@
if {![package vsatisfies [package provide Tcl] 9.0]} {return}
package ifneeded tcllibc 2.0 "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"
if {![package vsatisfies [package provide Tcl] 9.0]} {return}
package ifneeded tcllibc 2.0 "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"

53
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/punkbin-artifact.toml

@ -0,0 +1,53 @@
#punkshell library artifact metadata - EMBEDDED copy (schema v2, class "library"),
#written at library-artifacts emission into the staged package copy BEFORE the
#zip is assembled and hashed (embed-then-hash). Finished-zip facts (sha1, size,
#built) live only in the sidecar toml + sha1sums.txt, which remain the
#integrity authority; this copy makes a materialized package tree self-describing.
schema = 2
[artifact]
name = "tcllibc-tcl9-r1.zip"
class = "library"
package = "tcllibc"
package_version = "2.0"
#folder: the installed-shape package folder the zip carries at its root
folder = "tcllibc"
revision = 1
target = "linux-x86_64"
#tcl_generation: the Tcl major-generation the package was built/installed under
#(and, for binary packages, compiled against) - part of the artifact name.
tcl_generation = "tcl9"
#build_id: offline correlation key re-joining a renamed copy to its record;
#identical in the embedded and sidecar copies (a deterministic identity digest,
#not an integrity key - the sidecar sha1 is the integrity fact).
build_id = "e7030a7a-0486-9c94-00cb-7536716ea5d9"
#origin: canonical artifact repo this artifact was BUILT FOR - not necessarily
#where it is hosted; mirrors preserve it.
origin = "https://www.gitea1.intx.com.au/jn/punkbin"
#packager: declared identity, not proof - signing (minisign sidecars) is the
#verification layer.
packager = "Julian Noble <julian@precisium.com.au>"
project = "punkshell"
project_url = "unrecorded"
#license: summary for the distributed package; the package's own license text
#rides inside the zip (license.terms etc).
license = "BSD"
build_host_platform = "win32-x86_64"
[library]
#driving_tcl_patchlevel: patchlevel of the suite-built shell that ran the
#installer/critcl - the generation witness, not a runtime version requirement.
driving_tcl_patchlevel = "9.0.5"
[provenance]
#class: build-origin class (schema v2): suite-built | third-party | local.
#NOTE for line-based consumers: '[artifact] class' above is the first 'class ='
#line in the record by construction - whole-text single-key scans see that one.
class = "suite-built"
suite = "suite_tcl90"
toolchain = "zig 0.16.0"
optimize = "ReleaseFast"
#critcl: version declared by the package's own critcl-generated teapot.txt
critcl = "3.3.1"
tcllib_checkout = "c784f6fda4516f676453a2785b3c56f1ca5999f450e80ccba6c317ba78ce4e21"
critcl_checkout = "254bdffe2afc78148f79f92df8d6823a24f971bf"

42
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/teapot.txt

@ -1,21 +1,21 @@
Package tcllibc 2.0
Meta platform linux-glibc2.22-x86_64
Meta build::date 2025-08-20
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::date critcl
Meta license BSD licensed.
Meta author {Andreas Kupries}
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9}
Meta entrytclcommand {eval "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"}
Meta included critcl-rt.tcl linux-x86_64/tcllibc.so
Package tcllibc 2.0
Meta platform linux-x86_64
Meta build::date 2026-07-30
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::by {critcl 3.3.1} jnoble {critcl 3.3.1} jnoble
Meta generated::date critcl
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9}
Meta license BSD licensed.
Meta author {Andreas Kupries}
Meta entrytclcommand {eval "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"}
Meta included critcl-rt.tcl linux-x86_64/tcllibc.so

381
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/critcl-rt.tcl

@ -1,381 +0,0 @@
#
# Critcl - build C extensions on-the-fly
#
# Copyright (c) 2001-2007 Jean-Claude Wippler
# Copyright (c) 2002-2007 Steve Landers
#
# See http://wiki.tcl.tk/critcl
#
# This is the Critcl runtime that loads the appropriate
# shared library when a package is requested
#
namespace eval ::critcl::runtime {}
proc ::critcl::runtime::loadlib {dir package version libname initfun tsrc mapping args} {
# XXX At least parts of this can be done by the package generator,
# XXX like listing the Tcl files to source. The glob here allows
# XXX code-injection after-the-fact, by simply adding a .tcl in
# XXX the proper place.
set path [file join $dir [MapPlatform $mapping]]
set ext [info sharedlibextension]
set lib [file join $path $libname$ext]
set provide [list]
# Now the runtime equivalent of a series of 'preFetch' commands.
if {[llength $args]} {
set preload [file join $path preload$ext]
foreach p $args {
set prelib [file join $path $p$ext]
if {[file readable $preload] && [file readable $prelib]} {
lappend provide [list load $preload];# XXX Move this out of the loop, do only once.
lappend provide [list ::critcl::runtime::preload $prelib]
}
}
}
lappend provide [list load $lib $initfun]
foreach t $tsrc {
lappend loadcmd "::critcl::runtime::Fetch \$dir [list $t]"
}
lappend provide "package provide $package $version"
package ifneeded $package $version [join $provide "\n"]
return
}
proc ::critcl::runtime::preFetch {path ext dll} {
set preload [file join $path preload$ext]
if {![file readable $preload]} return
set prelib [file join $path $dll$ext]
if {![file readable $prelib]} return
load $preload ; # Defines next command.
::critcl::runtime::preload $prelib
return
}
proc ::critcl::runtime::Fetch {dir t} {
# The 'Ignore' disables compile & run functionality.
# Background: If the regular critcl package is already loaded, and
# this prebuilt package uses its defining .tcl file also as a
# 'tsources' then critcl might try to collect data and build it
# because of the calls to its API, despite the necessary binaries
# already being present, just not in the critcl cache. That is
# redundant in the best case, and fails in the worst case (no
# compiler), preventing the use o a perfectly fine package. The
# 'ignore' call now tells critcl that it should ignore any calls
# made to it by the sourced files, and thus avoids that trouble.
# The other case, the regular critcl package getting loaded after
# this prebuilt package is irrelevant. At that point the tsources
# were already run, and used the dummy procedures defined in the
# critcl-rt.tcl, which ignore the calls by definition.
set t [file join $dir tcl $t]
::critcl::Ignore $t
uplevel #0 [list source $t]
return
}
proc ::critcl::runtime::precopy {dll} {
# This command is only used on Windows when preloading out of a
# VFS that doesn't support direct loading (usually, a Starkit)
# - we preserve the dll name so that dependencies are satisfied
# - The critcl::runtime::preload command is defined in the supporting
# "preload" package, implemented in "critcl/lib/critcl/critcl_c/preload.c"
global env
if {[info exists env(TEMP)]} {
set dir $env(TEMP)
} elseif {[info exists env(TMP)]} {
set dir $env(TMP)
} elseif {[file exists $env(HOME)]} {
set dir $env(HOME)
} else {
set dir .
}
set dir [file join $dir TCL[pid]]
set i 0
while {[file exists $dir]} {
append dir [incr i]
}
set new [file join $dir [file tail $dll]]
file mkdir $dir
file copy $dll $new
return $new
}
proc ::critcl::runtime::MapPlatform {{mapping {}}} {
# A sibling of critcl::platform that applies the platform mapping
set platform [::platform::generic]
set version $::tcl_platform(osVersion)
if {[string match "macosx-*" $platform]} {
# "normalize" the osVersion to match OSX release numbers
set v [split $version .]
set v1 [lindex $v 0]
set v2 [lindex $v 1]
incr v1 -4
set version 10.$v1.$v2
} else {
# Strip trailing non-version info
regsub -- {-.*$} $version {} version
}
foreach {config map} $mapping {
if {![string match $config $platform]} continue
set minver [lindex $map 1]
if {[package vcompare $version $minver] < 0} continue
set platform [lindex $map 0]
break
}
return $platform
}
# Dummy implementation of the critcl package, if not present
if {![llength [info commands ::critcl::Ignore]]} {
namespace eval ::critcl {}
proc ::critcl::Ignore {args} {
namespace eval ::critcl::v {}
set ::critcl::v::ignore([file normalize [lindex $args 0]]) .
}
}
if {![llength [info commands ::critcl::api]]} {
namespace eval ::critcl {}
proc ::critcl::api {args} {}
}
if {![llength [info commands ::critcl::at]]} {
namespace eval ::critcl {}
proc ::critcl::at {args} {}
}
if {![llength [info commands ::critcl::cache]]} {
namespace eval ::critcl {}
proc ::critcl::cache {args} {}
}
if {![llength [info commands ::critcl::ccode]]} {
namespace eval ::critcl {}
proc ::critcl::ccode {args} {}
}
if {![llength [info commands ::critcl::ccommand]]} {
namespace eval ::critcl {}
proc ::critcl::ccommand {args} {}
}
if {![llength [info commands ::critcl::cdata]]} {
namespace eval ::critcl {}
proc ::critcl::cdata {args} {}
}
if {![llength [info commands ::critcl::cdefines]]} {
namespace eval ::critcl {}
proc ::critcl::cdefines {args} {}
}
if {![llength [info commands ::critcl::cflags]]} {
namespace eval ::critcl {}
proc ::critcl::cflags {args} {}
}
if {![llength [info commands ::critcl::cheaders]]} {
namespace eval ::critcl {}
proc ::critcl::cheaders {args} {}
}
if {![llength [info commands ::critcl::check]]} {
namespace eval ::critcl {}
proc ::critcl::check {args} {return 0}
}
if {![llength [info commands ::critcl::cinit]]} {
namespace eval ::critcl {}
proc ::critcl::cinit {args} {}
}
if {![llength [info commands ::critcl::clibraries]]} {
namespace eval ::critcl {}
proc ::critcl::clibraries {args} {}
}
if {![llength [info commands ::critcl::compiled]]} {
namespace eval ::critcl {}
proc ::critcl::compiled {args} {return 1}
}
if {![llength [info commands ::critcl::compiling]]} {
namespace eval ::critcl {}
proc ::critcl::compiling {args} {return 0}
}
if {![llength [info commands ::critcl::config]]} {
namespace eval ::critcl {}
proc ::critcl::config {args} {}
}
if {![llength [info commands ::critcl::cproc]]} {
namespace eval ::critcl {}
proc ::critcl::cproc {args} {}
}
if {![llength [info commands ::critcl::csources]]} {
namespace eval ::critcl {}
proc ::critcl::csources {args} {}
}
if {![llength [info commands ::critcl::debug]]} {
namespace eval ::critcl {}
proc ::critcl::debug {args} {}
}
if {![llength [info commands ::critcl::done]]} {
namespace eval ::critcl {}
proc ::critcl::done {args} {return 1}
}
if {![llength [info commands ::critcl::failed]]} {
namespace eval ::critcl {}
proc ::critcl::failed {args} {return 0}
}
if {![llength [info commands ::critcl::framework]]} {
namespace eval ::critcl {}
proc ::critcl::framework {args} {}
}
if {![llength [info commands ::critcl::include]]} {
namespace eval ::critcl {}
proc ::critcl::include {args} {}
}
if {![llength [info commands ::critcl::ldflags]]} {
namespace eval ::critcl {}
proc ::critcl::ldflags {args} {}
}
if {![llength [info commands ::critcl::license]]} {
namespace eval ::critcl {}
proc ::critcl::license {args} {}
}
if {![llength [info commands ::critcl::load]]} {
namespace eval ::critcl {}
proc ::critcl::load {args} {return 1}
}
if {![llength [info commands ::critcl::make]]} {
namespace eval ::critcl {}
proc ::critcl::make {args} {}
}
if {![llength [info commands ::critcl::meta]]} {
namespace eval ::critcl {}
proc ::critcl::meta {args} {}
}
if {![llength [info commands ::critcl::platform]]} {
namespace eval ::critcl {}
proc ::critcl::platform {args} {}
}
if {![llength [info commands ::critcl::preload]]} {
namespace eval ::critcl {}
proc ::critcl::preload {args} {}
}
if {![llength [info commands ::critcl::source]]} {
namespace eval ::critcl {}
proc ::critcl::source {args} {}
}
if {![llength [info commands ::critcl::tcl]]} {
namespace eval ::critcl {}
proc ::critcl::tcl {args} {}
}
if {![llength [info commands ::critcl::tk]]} {
namespace eval ::critcl {}
proc ::critcl::tk {args} {}
}
if {![llength [info commands ::critcl::tsources]]} {
namespace eval ::critcl {}
proc ::critcl::tsources {args} {}
}
if {![llength [info commands ::critcl::userconfig]]} {
namespace eval ::critcl {}
proc ::critcl::userconfig {args} {}
}
# Define a clone of platform::generic, if needed
if {![llength [info commands ::platform::generic]]} {
namespace eval ::platform {}
proc ::platform::generic {} {
global tcl_platform
set plat [string tolower [lindex $tcl_platform(os) 0]]
set cpu $tcl_platform(machine)
switch -glob -- $cpu {
sun4* {
set cpu sparc
}
intel -
ia32* -
i*86* {
set cpu ix86
}
x86_64 {
if {$tcl_platform(wordSize) == 4} {
# See Example <1> at the top of this file.
set cpu ix86
}
}
ppc -
"Power*" {
set cpu powerpc
}
"arm*" {
set cpu arm
}
ia64 {
if {$tcl_platform(wordSize) == 4} {
append cpu _32
}
}
}
switch -glob -- $plat {
windows {
if {$tcl_platform(platform) == "unix"} {
set plat cygwin
} else {
set plat win32
}
if {$cpu eq "amd64"} {
# Do not check wordSize, win32-x64 is an IL32P64 platform.
set cpu x86_64
}
}
sunos {
set plat solaris
if {[string match "ix86" $cpu]} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
} elseif {![string match "ia64*" $cpu]} {
# sparc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
darwin {
set plat macosx
# Correctly identify the cpu when running as a 64bit
# process on a machine with a 32bit kernel
if {$cpu eq "ix86"} {
if {$tcl_platform(wordSize) == 8} {
set cpu x86_64
}
}
}
aix {
set cpu powerpc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
hp-ux {
set plat hpux
if {![string match "ia64*" $cpu]} {
set cpu parisc
if {$tcl_platform(wordSize) == 8} {
append cpu 64
}
}
}
osf1 {
set plat tru64
}
default {
set plat [lindex [split $plat _-] 0]
}
}
return "${plat}-${cpu}"
}
}

1
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/license.terms

@ -1 +0,0 @@
<<Undefined>>

BIN
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/linux-x86_64/tcllibc.so

Binary file not shown.

2
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/pkgIndex.tcl

@ -1,2 +0,0 @@
if {![package vsatisfies [package provide Tcl] 9.0]} {return}
package ifneeded tcllibc 2.0 "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"

21
src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/teapot.txt

@ -1,21 +0,0 @@
Package tcllibc 2.0
Meta platform linux-glibc2.22-x86_64
Meta build::date 2025-08-20
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::by {critcl 3.3} obermeier {critcl 3.3} obermeier
Meta generated::date critcl
Meta license BSD licensed.
Meta author {Andreas Kupries}
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9} {Tcl 8.5 9}
Meta require {Tcl 8.5 9} {Tcl 8.5 9}
Meta entrytclcommand {eval "[list proc __critcl_load__ {dir} { ; source [file join $dir critcl-rt.tcl] ; set path [file join $dir [::critcl::runtime::MapPlatform]] ; set ext [info sharedlibextension] ; set lib [file join $path "tcllibc$ext"] ; load $lib Tcllibc ; package provide tcllibc 2.0 ; catch {rename __critcl_load__ {}}}] ; [list __critcl_load__ $dir]"}
Meta included critcl-rt.tcl linux-x86_64/tcllibc.so
Loading…
Cancel
Save