Browse Source
Activation gated on the G-112 rename core + G-104 contract (both achieved
today); score re-run recorded. First increment:
- suite_tcl86/: sources.config (source + self-description records - lists and
describes itself via 'make.tcl buildsuite list/info' with no make.tcl
edits), suite.tcl fork (folder-derived naming, {tcl tclthread tclvfs}
requireds, build86.zig recipe file), build86.zig pending-derivation skeleton
(staging succeeds, recipe fails with a clear message), build.zig.zon with
real zig-fetch hashes, README with the DERIVATION record.
- Thread 2.8 selection: thread-2-8-branch @ e14fa771ae (tagged thread-2-8-13,
2.8.13); configure.ac TCL_MAJOR_VERSION==8 guard confirms the pairing.
- 8.6 source records in BOTH flows: dev refs (core-8-6-branch -> tcl86,
thread-2-8-branch, tclvfs trunk 1.4.2-era) + zon per-checkin pins
(tcl 1d1d5cbd91 = 8.6.18 era).
- First staging run through 'make.tcl buildsuite build suite_tcl86' (a real
driver run through the G-104 surface): checkouts staged from the shared
hermetic store, TCL_PATCH_LEVEL 8.6.18 read from the tree.
- makefile.vc derivation findings recorded incl. two Context corrections:
8.6.18 DOES generate tclUuid.h; zlib is prebuilt-import in stock nmake
(zig-only recipe will compile compat/zlib statically).
Core-test census + baseline deliberately pending until a built tclsh86 exists
(recorded in Progress).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
8 changed files with 581 additions and 2 deletions
@ -0,0 +1,101 @@ |
|||||||
|
# suite_tcl86 - zig buildsuite for Tcl core-8-6-branch (G-099) |
||||||
|
|
||||||
|
Builds a Tcl 8.6 windows runtime from fossil core-8-6-branch sources with the |
||||||
|
pinned zig toolchain only (zig-only build policy; msys/mingw and MS toolchains |
||||||
|
remain test/validation-only), together with the core binary companions |
||||||
|
punkshell's Tcl 8 targets need - thread 2.8 and tclvfs - gated against the 8.6 |
||||||
|
core testsuite. Forked from `suite_tcl90` (the shape reference); shared |
||||||
|
scaffolding stays duplicated-with-a-note until this second consumer makes the |
||||||
|
right factoring obvious (G-099 Context). |
||||||
|
|
||||||
|
STATUS: recipe derivation IN PROGRESS. `suite.tcl build` stages the source |
||||||
|
checkouts (useful on its own - the derivation studies the staged |
||||||
|
`tcl86/win/makefile.vc`) and then fails at the `build86.zig` skeleton with a |
||||||
|
clear pending message. Progress ledger: `goals/G-099-suite-tcl86-buildsuite.md`. |
||||||
|
|
||||||
|
## Deliverables (per the G-099 acceptance) |
||||||
|
|
||||||
|
- `tclsh86.exe` + tcl86 dll + installed lib tree the shell resolves without |
||||||
|
external Tcl installations (TCLLIBPATH/TCL_LIBRARY unset in all suite child |
||||||
|
invocations). NO zipfs in 8.6 - no self-contained szip runtime is possible; |
||||||
|
this suite delivers exe + dll + on-disk lib tree only (kit containment is |
||||||
|
G-101 territory). |
||||||
|
- thread (thread-2-8-branch) and tclvfs (trunk) built and loading in that shell. |
||||||
|
- `suite.tcl test` runs the 8.6 core testsuite, parses totals (exit codes not |
||||||
|
trusted), and gates against a tracked `expected_test_failures.txt` baseline - |
||||||
|
the FIRST CENSUS is pending (the 9.0.5 census does not transfer; machine |
||||||
|
traits dispositioned there will likely reappear under 8.6 test names). |
||||||
|
|
||||||
|
## Sources (both flows carry the same identity) |
||||||
|
|
||||||
|
- Dev flow: `sources.config` (live refs; `suite.tcl build` stages checkouts |
||||||
|
from the hermetic clone store shared with suite_tcl90). |
||||||
|
- No-tclsh flow: `build.zig.zon` (content-hashed per-checkin pins, recorded |
||||||
|
from this suite's first commit; the bootstrap `build.zig` driver lands with |
||||||
|
the recipe). |
||||||
|
|
||||||
|
Selections (2026-07-25, staged and verified): |
||||||
|
|
||||||
|
- tcl: `core-8-6-branch` - tip checkin 1d1d5cbd91 = **8.6.18** era |
||||||
|
(TCL_PATCH_LEVEL "8.6.18" in the staged tree). |
||||||
|
- thread: `thread-2-8-branch` - tip checkin e14fa771ae, tagged |
||||||
|
**thread-2-8-13** (2.8.13, 2026-04-30). 8.6 pairs with the 2.8 line; the |
||||||
|
checkout's configure.ac guards `TCL_MAJOR_VERSION == 8` (trunk/3.x targets |
||||||
|
Tcl 9). Thread ships TEA + `win/makefile.vc` build surfaces. |
||||||
|
- tclvfs: `trunk` - tip checkin 9954261983 (1.4.2 era). The `forTcl9` branch |
||||||
|
(1.5.0) is tcl9-only (user decision 2026-07-22, recorded in suite_tcl90's |
||||||
|
sources.config). |
||||||
|
|
||||||
|
## DERIVATION (build86.zig from the staged 8.6.18 win/makefile.vc) |
||||||
|
|
||||||
|
Recorded findings from the staged tree (assess-not-assume items from the G-099 |
||||||
|
Context, verified 2026-07-25): |
||||||
|
|
||||||
|
- `TCLOBJS = COREOBJS + ZLIBOBJS + TOMMATHOBJS + PLATFORMOBJS` |
||||||
|
(makefile.vc:218/323/390/412) - the object inventory the recipe expresses. |
||||||
|
- **zlib divergence (key)**: 8.6's makefile.vc does NOT compile zlib - it |
||||||
|
copies PREBUILT `compat/zlib/win{32,win64,win64-arm}/zdll.lib` + `zlib1.dll` |
||||||
|
(makefile.vc:548-559) and links the import lib (`ZLIBOBJS = zdll.lib`). The |
||||||
|
zig-only build compiles `compat/zlib` sources instead (suite_tcl90's |
||||||
|
build_zlib helper pattern) - decision: compile zlib STATICALLY into the tcl86 |
||||||
|
dll, eliminating the shipped `zlib1.dll` (record the deviation from stock |
||||||
|
layout in the recipe; stock nmake builds ship zlib1.dll beside the dll). |
||||||
|
- libtommath: in-tree at `$(ROOT)/libtommath` with `TOMMATHOBJS` compiled into |
||||||
|
the core (same in-core model as 9.0; tree paths/versions differ - |
||||||
|
build_libtommath helper reusable with dir adjustments). |
||||||
|
- `tclUuid.h`: 8.6.18 DOES generate it (makefile.vc:797-802, |
||||||
|
`manifest.uuid` -> `tclUuid.h` via tclUuid.h.in) - the G-099 Context's |
||||||
|
"no tclUuid.h" assessment was outdated; the 9.0 recipe's generation step |
||||||
|
carries over with the 8.6 input paths. |
||||||
|
- Entry points: `TCL_BROKEN_MAINARGS` handling lives in `win/tclAppInit.c` |
||||||
|
(8 occurrences; generic/tclMain.c has none) - the mingw-class argv handling |
||||||
|
for zig cc lands there, distinct from the 9.0.5 mingw-unicode-entry work. |
||||||
|
- Bundled extensions built by makefile.vc: `dde 1.4.6`, `registry 1.3.5` |
||||||
|
(dlls or static per OPTS; the 9.1-era statics probe showed Dde 1.5b0 - the |
||||||
|
8.6 line is older). Decide inclusion when the recipe lands (punk86-class |
||||||
|
kits historically carry them). |
||||||
|
- No `generic/tclZipfs.c` (confirmed): no zipfs, no script-library zip |
||||||
|
embedding - the install step lays the `library/` tree on disk |
||||||
|
(`lib/tcl8.6/...`), and `init.tcl` resolution rides `TCL_LIBRARY`-free |
||||||
|
relative discovery from the exe path. |
||||||
|
- rules.vc/makefile.vc are the config authority (1066 + 1883 lines staged); |
||||||
|
versions derive from `library/init.tcl` + `generic/tcl.h` |
||||||
|
(TCL_PATCH_LEVEL "8.6.18") - version-derived output names (tcl86t.dll |
||||||
|
naming class, tclsh86 vs tclsh8.6 spellings) settle with the recipe. |
||||||
|
|
||||||
|
Remaining derivation work (tracked in G-099 Progress): express COREOBJS/ |
||||||
|
PLATFORMOBJS source lists + defines in build86.zig (build905.zig + |
||||||
|
build_common.zig as the shape reference), decide static-vs-dll core linkage |
||||||
|
for the punk86-class consumers, port the manifest/rc resource step, wire |
||||||
|
thread 2.8 + tclvfs builds (TEA-style configure products generated |
||||||
|
recipe-side as in 9.0), then the core-test gate + first census. |
||||||
|
|
||||||
|
## Flows |
||||||
|
|
||||||
|
- FOSSIL DEV FLOW: `tclsh suite.tcl build|test|clean` (or via the make.tcl |
||||||
|
surface: `tclsh src/make.tcl buildsuite build suite_tcl86 ?driver-args?`). |
||||||
|
- NO-TCLSH FLOW: `zig build stage|bootstrap` - lands with the recipe; |
||||||
|
`build.zig.zon` pins are already recorded. |
||||||
|
|
||||||
|
The suite self-description contract (records in `sources.config` read by |
||||||
|
`make.tcl buildsuite list/info`) is documented in `src/buildsuites/README.md`. |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
//build.zig.zon - suite_tcl86 pinned source manifest (G-099). |
||||||
|
// |
||||||
|
//The CONTENT-HASHED tweak surface for the no-tclsh bootstrap flow (G-102 shape - |
||||||
|
//see suite_tcl90/build.zig.zon for the mechanism documentation: per-checkin |
||||||
|
//tarball urls + zig package hashes; 'zig fetch <url>' prints a hash, branch-tip |
||||||
|
//urls are deliberately NOT used - the pin IS the provenance record). |
||||||
|
// |
||||||
|
//The bootstrap build.zig driver lands with the recipe (build86.zig is a |
||||||
|
//pending-derivation skeleton); these records pin the 8.6 sources from the |
||||||
|
//suite's FIRST COMMIT so both flows carry the same source identity |
||||||
|
//(sources.config = live dev-flow refs on the same repositories/branches). |
||||||
|
//Hashes below were computed with the pinned zig 0.16.0 ('zig fetch') on |
||||||
|
//2026-07-25. |
||||||
|
.{ |
||||||
|
.name = .suite_tcl86, |
||||||
|
.version = "0.0.1", |
||||||
|
.fingerprint = 0x9fe14fa771ae8617, |
||||||
|
.minimum_zig_version = "0.16.0", |
||||||
|
.dependencies = .{ |
||||||
|
//tcl core-8-6-branch checkout 1d1d5cbd91 2026-07-14 (8.6.17+ maintenance era) |
||||||
|
.tcl = .{ |
||||||
|
.url = "https://core.tcl-lang.org/tcl/tarball/1d1d5cbd91ebdb4a91246e9d63b8763622179c2d0d744a7e75d7d6580a70514a/tcl.tar.gz", |
||||||
|
.hash = "N-V-__8AAA0mDwKkYPpxjZfpjor-2EFvJY-hcGnmmhaPDwbM", |
||||||
|
.lazy = true, |
||||||
|
}, |
||||||
|
//thread thread-2-8-branch checkout e14fa771ae 2026-04-30 (tagged thread-2-8-13; 2.8.13 - |
||||||
|
//the 8.6-compatible thread line; trunk/3.x targets Tcl 9. Selection: goals G-099) |
||||||
|
.tclthread = .{ |
||||||
|
.url = "https://core.tcl-lang.org/thread/tarball/e14fa771ae2e4bdca37a3afb4d4fe65b30fb41e544fec6104b070a47929a5310/thread.tar.gz", |
||||||
|
.hash = "N-V-__8AAHbmFACk7qBbJWoGQonF60vKEbOCuMbsEXkJN2lf", |
||||||
|
.lazy = true, |
||||||
|
}, |
||||||
|
//tclvfs trunk checkout 9954261983 2020-02-25 (1.4.2 era - 8.6 suites keep trunk; |
||||||
|
//the forTcl9 branch (1.5.0) is tcl9-only, user decision 2026-07-22) |
||||||
|
.tclvfs = .{ |
||||||
|
.url = "https://core.tcl-lang.org/tclvfs/tarball/995426198338747be626b38cb267eb3dd81fc4258c59e64aec6b91376a26935d/tclvfs.tar.gz", |
||||||
|
.hash = "N-V-__8AAIaeDQBJ9V3M96hpQSxemxghwLBG8fB1s0rqh4SQ", |
||||||
|
.lazy = true, |
||||||
|
}, |
||||||
|
}, |
||||||
|
.paths = .{""}, |
||||||
|
} |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
//build86.zig - suite_tcl86 zig recipe (G-099) - DERIVATION IN PROGRESS. |
||||||
|
// |
||||||
|
//This is a deliberate pending-state skeleton: 'suite.tcl build' stages the |
||||||
|
//core-8-6-branch / thread-2-8-branch / tclvfs-trunk sources (useful on its own - |
||||||
|
//the checkout carries win/makefile.vc, the derivation source of truth) and then |
||||||
|
//fails HERE with a clear message instead of pretending to build. |
||||||
|
// |
||||||
|
//Derivation record (what this recipe must express, from 8.6's win/makefile.vc): |
||||||
|
//see README.md section DERIVATION. The 9.0.5 recipe (suite_tcl90/build905.zig + |
||||||
|
//build_common.zig + build_zlib/build_libtommath/build_tclvfs/build_tclthread |
||||||
|
//helper modules) is the shape reference; the G-099 Context records the known |
||||||
|
//8.6 differences to verify rather than assume (bundled zlib/libtommath |
||||||
|
//arrangements, no tclUuid.h, makefile.vc-derived manifest/rc generation, |
||||||
|
//TCL_BROKEN_MAINARGS-era entry points, no zipfs). |
||||||
|
const std = @import("std"); |
||||||
|
|
||||||
|
pub fn build(b: *std.Build) void { |
||||||
|
_ = b; |
||||||
|
@compileError("suite_tcl86 recipe derivation in progress (G-099) - sources are staged; see suite_tcl86/README.md DERIVATION for the makefile.vc-derived plan and goals/G-099-suite-tcl86-buildsuite.md for progress"); |
||||||
|
} |
||||||
@ -0,0 +1,40 @@ |
|||||||
|
# sources.config - suite_tcl86 source-pull declarations for the FOSSIL DEV FLOW |
||||||
|
# (live checkouts driven by suite.tcl). This is the tweak surface for retargeting |
||||||
|
# that flow at different repositories/branches/tags. Forked from suite_tcl90 |
||||||
|
# (G-099); build.zig.zon is the equivalent PINNED surface for the no-tclsh flow |
||||||
|
# (records present from this suite's first commit - the bootstrap build.zig |
||||||
|
# driver lands with the recipe). |
||||||
|
# |
||||||
|
# Read by suite.tcl as plain line records - the file is parsed, never executed. |
||||||
|
# Record grammar (whitespace separated, one record per line, # comments and |
||||||
|
# blanks ignored) - the G-104 self-description contract is documented in |
||||||
|
# src/buildsuites/README.md: |
||||||
|
# |
||||||
|
# source <name> <kind> <url> <ref> <dir> |
||||||
|
# description <text...> one line - the list/info one-liner for this suite |
||||||
|
# product <text...> repeatable - what a full build produces |
||||||
|
# doc <relpath> repeatable - suite-relative doc pointers |
||||||
|
# zigpin <relpath> projectroot-relative pinned zig executable |
||||||
|
# |
||||||
|
# dir names are RECIPE-COUPLED: build86.zig references them by relative path |
||||||
|
# (e.g "../tcl86") - keep dir names unless you also adjust the recipe. |
||||||
|
# |
||||||
|
# 8.6-arc notes (G-099): |
||||||
|
# - tcl rides core-8-6-branch (the live 8.6 maintenance line; 8.6.17+ era). |
||||||
|
# Override per-run with 'suite.tcl build -tclbranch <ref>'. |
||||||
|
# - thread rides thread-2-8-branch: 8.6 pairs with thread 2.8 (trunk/3.x |
||||||
|
# targets Tcl 9). Branch tip is the thread-2-8-13-tagged checkin |
||||||
|
# (2.8.13, 2026-04-30) - selection recorded in goals G-099. |
||||||
|
# - tclvfs keeps TRUNK (1.4.2 era): the forTcl9 branch (1.5.0) is for tcl9 |
||||||
|
# suites only (user decision 2026-07-22, recorded in suite_tcl90). |
||||||
|
|
||||||
|
description Zig-built Tcl 8.6 windows runtime (core-8-6-branch): tclsh86 + tcl86 dll + installed lib tree, thread 2.8 + tclvfs, core-test gate (G-099 arc - recipe derivation in progress) |
||||||
|
product tclsh86 executable + tcl86 dll with installed lib tree (no zipfs in 8.6 - no self-contained szip runtime; kit containment is G-101 territory) |
||||||
|
product 8.6-compatible thread (thread-2-8-branch, 2.8.13 era) and tclvfs (trunk, 1.4.2 era) built and loadable in that shell |
||||||
|
product core testsuite gate vs a tracked expected_test_failures baseline (parsed all.tcl totals; first census pending - see README) |
||||||
|
doc README.md |
||||||
|
zigpin bin/tools/zig-x86_64-windows-0.16.0/zig.exe |
||||||
|
|
||||||
|
source tcl fossil https://core.tcl-lang.org/tcl core-8-6-branch tcl86 |
||||||
|
source tclthread fossil https://core.tcl-lang.org/thread thread-2-8-branch tclthread |
||||||
|
source tclvfs fossil https://core.tcl-lang.org/tclvfs trunk tclvfs |
||||||
@ -0,0 +1,324 @@ |
|||||||
|
#!/usr/bin/env tclsh |
||||||
|
#suite_tcl86 dev driver (G-099) - forked from suite_tcl90 (G-096/G-102 shape; |
||||||
|
#duplication-with-a-note is the recorded starting posture - shared scaffolding is |
||||||
|
#factored out only when this second consumer makes the right shape obvious). |
||||||
|
#Stages the tracked zig recipe into ../_build/suite_tcl86, arranges sources from |
||||||
|
#LIVE fossil checkouts, and delegates the build/test pipeline to the staged zig |
||||||
|
#recipe's steps. |
||||||
|
# |
||||||
|
#RECIPE STATUS (G-099): build86.zig is a pending-derivation skeleton - it fails |
||||||
|
#with a clear message after source staging succeeds. Staging alone is useful: it |
||||||
|
#materializes the core-8-6-branch checkout (win/makefile.vc etc) the derivation |
||||||
|
#studies. See README.md DERIVATION. |
||||||
|
# |
||||||
|
#This is the FOSSIL DEV FLOW - convenient live-branch work against checkouts. The |
||||||
|
#equivalent no-tclsh flow ('zig build stage|bootstrap' fetching the build.zig.zon |
||||||
|
#pins) lands with the recipe; the zon pins are recorded from this suite's first |
||||||
|
#commit. |
||||||
|
# |
||||||
|
#Usage: tclsh suite.tcl build ?options? |
||||||
|
# tclsh suite.tcl test ?-testargs {tcltest args}? |
||||||
|
# tclsh suite.tcl clean |
||||||
|
#Options: |
||||||
|
# -zig <path> zig executable (default: $env(PUNK_ZIG), else the sources.config |
||||||
|
# zigpin, else 'zig' on PATH) |
||||||
|
# -optimize <mode> Debug|ReleaseSafe|ReleaseFast|ReleaseSmall (default ReleaseFast) |
||||||
|
# -tclbranch <branch> override the 'tcl' ref from sources.config for this run |
||||||
|
# (default: core-8-6-branch) |
||||||
|
# -refresh <0|1> pull clones + fossil update existing source checkouts (default 0) |
||||||
|
# -repofolder <dir> fossil clone store (default ~/.punkshell/fossils; env PUNK_FOSSIL_STORE) |
||||||
|
# -seedfossils <dir> read-only seed collection for missing clones (default ~/.fossils; "" disables) |
||||||
|
# -all <0|1> with 'clean': reserved (the clone store lives outside the stage) |
||||||
|
# -steps <list> zig build steps. 'build' default: {install} (grows with the |
||||||
|
# recipe: thread/tclvfs installs, smoke, per G-099). |
||||||
|
# 'test' default: {test-gate} (the 8.6 core suite gate vs the |
||||||
|
# tracked expected_test_failures baseline - pending first census). |
||||||
|
# -zigargs <list> extra args appended to the zig build invocation |
||||||
|
# |
||||||
|
#The build area lives entirely under src/buildsuites/_build (VCS-ignored). Fossil |
||||||
|
#clones live in the punkshell-owned machine-level store ~/.punkshell/fossils |
||||||
|
#(shared with suite_tcl90 - tcl/tclthread/tclvfs clone names are common). |
||||||
|
#Checkouts use FOSSIL_HOME=<stage> so the user's global fossil config db records |
||||||
|
#nothing. 'clean' wipes the stage; the store lives outside it. |
||||||
|
|
||||||
|
set suiteroot [file dirname [file normalize [info script]]] |
||||||
|
set suitename [file tail $suiteroot] |
||||||
|
#stage derived from the suite FOLDER name so a copied tree (copy-and-tweak workflow, |
||||||
|
#see sources.config) stages into its own _build/<name> - copies stay isolated. |
||||||
|
set stage [file normalize [file join $suiteroot .. _build $suitename]] |
||||||
|
set builddir [file join $stage build] |
||||||
|
|
||||||
|
proc log {msg} {puts stdout "$::suitename: $msg"; flush stdout} |
||||||
|
proc fail {msg} {puts stderr "$::suitename ERROR: $msg"; flush stderr; exit 1} |
||||||
|
|
||||||
|
proc run {args} { |
||||||
|
#stream output; abort on nonzero exit |
||||||
|
log "run: $args" |
||||||
|
if {[catch {exec {*}$args >@stdout 2>@stderr} err opts]} { |
||||||
|
set code [dict get $opts -errorcode] |
||||||
|
if {[lindex $code 0] eq "CHILDSTATUS"} { |
||||||
|
fail "command failed (exit [lindex $code 2]): $args" |
||||||
|
} |
||||||
|
fail "command failed: $args\n$err" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#-- sources.config load --------------------------------------------------- |
||||||
|
#Declared in sources.config (the copy-and-tweak surface for the LIVE-checkout dev |
||||||
|
#flow - see its header; build.zig.zon is the equivalent PINNED surface for the |
||||||
|
#no-tclsh flow). Parsed as line records - never executed. |
||||||
|
#Record grammar incl. the G-104 self-description records: see |
||||||
|
#src/buildsuites/README.md ('make.tcl buildsuite list/info' reads the same records). |
||||||
|
proc load_sources_config {path} { |
||||||
|
set config [dict create sources [dict create] description "" products [list] docs [list] zigpin ""] |
||||||
|
set f [open $path r]; set data [read $f]; close $f |
||||||
|
set ln 0 |
||||||
|
foreach line [split $data \n] { |
||||||
|
incr ln |
||||||
|
set line [string trim $line] |
||||||
|
if {$line eq "" || [string index $line 0] eq "#"} {continue} |
||||||
|
if {[catch {llength $line} len]} { |
||||||
|
fail "sources.config line $ln: not a well-formed record: $line" |
||||||
|
} |
||||||
|
switch -- [lindex $line 0] { |
||||||
|
source { |
||||||
|
if {$len != 6} { |
||||||
|
fail "sources.config line $ln: expected 'source <name> <kind> <url> <ref> <dir>' - got: $line" |
||||||
|
} |
||||||
|
lassign $line -> name kind url ref dir |
||||||
|
if {$kind ni {fossil git}} { |
||||||
|
fail "sources.config line $ln: unknown kind '$kind' (expected fossil|git)" |
||||||
|
} |
||||||
|
dict set config sources $name [dict create kind $kind url $url ref $ref dir $dir] |
||||||
|
} |
||||||
|
description { |
||||||
|
dict set config description [join [lrange $line 1 end] " "] |
||||||
|
} |
||||||
|
product { |
||||||
|
dict lappend config products [join [lrange $line 1 end] " "] |
||||||
|
} |
||||||
|
doc { |
||||||
|
dict lappend config docs [lindex $line 1] |
||||||
|
} |
||||||
|
zigpin { |
||||||
|
dict set config zigpin [lindex $line 1] |
||||||
|
} |
||||||
|
default { |
||||||
|
fail "sources.config line $ln: unknown record type '[lindex $line 0]' (expected source|description|product|doc|zigpin)" |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return $config |
||||||
|
} |
||||||
|
set suiteconfig [load_sources_config [file join $suiteroot sources.config]] |
||||||
|
set sources [dict get $suiteconfig sources] |
||||||
|
|
||||||
|
#-- options --------------------------------------------------------------- |
||||||
|
set action [lindex $argv 0] |
||||||
|
if {$action ni {build test clean}} { |
||||||
|
puts stderr "usage: tclsh suite.tcl build|test|clean ?options? (see header)" |
||||||
|
exit 2 |
||||||
|
} |
||||||
|
array set opt { |
||||||
|
-optimize ReleaseFast |
||||||
|
-tclbranch {} |
||||||
|
-refresh 0 |
||||||
|
-steps {install} |
||||||
|
-testargs {} |
||||||
|
-zigargs {} |
||||||
|
-repofolder {} |
||||||
|
-all 0 |
||||||
|
} |
||||||
|
set explicitopts {} |
||||||
|
set opt(-seedfossils) [file normalize [file join $env(HOME) .fossils]] |
||||||
|
#zig resolution: -zig option > PUNK_ZIG env > the sources.config zigpin record |
||||||
|
#(projectroot-relative; single source of truth shared with 'make.tcl buildsuite |
||||||
|
#info') > 'zig' on PATH. The recipe targets the pinned zig 0.16 API (as |
||||||
|
#suite_tcl90 - see its README Lineage). |
||||||
|
if {[dict get $suiteconfig zigpin] ne ""} { |
||||||
|
set pinned_zig [file normalize [file join $suiteroot .. .. .. [dict get $suiteconfig zigpin]]] |
||||||
|
} else { |
||||||
|
set pinned_zig [file normalize [file join $suiteroot .. .. .. bin tools zig-x86_64-windows-0.16.0 zig.exe]] |
||||||
|
} |
||||||
|
if {[info exists env(PUNK_ZIG)]} { |
||||||
|
set opt(-zig) $env(PUNK_ZIG) |
||||||
|
} elseif {[file exists $pinned_zig]} { |
||||||
|
set opt(-zig) $pinned_zig |
||||||
|
} else { |
||||||
|
set opt(-zig) "zig" |
||||||
|
} |
||||||
|
foreach {k v} [lrange $argv 1 end] { |
||||||
|
if {![info exists opt($k)]} {fail "unknown option '$k'"} |
||||||
|
set opt($k) $v |
||||||
|
lappend explicitopts $k |
||||||
|
} |
||||||
|
|
||||||
|
#suite-owned clone store resolution: -repofolder > PUNK_FOSSIL_STORE > ~/.punkshell/fossils |
||||||
|
#(shared with suite_tcl90 - see its suite.tcl for the rationale record) |
||||||
|
if {$opt(-repofolder) ne ""} { |
||||||
|
set fossildir [file normalize $opt(-repofolder)] |
||||||
|
} elseif {[info exists env(PUNK_FOSSIL_STORE)] && $env(PUNK_FOSSIL_STORE) ne ""} { |
||||||
|
set fossildir [file normalize $env(PUNK_FOSSIL_STORE)] |
||||||
|
} else { |
||||||
|
if {[info exists env(HOME)] && $env(HOME) ne ""} { |
||||||
|
set homedir $env(HOME) |
||||||
|
} elseif {[info exists env(USERPROFILE)] && $env(USERPROFILE) ne ""} { |
||||||
|
set homedir $env(USERPROFILE) |
||||||
|
} elseif {![catch {file home} h]} { |
||||||
|
set homedir $h |
||||||
|
} else { |
||||||
|
fail "cannot determine home directory for the default fossil store (set PUNK_FOSSIL_STORE or -repofolder)" |
||||||
|
} |
||||||
|
set fossildir [file join [file normalize $homedir] .punkshell fossils] |
||||||
|
} |
||||||
|
|
||||||
|
#Hermetic child shells: the suite-built tclsh must not see the user's machine-level |
||||||
|
#package paths (TCLLIBPATH/TCL_LIBRARY misdirect installer paths and risk |
||||||
|
#false-positive smokes). The zig recipe additionally scrubs these per built-shell |
||||||
|
#Run step (suite_tcl90 G-102 convention, kept for the 8.6 recipe). |
||||||
|
foreach ev {TCLLIBPATH TCL_LIBRARY TK_LIBRARY} { |
||||||
|
if {[info exists env($ev)]} { |
||||||
|
log "unsetting inherited \$env($ev) for hermetic child shells" |
||||||
|
unset env($ev) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
proc run_zig_steps {steps {extraopts {}}} { |
||||||
|
#drive the STAGED recipe (cwd = staged build dir, per-zig-version cache, |
||||||
|
#forward-slash prefix - suite_tcl90 parity) |
||||||
|
global opt builddir stage |
||||||
|
if {![file exists [file join $builddir build86.zig]]} { |
||||||
|
fail "no staged recipe at $builddir - run 'suite.tcl build' first" |
||||||
|
} |
||||||
|
set zigv [exec $opt(-zig) version] |
||||||
|
log "zig: $opt(-zig) ($zigv)" |
||||||
|
#Per-zig-version local cache: object caches must never be shared across zig |
||||||
|
#versions (suite_tcl90-observed stale/duplicate artifacts in the link). |
||||||
|
set cachedir ".zig-cache-[string map {+ _ / _ : _} $zigv]" |
||||||
|
set savedpwd [pwd] |
||||||
|
cd $builddir |
||||||
|
run $opt(-zig) build --build-file build86.zig --cache-dir $cachedir --prefix [file join $stage out] -Doptimize=$opt(-optimize) {*}$extraopts {*}$steps |
||||||
|
cd $savedpwd |
||||||
|
} |
||||||
|
|
||||||
|
if {$action eq "clean"} { |
||||||
|
log "removing $stage (the clone store at $fossildir is untouched)" |
||||||
|
file delete -force $stage |
||||||
|
exit 0 |
||||||
|
} |
||||||
|
|
||||||
|
if {$action eq "test"} { |
||||||
|
#Delegates to the recipe's test steps. Default step: test-gate (8.6 core |
||||||
|
#testsuite gated on parsed totals vs the tracked expected_test_failures |
||||||
|
#baseline - pending the first census; the 9.0.5 census does not transfer). |
||||||
|
#-j1: independent zig steps must not run timing-sensitive suites in parallel. |
||||||
|
set extraopts {-j1} |
||||||
|
if {[llength $opt(-testargs)]} { |
||||||
|
lappend extraopts -Dtestargs=$opt(-testargs) |
||||||
|
} |
||||||
|
lappend extraopts {*}$opt(-zigargs) |
||||||
|
set teststeps [expr {"-steps" in $explicitopts ? $opt(-steps) : {test-gate}}] |
||||||
|
run_zig_steps $teststeps $extraopts |
||||||
|
log "test steps done ([join $teststeps {, }])" |
||||||
|
exit 0 |
||||||
|
} |
||||||
|
|
||||||
|
#-- action: build ---------------------------------------------------------- |
||||||
|
|
||||||
|
#-- fossil environment ---------------------------------------------------- |
||||||
|
#Checkout registrations go to a stage-local config db, not the user's global one |
||||||
|
#(fossil scratchpad registry pollution guard). Clones are still shared. |
||||||
|
file mkdir $stage |
||||||
|
set env(FOSSIL_HOME) $stage |
||||||
|
file mkdir $fossildir |
||||||
|
|
||||||
|
proc fossil_source {name url branch dir} { |
||||||
|
#ensure <store>/<name>.fossil exists (read-only seed copy, else network clone) and |
||||||
|
#open it at branch in dir |
||||||
|
global fossildir opt |
||||||
|
set repo [file join $fossildir $name.fossil] |
||||||
|
if {![file exists $repo]} { |
||||||
|
set seeded 0 |
||||||
|
if {$opt(-seedfossils) ne ""} { |
||||||
|
set seed [file join $opt(-seedfossils) $name.fossil] |
||||||
|
if {[file exists $seed]} { |
||||||
|
log "seeding $name.fossil into the suite store from $seed (read-only copy)" |
||||||
|
file copy $seed $repo |
||||||
|
#the seed may be stale - freshen OUR copy (the seed is never written) |
||||||
|
run fossil pull -R $repo |
||||||
|
set seeded 1 |
||||||
|
} |
||||||
|
} |
||||||
|
if {!$seeded} { |
||||||
|
log "cloning $url -> $repo" |
||||||
|
run fossil clone $url $repo |
||||||
|
} |
||||||
|
} elseif {$opt(-refresh)} { |
||||||
|
log "refreshing $name.fossil (pull)" |
||||||
|
run fossil pull -R $repo |
||||||
|
} |
||||||
|
if {![file exists [file join $dir _FOSSIL_]] && ![file exists [file join $dir .fslckout]]} { |
||||||
|
file mkdir $dir |
||||||
|
set savedpwd [pwd] |
||||||
|
cd $dir |
||||||
|
#--nested: the stage lives inside the punkshell checkout tree |
||||||
|
run fossil open $repo $branch --nested |
||||||
|
cd $savedpwd |
||||||
|
} elseif {$opt(-refresh)} { |
||||||
|
set savedpwd [pwd] |
||||||
|
cd $dir |
||||||
|
run fossil pull -R $repo |
||||||
|
run fossil update $branch |
||||||
|
cd $savedpwd |
||||||
|
} |
||||||
|
#provenance: materialize manifest.uuid regardless of the upstream repo's |
||||||
|
#versioned 'manifest' setting (suite_tcl90 convention - local checkout-scoped |
||||||
|
#setting 'u' generates manifest.uuid immediately and keeps it current). |
||||||
|
set savedpwd [pwd] |
||||||
|
cd $dir |
||||||
|
run fossil settings manifest u |
||||||
|
cd $savedpwd |
||||||
|
} |
||||||
|
|
||||||
|
#-- stage the recipe ------------------------------------------------------ |
||||||
|
#Per-item sync (not a wholesale delete of the build dir): zig cache dirs live in |
||||||
|
#the build dir and are kept (per-zig-version; windows can hold transient locks on |
||||||
|
#recently-used cache trees). |
||||||
|
log "staging recipe -> $builddir" |
||||||
|
file mkdir $builddir |
||||||
|
foreach item {build86.zig} { |
||||||
|
file delete -force [file join $builddir $item] |
||||||
|
file copy [file join $suiteroot $item] $builddir |
||||||
|
} |
||||||
|
|
||||||
|
#-- sources --------------------------------------------------------------- |
||||||
|
foreach required {tcl tclthread tclvfs} { |
||||||
|
if {![dict exists $sources $required]} { |
||||||
|
fail "sources.config: missing required source record '$required'" |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
dict for {name s} $sources { |
||||||
|
set ref [dict get $s ref] |
||||||
|
if {$name eq "tcl" && $opt(-tclbranch) ne ""} { |
||||||
|
set ref $opt(-tclbranch) ;#per-run CLI override of the declared tcl ref |
||||||
|
} |
||||||
|
switch -- [dict get $s kind] { |
||||||
|
fossil {fossil_source $name [dict get $s url] $ref [file join $stage [dict get $s dir]]} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#zlib/libtommath: 8.6 compiles the tcl tree's own vendored copies in place |
||||||
|
#(tcl86/compat/zlib, tcl86/libtommath) - arrangement differs from 9.0 (see README |
||||||
|
#DERIVATION); nothing extra to stage. |
||||||
|
|
||||||
|
#-- version facts for the final log ---------------------------------------- |
||||||
|
set f [open [file join $stage tcl86 manifest.uuid] r]; set uuid [read $f]; close $f |
||||||
|
set f [open [file join $stage tcl86 generic tcl.h] r]; set tclh [read $f]; close $f |
||||||
|
if {![regexp {#\s*define\s+TCL_PATCH_LEVEL\s+"([^"]+)"} $tclh -> patchlevel]} {fail "TCL_PATCH_LEVEL not found in tcl.h"} |
||||||
|
log "sources: tcl $patchlevel (checkout [string range $uuid 0 11]...)" |
||||||
|
|
||||||
|
#-- build (staged recipe steps) ------------------------------------------- |
||||||
|
run_zig_steps $opt(-steps) $opt(-zigargs) |
||||||
|
|
||||||
|
log "PASS - built $patchlevel (checkout [string range $uuid 0 11]...) -> $stage/out" |
||||||
Loading…
Reference in new issue