diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index e666b79c..2a72681a 100644 --- a/ARCHITECTURE.md +++ b/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/` 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 `-` 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 `.resources.toml` sidecar (deployed beside `bin/`) 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/`, 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/` tier with server-trust consent, and the PACKAGES_tcl libs phase + vfslibs packages-root declarations feed the deployed `lib_tcl` 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__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/`, embedded schema-v2 class=library records, punkzip-deterministic) - the `library-artifacts` step in each recipe. The tier's `` 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/` tier with server-trust consent, and the PACKAGES_tcl libs phase + vfslibs packages-root declarations feed the deployed `lib_tcl` 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__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. diff --git a/CHANGELOG.md b/CHANGELOG.md index aa8f3ab3..29fe0e71 100644 --- a/CHANGELOG.md +++ b/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.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` diff --git a/GOALS-archive.md b/GOALS-archive.md index ed41de98..a2aad9f3 100644 --- a/GOALS-archive.md +++ b/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// (new untracked materialization tier mirroring bin/runtime//); 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 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// 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/allplatforms and lib_tcl/ 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.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/ 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). diff --git a/GOALS.md b/GOALS.md index a4b8d785..fa43e619 100644 --- a/GOALS.md +++ b/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 diff --git a/goals/G-105-buildsuite-cross-target.md b/goals/G-105-buildsuite-cross-target.md index 922fcebc..0846fbb8 100644 --- a/goals/G-105-buildsuite-cross-target.md +++ b/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. diff --git a/goals/G-140-linux-lib-tier-emission.md b/goals/G-140-linux-lib-tier-emission.md index 132360fc..3b6d0412 100644 --- a/goals/G-140-linux-lib-tier-emission.md +++ b/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//) - 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 + /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/ 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/ folders (G-138). After publication, the + already-declared libpackages.toml entry serves plain canonical + 'make.tcl libfetch' with no further edits. diff --git a/punkproject.toml b/punkproject.toml index 0075f4ca..41fd5be3 100644 --- a/punkproject.toml +++ b/punkproject.toml @@ -1,4 +1,4 @@ [project] name = "punkshell" -version = "0.32.1" +version = "0.32.2" license = "BSD-2-Clause" diff --git a/src/buildsuites/AGENTS.md b/src/buildsuites/AGENTS.md index 5e0e1c1d..bc24cebd 100644 --- a/src/buildsuites/AGENTS.md +++ b/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, diff --git a/src/buildsuites/suite_tcl86/tools/library_artifacts.tcl b/src/buildsuites/suite_tcl86/tools/library_artifacts.tcl index 4929fc2d..b2844697 100644 --- a/src/buildsuites/suite_tcl86/tools/library_artifacts.tcl +++ b/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]" diff --git a/src/buildsuites/suite_tcl90/README.md b/src/buildsuites/suite_tcl90/README.md index cd7fc26e..da9f7ef4 100644 --- a/src/buildsuites/suite_tcl90/README.md +++ b/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= ` 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 `.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 `.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.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 diff --git a/src/buildsuites/suite_tcl90/build905.zig b/src/buildsuites/suite_tcl90/build905.zig index 78667210..f4d27938 100644 --- a/src/buildsuites/suite_tcl90/build905.zig +++ b/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 (-tcl9-r.zip + toml + sha1sums) from the verified tcllib/tcllibc installs -> /library/punkbin/lib"); + const library_artifacts_step = b.step("library-artifacts", "emit punkbin lib-tier artifacts (-tcl9-r.zip + toml + sha1sums) from the verified tcllib/tcllibc installs incl. the linux-x86_64 cross build -> /library/punkbin/lib"); const librev = b.option(u32, "librev", "assembly revision N for the -r 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, "/", "_"); diff --git a/src/buildsuites/suite_tcl90/critcl_zig.config b/src/buildsuites/suite_tcl90/critcl_zig.config index e38ce851..507f5d78 100644 --- a/src/buildsuites/suite_tcl90/critcl_zig.config +++ b/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
': 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 +# // 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 diff --git a/src/buildsuites/suite_tcl90/suite.tcl b/src/buildsuites/suite_tcl90/suite.tcl index 7d450e1e..81f4f0b9 100644 --- a/src/buildsuites/suite_tcl90/suite.tcl +++ b/src/buildsuites/suite_tcl90/suite.tcl @@ -22,15 +22,17 @@ # -seedfossils read-only seed collection for missing clones (default ~/.fossils; "" disables) # -all <0|1> with 'clean': reserved (the clone store lives outside the stage) # -steps 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 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 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 {} diff --git a/src/buildsuites/suite_tcl90/tools/elf_gate.tcl b/src/buildsuites/suite_tcl90/tools/elf_gate.tcl new file mode 100644 index 00000000..d48848e6 --- /dev/null +++ b/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 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 required architecture: x86_64 | arm64 | i386 +#exit 0: every member classifies as ELF64 LSB ET_DYN ; 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 diff --git a/src/buildsuites/suite_tcl90/tools/library_artifacts.tcl b/src/buildsuites/suite_tcl90/tools/library_artifacts.tcl index 4929fc2d..b2844697 100644 --- a/src/buildsuites/suite_tcl90/tools/library_artifacts.tcl +++ b/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]" diff --git a/src/runtime/libpackages.toml b/src/runtime/libpackages.toml index c5625742..fad5883e 100644 --- a/src/runtime/libpackages.toml +++ b/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" diff --git a/src/runtime/vendorlib_vfs.toml b/src/runtime/vendorlib_vfs.toml index b24aa27d..f5b3ec29 100644 --- a/src/runtime/vendorlib_vfs.toml +++ b/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" diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/critcl-rt.tcl b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/critcl-rt.tcl index 01053a30..84c74113 100644 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/critcl-rt.tcl +++ b/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}" + } +} + + diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms index 96651147..6975e4c9 100644 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms +++ b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/license.terms @@ -1 +1 @@ -<> +<> diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so index dee52eee..b84c100f 100644 Binary files a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so and b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/linux-x86_64/tcllibc.so differ diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/pkgIndex.tcl b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/pkgIndex.tcl index 03a1100a..7b6fb366 100644 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/pkgIndex.tcl +++ b/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]" diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/punkbin-artifact.toml b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/punkbin-artifact.toml new file mode 100644 index 00000000..ff01732b --- /dev/null +++ b/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 " +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" diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/teapot.txt b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/teapot.txt index a0cd3d29..cf2d7786 100644 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc/teapot.txt +++ b/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 diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/critcl-rt.tcl b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/critcl-rt.tcl deleted file mode 100644 index 01053a30..00000000 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/critcl-rt.tcl +++ /dev/null @@ -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}" - } -} - - diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/license.terms b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/license.terms deleted file mode 100644 index 96651147..00000000 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/license.terms +++ /dev/null @@ -1 +0,0 @@ -<> diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/linux-x86_64/tcllibc.so b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/linux-x86_64/tcllibc.so deleted file mode 100644 index dee52eee..00000000 Binary files a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/linux-x86_64/tcllibc.so and /dev/null differ diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/pkgIndex.tcl b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/pkgIndex.tcl deleted file mode 100644 index 03a1100a..00000000 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/pkgIndex.tcl +++ /dev/null @@ -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]" diff --git a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/teapot.txt b/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/teapot.txt deleted file mode 100644 index a0cd3d29..00000000 --- a/src/vfs/punk9linux.vfs/lib_tcl9/tcllibc2.0/teapot.txt +++ /dev/null @@ -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