Browse Source
Extends the 8.6 buildsuite with the remaining pieces punkshell's Tcl 8 testing
depends on, all built from source with the pinned zig 0.16.0 toolchain only.
Tk 8.6.17 (build_tk86/build_tk86.zig) is a RE-DERIVATION from the staged 8.6
win/makefile.vc + rules.vc, not a port of suite_tcl90's build_tk.zig:
- no generic/tkPkgConfig.c in 8.6 -> no CFG_* defines at all
- rules.vc TCL_MAJOR_VERSION==8 arm -> tk86t.dll + lib/tk8.6 (vs tcl9tk90.dll)
- @TK_WIN_VERSION@ substitutes $(DOTVERSION).0.0, not the tcl-style
<dotversion>.<releaselevel>.<patchlevel> formula
- 8.6 TKOBJS carries no tkIcu/tkImgListFormat/tkImgSVGnano/tkWinGDI/tkWinIco/
tkWinSysTray; XLIBOBJS is a first-class makefile macro here (the 9.0
derivation had to recover those files by hand)
USE_TCL_STUBS + USE_TCLOO_STUBS against libtclstub86.a is the stock rules.vc
arrangement and keeps the dll loadable by both suite shells. tkMain.c is
compiled twice per makefile.vc, the ansi copy forced with -UUNICODE/-U_UNICODE
(verified the pinned zig cc defines neither for x86_64-windows-gnu, so the 8.6
core's ANSI/TCHAR arrangement is matched exactly).
tklib 0.9 and tcllib 2.0 install via their own installer.tcl (batch, packages
only, explicit -pkg-path so the installer's tcl_pkgPath-derived default can
never write off-tree); tcllibc is built by critcl 3.3.1 driving zig cc (tracked
critcl_zig.config, target pinned win32-x86_64-zig - critcl otherwise probes PATH
and falls back to its builtin msvc target). critcl compiles against its own
bundled headers chosen by the driving shell's version, which is why one config
serves both generations.
New evidence tools, run on every build:
tools/tk_smoke.tcl maps a real toplevel with classic + themed widgets,
updates, then destroys it - a load-only check passes
even with no usable display
tools/accel_bench.tcl same payload through sha1's critcl and pure-Tcl
implementations with the digests compared:
4MB -> critcl 5.7ms vs pure-tcl 2736ms = 477x
Test tiers (G-107 policy pattern): test-tcllib/test-tklib on the record tier
inside test-libraries, plus an opt-in test-tk (winDialog/winMsgbox excluded by
default - their message-injection automation blocks on a human under a batch
shell). First censuses on tclsh86ts.exe 8.6.18:
thread 142 run / 0 failed GATE PASS
tklib 796 run / 0 failed record
tcllib 64259 run / 41 failed record (names in the summary artifact)
tclvfs 51 run / 4 failed GATE PASS after baseline extension
The tclvfs baseline grew vfsFtp-1.1..1.3: they sit behind an 'ftp' constraint
needing tcllib's ftp package - absent at the G-099 capture, satisfied now that
the suite installs tcllib - so they run and reach the retired ftp.tcl.tk, the
same external-service class already baselined for vfsUrl-1.2/2.1.
punkshell runtests census (both runs 2026-07-26, identical flags, default
single-process sequential - 8.6 has no tcl::process so -jobs re-convoys):
native Tcl 8.6.17 1003 total / 986 passed / 10 skipped / 7 failed
suite tclsh86ts 1003 total / 987 passed / 10 skipped / 6 failed
runtests_parity.tcl finds exactly ONE difference: punkcheck
concurrency_two_writers_no_corruption failed in the BASELINE run and passed on
the suite runtime - a full-suite-load flake (6/6 twice in isolation on both
runtimes). Zero suite-runtime-only failures. Tk-dependent suites ran unskipped
(repl consolebackends 3/3, including the tkconsole backend on the suite Tk).
Two defects fixed in passing:
- scrubTclEnv never cleared TCL<major>_<minor>_TM_PATH, so suite shells
silently preferred machine/repo tm modules over what the suite had just
installed (a repo-built sha1-2.0.4.tm shadowed tcllib's 2.0.5, md5 2.0.8
shadowed 2.0.9) - any census through such a shell measures the machine. The
scrub list now covers TCL8_0..8_7 + TCL9_0/9_1 in all three sites (per-step,
suite.tcl process-level, bootstrap nested build). suite_tcl90 has the same
exposure via TCL9_0_TM_PATH and is deliberately untouched here (out of this
goal's scope) - pointers recorded in G-108 and G-116.
- build.zig.zon's .fingerprint was hand-authored, so 'zig build' from the
tracked suite dir died with 'invalid fingerprint' - the no-tclsh bootstrap
flow could never have run. Corrected to zig's computed value (its low half
is a checksum of the package name); 'zig build stage' now verified.
Goal flipped to achieved 2026-07-26 and archived; reference sweep updated G-005,
G-101, G-105 and ARCHITECTURE.md, and the archive-time xref pair G-101 <-> G-116
(whose only bridges were the archived G-100/G-103) gained a direct Related
pointer. No project-version bump - arm's-length build tooling, not shipped shell
behaviour.
Assisted-by: harness=claude; primary-model=claude-opus-5[1m]; api-location=anthropic.com
master
22 changed files with 1184 additions and 135 deletions
@ -1,57 +0,0 @@
|
||||
# G-100 suite_tcl86 dependency set: Tk 8.6 + tklib, tcllib with critcl accelerators, punkshell runtests on the 8.6 runtime |
||||
|
||||
Status: proposed |
||||
Scope: src/buildsuites/suite_tcl86/ (recipe extensions, driver steps); src/buildsuites/_build/ (tk/tklib/tcllib/critcl sources and outputs); bin/tools/ (pinned zig as consumed); src/tests/ (punkshell suites exercised against the suite-built 8.6 runtime) |
||||
Goal: suite_tcl86 builds/installs the remaining runtime pieces punkshell's Tcl 8 testing depends on - Tk from fossil core-8-6-branch loadable by the suite's 8.6 windows runtime together with a matching tklib (installer.tcl where it does more than a straight copy), and tcllib installed via its documented installer machinery WITH its critcl-built C accelerators (tcllibc; critcl driving zig cc, bootstrapped by the suite-built tclsh86 - no MS toolchain) - and punkshell's own runtests runs against the suite-built 8.6 runtime with Tk-dependent suites unskipped. |
||||
Acceptance: from the pinned zig and fetched sources the suite produces a Tk 8.6 the suite tclsh loads (package require Tk with a create/destroy-window verification recorded here) and a matching tklib whose packages resolve (a representative require recorded); a tcllib install via its installer whose accelerators load (package require tcllibc) with the accelerated-vs-pure comparison recorded; punkshell runtests runs against the suite 8.6 runtime and its census is recorded here against a same-day native/kit 8.6 baseline run (same include set), with every difference dispositioned - Tk-dependent suites run unskipped, and any 8.6-runtime-only failures are root-caused or baselined with reasons. |
||||
|
||||
## Context |
||||
|
||||
Mirror of G-098 (suite_tcl90 dependency set, achieved 2026-07-20) for the 8.6 arc. |
||||
Depends on G-099 (suite_tcl86 core buildsuite) - ACHIEVED 2026-07-26 (see |
||||
goals/archive/G-099-suite-tcl86-buildsuite.md); the 8.6 runtime (tclsh86ts/ |
||||
tclsh86t + tcl86t.dll + installed lib tree), thread 2.8.13, tclvfs 1.4.2 and |
||||
the core/thread/tclvfs test-gate this goal extends now exist, so the dependency |
||||
is met and G-100 is unblocked. |
||||
|
||||
8.6-specific expectations (verify at activation): |
||||
|
||||
- Tk core-8-6-branch pairs with the 8.6 runtime; the 9.0 build_tk zig module was |
||||
derived from tk9 makefile.vc object lists - the 8.6 lists/xlib arrangement differ, |
||||
so expect a re-derivation rather than reuse. |
||||
- tcllib trunk supports 8.5+; the same vendored critcl mechanism applies, with |
||||
critcl driven by the suite tclsh86. tcllibc built per-generation (the punk9wintk903 |
||||
vfs precedent carries tcl8/tcl9 tcllibc side by side under lib_tcl8/lib_tcl9). |
||||
- runtests under 8.6: no tcl::process, so -jobs child spawning falls back to |
||||
blocking execs which CONVOY on windows (documented) - run -singleproc 1 or accept |
||||
serialized child walls for the census run; record which mode produced the census. |
||||
- Census baseline: compare against the punk86-class kit runtime results on the same |
||||
day/include-set (forward-slash path conventions on 8.6 kits noted in project |
||||
memory) rather than against the 9.x census. |
||||
- The kit-child 'src' package_mode launch added to runtests for punk kits (G-098 |
||||
increment 7) applies to 8.6 punk kits too - a plain suite tclsh86 host takes the |
||||
native path. |
||||
|
||||
SEQUENCING: as for G-099 - proposed now, activation recommended after suite_tcl90's |
||||
G-096 (achieved 2026-07-20) remainder closed and punk905_beta trial concludes. |
||||
|
||||
## Notes |
||||
|
||||
- G-116 relationship (recorded 2026-07-24 after overlap review): G-116's zig-built |
||||
crypto-backend + static tcltls pattern (suite_tcl90) is the reference if the 8.6 |
||||
dependency set later grows a tls battery - the bi-family payload contract it |
||||
extends is generation-shaped, not 9-only. |
||||
- G-005 relationship: same zig toolchain-policy lineage as G-099's note - G-005 |
||||
owns the make.tcl-integrated vendored-extension build direction; the suites are |
||||
its arm's-length proving ground. |
||||
- G-099 (achieved, see goals/archive/G-099-suite-tcl86-buildsuite.md) delivered |
||||
the patterns this goal extends: the build86.zig recipe + build_tclthread86/ |
||||
build_tclvfs86 helpers (TEA-shape companion builds against the 8.6 stub lib), |
||||
the whole-tree library install + tm-module derivation, and the suite_tcl90 |
||||
G-107 (achieved - goals/archive/G-107-buildsuite-library-tests.md) policy-tier |
||||
test-gate (test_gate.tcl) - a Tk/tklib/tcllib gate follows the same shape. Two 8.6-specific traps recorded there carry forward: the |
||||
load-bearing MP_FIXED_CUTOFFS define and TCL_BROKEN_MAINARGS+console-subsystem |
||||
entry handling (build86.zig comments + README DERIVATION). Also inherited from |
||||
G-099 Notes: the G-106 powershell console-mode disableraw-via-server path is |
||||
only tcl9-verified - now that a twapi-less 8.6 runtime exists, run the G-106 |
||||
recipe against it (goals/archive/G-106-powershell-consolemode-fallback.md). |
||||
@ -0,0 +1,210 @@
|
||||
# G-100 suite_tcl86 dependency set: Tk 8.6 + tklib, tcllib with critcl accelerators, punkshell runtests on the 8.6 runtime |
||||
|
||||
Status: achieved 2026-07-26 |
||||
Scope: src/buildsuites/suite_tcl86/ (recipe extensions, driver steps); src/buildsuites/_build/ (tk/tklib/tcllib/critcl sources and outputs); bin/tools/ (pinned zig as consumed); src/tests/ (punkshell suites exercised against the suite-built 8.6 runtime) |
||||
Goal: suite_tcl86 builds/installs the remaining runtime pieces punkshell's Tcl 8 testing depends on - Tk from fossil core-8-6-branch loadable by the suite's 8.6 windows runtime together with a matching tklib (installer.tcl where it does more than a straight copy), and tcllib installed via its documented installer machinery WITH its critcl-built C accelerators (tcllibc; critcl driving zig cc, bootstrapped by the suite-built tclsh86 - no MS toolchain) - and punkshell's own runtests runs against the suite-built 8.6 runtime with Tk-dependent suites unskipped. |
||||
Acceptance: from the pinned zig and fetched sources the suite produces a Tk 8.6 the suite tclsh loads (package require Tk with a create/destroy-window verification recorded here) and a matching tklib whose packages resolve (a representative require recorded); a tcllib install via its installer whose accelerators load (package require tcllibc) with the accelerated-vs-pure comparison recorded; punkshell runtests runs against the suite 8.6 runtime and its census is recorded here against a same-day native/kit 8.6 baseline run (same include set), with every difference dispositioned - Tk-dependent suites run unskipped, and any 8.6-runtime-only failures are root-caused or baselined with reasons. |
||||
|
||||
## Context |
||||
|
||||
Mirror of G-098 (suite_tcl90 dependency set, achieved 2026-07-20) for the 8.6 arc. |
||||
Depends on G-099 (suite_tcl86 core buildsuite) - ACHIEVED 2026-07-26 (see |
||||
goals/archive/G-099-suite-tcl86-buildsuite.md); the 8.6 runtime (tclsh86ts/ |
||||
tclsh86t + tcl86t.dll + installed lib tree), thread 2.8.13, tclvfs 1.4.2 and |
||||
the core/thread/tclvfs test-gate this goal extends now exist, so the dependency |
||||
is met and G-100 is unblocked. |
||||
|
||||
8.6-specific expectations (verify at activation): |
||||
|
||||
- Tk core-8-6-branch pairs with the 8.6 runtime; the 9.0 build_tk zig module was |
||||
derived from tk9 makefile.vc object lists - the 8.6 lists/xlib arrangement differ, |
||||
so expect a re-derivation rather than reuse. |
||||
- tcllib trunk supports 8.5+; the same vendored critcl mechanism applies, with |
||||
critcl driven by the suite tclsh86. tcllibc built per-generation (the punk9wintk903 |
||||
vfs precedent carries tcl8/tcl9 tcllibc side by side under lib_tcl8/lib_tcl9). |
||||
- runtests under 8.6: no tcl::process, so -jobs child spawning falls back to |
||||
blocking execs which CONVOY on windows (documented) - run -singleproc 1 or accept |
||||
serialized child walls for the census run; record which mode produced the census. |
||||
- Census baseline: compare against the punk86-class kit runtime results on the same |
||||
day/include-set (forward-slash path conventions on 8.6 kits noted in project |
||||
memory) rather than against the 9.x census. |
||||
- The kit-child 'src' package_mode launch added to runtests for punk kits (G-098 |
||||
increment 7) applies to 8.6 punk kits too - a plain suite tclsh86 host takes the |
||||
native path. |
||||
|
||||
SEQUENCING: as for G-099 - proposed now, activation recommended after suite_tcl90's |
||||
G-096 (achieved 2026-07-20) remainder closed and punk905_beta trial concludes. |
||||
|
||||
## Progress |
||||
|
||||
### 2026-07-26 activation + increment 1 (dependency set built, census taken) |
||||
|
||||
- ACTIVATED by the user. Sources wired into both flows: `sources.config` gains |
||||
tk (`core-8-6-branch` -> dir `tk86`), tklib/tcllib (trunk) and critcl (git |
||||
3.3.1); `build.zig.zon` gains the matching pins - tk freshly `zig fetch`ed |
||||
(checkin 9986fdc267, 2025-03-17 = Tk 8.6.17), tklib/tcllib/critcl re-fetched |
||||
and verified BYTE-IDENTICAL to suite_tcl90's pins (generation-neutral |
||||
upstreams; what differs per suite is the shell running the installers and the |
||||
critcl target). suite.tcl gains git-source support + the new staging items; |
||||
the bootstrap driver's `source_dirs`/`recipe_items` match. |
||||
- TK 8.6 RE-DERIVED (`build_tk86/build_tk86.zig`) from the staged 8.6 |
||||
`win/makefile.vc` + `rules.vc`, not ported from the 9.0 module - the goal |
||||
Context's expectation held. Full derivation record in |
||||
`src/buildsuites/suite_tcl86/README.md`; the load-bearing differences: |
||||
no `tkPkgConfig.c` (so NO `CFG_*` defines at all), the |
||||
TCL_MAJOR_VERSION==8 naming arm (`tk86t.dll`, `lib/tk8.6`), the |
||||
`@TK_WIN_VERSION@` = `$(DOTVERSION).0.0` manifest substitution (not the |
||||
tcl-style releaselevel formula), and an 8.6 object inventory without |
||||
tkIcu/tkImgListFormat/tkImgSVGnano/tkWinGDI/tkWinIco/tkWinSysTray. Products: |
||||
`bin/tk86t.dll` + `lib/tk86t.lib` + the `lib/tk8.6` script library + |
||||
makefile-shaped `pkgIndex.tcl`. |
||||
- TK ACCEPTANCE EVIDENCE (repeatable - `tools/tk_smoke.tcl` runs in the `smoke` |
||||
step on every build, and a load-only check would pass with no usable display): |
||||
`tk_smoke OK: Tk 8.6.17 (Ttk 8.6.17) windowingsystem win32 screen 3840x2160 |
||||
depth 32 widgets Label/TButton/Toplevel create+map+destroy clean`. Both shells |
||||
load it: `pkg_smoke OK: Thread:2.8.13 vfs:1.4.2 registry:1.3.5 dde:1.4.6 |
||||
Tk:8.6.17` (static AND dynamic). |
||||
- TKLIB via its OWN installer (batch, packages-only, explicit `-pkg-path` so the |
||||
installer's tcl_pkgPath-derived default can never place files off-tree) -> |
||||
`lib/tklib0.9`. Representative require recorded: `pkg_smoke OK: tooltip:2.0.4` |
||||
- a Tk-DEPENDENT package resolving through the installer-generated aggregate |
||||
pkgIndex. |
||||
- TCLLIB 2.0 installed the same way (`md5:2.0.9 sha1:2.0.5 cmdline:1.5.3`), and |
||||
TCLLIBC built by critcl 3.3.1 driving `zig cc` under the suite-built 8.6 shell |
||||
(tracked `critcl_zig.config`, target pinned `win32-x86_64-zig` - critcl |
||||
otherwise probes PATH and falls back to its builtin msvc target). Accelerator |
||||
evidence, both on every build: `pkg_smoke OK: tcllibc:2.0 md5-critcl-accel:1` |
||||
and the new `tools/accel_bench.tcl` - |
||||
`accel_bench OK: sha1 over 4198400 bytes - critcl 5.9ms vs pure-tcl 2661.4ms |
||||
= 452.3x (digests identical, sha1 2.0.5, tcllibc 2.0)`. The bench loads BOTH |
||||
implementations via `::sha1::LoadAccelerator` and switches with |
||||
`::sha1::SwitchTo`, so the comparison is in-process and the digests are |
||||
compared rather than assumed. |
||||
- TEST TIERS extended on the G-107 policy pattern: `test-tcllib` / `test-tklib` |
||||
(record tier, inside `test-libraries`) and the OPT-IN `test-tk` (excluded from |
||||
`test-libraries`; `winDialog.test`/`winMsgbox.test` excluded by default - |
||||
their message-injection automation blocks on a human under a batch shell). |
||||
- HERMETIC-ENVIRONMENT FINDING (see Notes): `TCL<major>_<minor>_TM_PATH` was |
||||
never scrubbed, so the suite shells were silently preferring repo-built tm |
||||
modules over the tcllib the suite had just installed. Fixed in all three |
||||
scrub sites before the census was taken. |
||||
|
||||
#### punkshell runtests census (2026-07-26, both runs same day, same include set) |
||||
|
||||
Mode: DEFAULT single-process sequential (`-singleproc 1`; no `-jobs` - 8.6 has |
||||
no `tcl::process`, so parallel child spawning re-convoys on windows, per the |
||||
goal Context). Identical invocation for both runtimes, full source-tree suite, |
||||
no include filter: `<shell> src/tests/runtests.tcl -report json`. |
||||
|
||||
- BASELINE - native Tcl 8.6.17 (`C:/Users/sleek/AppData/Local/Apps/Tcl86`, |
||||
which carries Tk 8.6.17, Thread 2.8.12, tcllibc 2.0, twapi): 101 files, |
||||
Total 1003 / Passed 986 / Skipped 10 / Failed 7, 657s. Files failed: |
||||
`core/tcl/.../exec.test` (ERROR `invalid command name "tcl::build-info"` - a |
||||
9-era core test under an 8.6 shell), `modules/punk/ns/.../nslist.test` (4), |
||||
`modules/punk/ns/.../nsprimitives.test` (2 - the `:::odd` namespace-lookup |
||||
class), `modules/punkcheck/.../concurrency.test` (1). |
||||
- SUITE RUNTIME - `out/bin/tclsh86ts.exe` (8.6.18, this suite's static shell): |
||||
101 files, Total 1003 / Passed 987 / Skipped 10 / Failed 6, 601s. |
||||
- DIFFERENCE SET (authoritative, `scriptlib/developer/runtests_parity.tcl`): |
||||
exactly ONE - `punkcheck concurrency_two_writers_no_corruption` ERRORed in the |
||||
BASELINE run and PASSED on the suite runtime. Every other per-file status, |
||||
tally, failure identity, skip identity+reason and warning code is identical. |
||||
DISPOSITION: flake under full-suite load, not a runtime difference - the file |
||||
passes 6/6 in isolation on BOTH runtimes, twice each (verified same day). |
||||
ZERO suite-runtime-only failures; nothing needed baselining. |
||||
- TK-DEPENDENT SUITES RAN UNSKIPPED on the suite runtime: |
||||
`modules/punk/repl/testsuites/repl/consolebackends.test` 3/3 PASS (its |
||||
tkconsole backend drives a child repl on the suite-built Tk) and |
||||
`modules/opunk/console/testsuites/console/backends.test` 7 passed / 1 skipped. |
||||
That single skip is `backends_tkconsole_widget_size_and_eof`, whose |
||||
`tkavailable` constraint requires the `PUNK_TEST_TK` OPT-IN env var (not Tk |
||||
availability); it skips identically on the native baseline, and the opt-in's |
||||
own pre-existing quirk is recorded in G-098's increment 6 notes. |
||||
- Runtime-difference note (does not change any result): the suite runtime has no |
||||
twapi, so its runs open with `is_interactive cannot detect console ... without |
||||
twapi` and a `punk::du` slower-disk-operations warning that the native |
||||
baseline (twapi present) does not print. |
||||
|
||||
#### library test tiers - first censuses (2026-07-26, suite tclsh86ts.exe 8.6.18) |
||||
|
||||
Beyond the acceptance text; run because the goal Context asks the G-107 |
||||
policy-tier shape to follow for the new libraries. |
||||
|
||||
- thread (gate): 142 run / 126 passed / 16 skipped / 0 failed - GATE PASS |
||||
(baseline still empty; constraint-driven skips only). |
||||
- tklib (RECORD, new tier): 796 run / 684 passed / 112 skipped / 0 failed. Its |
||||
Tk-dependent suites exercise the suite-built Tk, and nothing failed. |
||||
- tcllib (RECORD, new tier): 64259 run / 61186 passed / 3032 skipped / 41 |
||||
failed - names in `out/testreports/tcllib.summary`. Dominant classes: |
||||
network-reaching suites (picoirc 20, httpd-proxy/cgi 4), installer/path |
||||
assumptions (install-2.1/2.2, find-sf-*/find-4.0, multi/multiop-5.2), plus |
||||
matrix-16.7/16.8, tar-add, uri-4.1, example-*, zipfile-encode-6.4/6.5. A |
||||
record tier is evidence, not a gate criterion - no baseline is tracked and the |
||||
step never fails the build on these. |
||||
- tclvfs (gate): the tcllib install CHANGED this suite's census - vfsFtp-1.1.. |
||||
1.3 sit behind an `ftp` constraint that needs tcllib's ftp package (absent at |
||||
the G-099 capture: 3 constraint skips), so they now RUN and reach the retired |
||||
`ftp://ftp.tcl.tk`, the same external-service class already baselined for |
||||
vfsUrl-1.2/2.1 (skips 8 -> 5 accordingly). `expected_test_failures_tclvfs.txt` |
||||
extended with the three names and the cause; re-run confirms GATE PASS |
||||
(51 run / 42 passed / 5 skipped / 4 failed, all baselined; vfsUrl-1.2 noted as |
||||
a stale entry - which members of the family fail is network-timing dependent, |
||||
so stale notes are expected and never fatal). |
||||
|
||||
Remains for acceptance: nothing - the four acceptance clauses (Tk loadable + |
||||
create/destroy verification, matching tklib with a representative require, |
||||
tcllib installed by its own machinery with loading accelerators and a recorded |
||||
accelerated-vs-pure comparison, and a dispositioned runtests census against a |
||||
same-day 8.6 baseline with Tk suites unskipped) are all recorded above. |
||||
|
||||
## Notes |
||||
|
||||
- Hermetic-environment finding 2026-07-26 (fixed here, exposure recorded for |
||||
suite_tcl90): `scrubTclEnv` cleared only TCLLIBPATH/TCL_LIBRARY/TK_LIBRARY, |
||||
but `tm.tcl` also seeds module roots from `env(TCL<major>_<minor>_TM_PATH)` |
||||
down through every lower minor. This machine points `TCL8_6_TM_PATH` at |
||||
`C:/repo/jn/shellspy/modules` among others, so suite shells preferred a |
||||
repo-built `sha1-2.0.4.tm` / `md5 2.0.8` over the tcllib 2.0.5 / 2.0.9 the |
||||
suite had just installed - a census through such a shell measures the machine. |
||||
Scrub list now covers `TCL8_0..8_7_TM_PATH` + `TCL9_0/9_1_TM_PATH` in the |
||||
per-step scrub (`build_common.zig` `tcl_env_vars`), `suite.tcl`'s |
||||
process-level unset and the bootstrap nested-build scrub. suite_tcl90 has the |
||||
same exposure via `TCL9_0_TM_PATH` and was deliberately left untouched (out of |
||||
this goal's scope) - worth a suite_tcl90-scoped fix. |
||||
- zig 0.16 trap (recorded while pinning): `zig fetch <url>` resolves a BUILD |
||||
ROOT before fetching, so it must be run from a directory containing a |
||||
`build.zig`; from anywhere else it dies with the misleading "no build.zig file |
||||
found, in the current directory or any parent directories". Also in the |
||||
`build.zig.zon` header. |
||||
- Activation freshness 2026-07-26: goals_xref.tcl score G-100 re-run at the |
||||
proposed->active flip (user-directed activation). Top pairs G-105 / G-101 / |
||||
G-116 / G-108 reviewed; the two that were only one-directional get the |
||||
back-pointers below, G-116 was already recorded here, and the remaining hits |
||||
are term noise - no new relationships. |
||||
- Related: G-105 (buildsuite cross-target) - it names this arc as a target- |
||||
dimension consumer; the tk/tklib/tcllib/critcl steps this goal adds must not |
||||
preclude a per-target dimension (no per-target tree copies, per-target out |
||||
prefixes). |
||||
- Related: G-101 (8.6 kit container strategy) - the downstream consumer of this |
||||
dependency set: whatever container it picks carries the Tk/tklib/tcllib/ |
||||
tcllibc payload this goal produces. |
||||
- Related: G-108 (debug buildsuite tier) - sibling suite-arc goal queued behind |
||||
this arc; its -dbg<n>/tcl::test variant pattern is suite_tcl90-scoped today. |
||||
- G-116 relationship (recorded 2026-07-24 after overlap review): G-116's zig-built |
||||
crypto-backend + static tcltls pattern (suite_tcl90) is the reference if the 8.6 |
||||
dependency set later grows a tls battery - the bi-family payload contract it |
||||
extends is generation-shaped, not 9-only. |
||||
- G-005 relationship: same zig toolchain-policy lineage as G-099's note - G-005 |
||||
owns the make.tcl-integrated vendored-extension build direction; the suites are |
||||
its arm's-length proving ground. |
||||
- G-099 (achieved, see goals/archive/G-099-suite-tcl86-buildsuite.md) delivered |
||||
the patterns this goal extends: the build86.zig recipe + build_tclthread86/ |
||||
build_tclvfs86 helpers (TEA-shape companion builds against the 8.6 stub lib), |
||||
the whole-tree library install + tm-module derivation, and the suite_tcl90 |
||||
G-107 (achieved - goals/archive/G-107-buildsuite-library-tests.md) policy-tier |
||||
test-gate (test_gate.tcl) - a Tk/tklib/tcllib gate follows the same shape. Two 8.6-specific traps recorded there carry forward: the |
||||
load-bearing MP_FIXED_CUTOFFS define and TCL_BROKEN_MAINARGS+console-subsystem |
||||
entry handling (build86.zig comments + README DERIVATION). Also inherited from |
||||
G-099 Notes: the G-106 powershell console-mode disableraw-via-server path is |
||||
only tcl9-verified - now that a twapi-less 8.6 runtime exists, run the G-106 |
||||
recipe against it (goals/archive/G-106-powershell-consolemode-fallback.md). |
||||
@ -0,0 +1,260 @@
|
||||
const std = @import("std"); |
||||
const common = @import("../build_common.zig"); |
||||
|
||||
//G-100: Tk 8.6 windows loadable extension (tk86t.dll) from stock core-8-6-branch |
||||
//sources, plus the tk script library installed to lib/tk8.6. |
||||
// |
||||
//DERIVED from the staged tk 8.6 win/makefile.vc + win/rules.vc - a re-derivation, |
||||
//not a port of the 9.0 build_tk.zig (the goal Context predicted this: the object |
||||
//lists and xlib arrangement differ). Differences from the 9.0 module, all |
||||
//makefile-authorised: |
||||
// - object inventory: 8.6 TKOBJS has no tkIcu / tkImgListFormat / tkImgSVGnano / |
||||
// tkPkgConfig, and no tkWinGDI / tkWinIco / tkWinSysTray. XLIBOBJS is the same |
||||
// 5-file emulation set but is a first-class makefile macro here (in 9.0 the |
||||
// xlib files had to be recovered by hand - the name-pattern extraction missed |
||||
// them). |
||||
// - NO tkPkgConfig.c in 8.6 -> no CFG_* configure-era defines at all (the 9.0 |
||||
// module carries a full CFG_{RUNTIME,INSTALL}_* set for it). |
||||
// - dll naming: rules.vc's TCL_MAJOR_VERSION==8 arm gives TKLIBNAME |
||||
// tk86t.dll (SUFX 't' survives while TCL_VERSION <= 86); the 9.0 arm produces |
||||
// the tcl9tk90.dll form. |
||||
// - wish.exe.manifest version: 8.6's makefile substitutes @TK_WIN_VERSION@ with |
||||
// $(DOTVERSION).0.0 = "8.6.0.0" - NOT the tcl-style |
||||
// <dotversion>.<releaselevel>.<patchlevel> formula the 9.0 tree uses. |
||||
// - pkgIndex: the 8.6 install-binaries text provides ONLY 'Tk' (no lowercase |
||||
// 'tk' alias) and guards with 'package vsatisfies [package provide Tcl] 8.6.0'. |
||||
// |
||||
//Kept from the 9.0 module (same reasons): |
||||
// - USE_TCL_STUBS/USE_TCLOO_STUBS + link against the suite's libtclstub86.a: |
||||
// that IS the stock arrangement (rules.vc sets USE_STUBS_DEFS for every |
||||
// project except tcl itself), and it keeps the dll unbound to a particular |
||||
// tcl dll name so both the static and dynamic suite shells can load it. |
||||
// - tkMain.c compiled twice (makefile: tkMain.obj + tkMain2.obj). The ansi copy |
||||
// gets explicit -UUNICODE/-U_UNICODE so a driver-side UNICODE default could |
||||
// never turn it into a duplicate UNICODE compile (G-096 finding; verified |
||||
// 2026-07-26 that the pinned zig cc defines neither for x86_64-windows-gnu, |
||||
// so the guard is belt-and-braces and the stock ANSI/TCHAR arrangement of the |
||||
// 8.6 core is matched exactly). |
||||
// - tkUuid.h generated into the build cache (tkWindow.c #includes it) and |
||||
// consumed via an include-dir overlay added FIRST - source trees are never |
||||
// written (G-102 convention). |
||||
|
||||
//win/makefile.vc TKOBJS, split by the directory each source actually lives in |
||||
//(verified against the staged tree - every name resolved to exactly one dir). |
||||
const generic_names = [_][]const u8{ |
||||
"tkConsole", "tk3d", "tkArgv", "tkAtom", "tkBind", |
||||
"tkBitmap", "tkBusy", "tkButton", "tkCanvArc", "tkCanvBmap", |
||||
"tkCanvImg", "tkCanvLine", "tkCanvPoly", "tkCanvPs", "tkCanvText", |
||||
"tkCanvUtil", "tkCanvWind", "tkCanvas", "tkClipboard", "tkCmds", |
||||
"tkColor", "tkConfig", "tkCursor", "tkEntry", "tkError", |
||||
"tkEvent", "tkFileFilter", "tkFocus", "tkFont", "tkFrame", |
||||
"tkGC", "tkGeometry", "tkGet", "tkGrab", "tkGrid", |
||||
"tkImage", "tkImgBmap", "tkImgGIF", "tkImgPNG", "tkImgPPM", |
||||
"tkImgPhoto", "tkImgPhInstance", "tkImgUtil", "tkListbox", "tkMacWinMenu", |
||||
"tkMenu", "tkMenubutton", "tkMenuDraw", "tkMessage", "tkPanedWindow", |
||||
"tkObj", "tkOldConfig", "tkOption", "tkPack", "tkPlace", |
||||
"tkPointer", "tkRectOval", "tkScale", "tkScrollbar", "tkSelect", |
||||
"tkStyle", "tkText", "tkTextBTree", "tkTextDisp", "tkTextImage", |
||||
"tkTextIndex", "tkTextMark", "tkTextTag", "tkTextWind", "tkTrig", |
||||
"tkUndo", "tkUtil", "tkVisual", "tkStubInit", "tkWindow", |
||||
}; |
||||
const unix_names = [_][]const u8{ "tkUnixMenubu", "tkUnixScale" }; |
||||
const xlib_names = [_][]const u8{ "xcolors", "xdraw", "xgc", "ximage", "xutil" }; |
||||
const win_names = [_][]const u8{ |
||||
"tkWin3d", "tkWin32Dll", "tkWinButton", "tkWinClipboard", "tkWinColor", |
||||
"tkWinConfig", "tkWinCursor", "tkWinDialog", "tkWinDraw", "tkWinEmbed", |
||||
"tkWinFont", "tkWinImage", "tkWinInit", "tkWinKey", "tkWinMenu", |
||||
"tkWinPixmap", "tkWinPointer", "tkWinRegion", "tkWinScrlbr", "tkWinSend", |
||||
"tkWinSendCom", "tkWinWindow", "tkWinWm", "tkWinX", "stubs", |
||||
"ttkWinMonitor", "ttkWinTheme", "ttkWinXPTheme", |
||||
}; |
||||
const ttk_names = [_][]const u8{ |
||||
"ttkBlink", "ttkButton", "ttkCache", "ttkClamTheme", "ttkClassicTheme", |
||||
"ttkDefaultTheme", "ttkElements", "ttkEntry", "ttkFrame", "ttkImage", |
||||
"ttkInit", "ttkLabel", "ttkLayout", "ttkManager", "ttkNotebook", |
||||
"ttkPanedwindow", "ttkProgress", "ttkScale", "ttkScrollbar", "ttkScroll", |
||||
"ttkSeparator", "ttkSquare", "ttkState", "ttkTagSet", "ttkTheme", |
||||
"ttkTrace", "ttkTrack", "ttkTreeview", "ttkWidget", "ttkStubInit", |
||||
}; |
||||
|
||||
pub const TkBuild = struct { |
||||
lib: *std.Build.Step.Compile, |
||||
pkgidx: std.Build.LazyPath, |
||||
patchlevel: []const u8, //e.g "8.6.17" (tk.h TK_PATCH_LEVEL) |
||||
libdir: []const u8, //install dir name, e.g "tk8.6" |
||||
dll_file: []const u8, //e.g "tk86t.dll" |
||||
}; |
||||
|
||||
pub fn build_tk86(comptime tcldir: []const u8, comptime subdir: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, stublib: *std.Build.Step.Compile) !TkBuild { |
||||
//-- version facts from the staged tree (never hardcoded) |
||||
const tkh_content = common.readSourceFile(b, subdir ++ "/generic/tk.h"); |
||||
const tk_h_version = common.parseDefineString(tkh_content, "TK_VERSION") orelse @panic("TK_VERSION not found in tk.h"); |
||||
const tk_h_patchlevel = common.parseDefineString(tkh_content, "TK_PATCH_LEVEL") orelse @panic("TK_PATCH_LEVEL not found in tk.h"); |
||||
if (!std.mem.eql(u8, tk_h_version, "8.6")) { |
||||
std.debug.panic("staged tk tree is {s} but this recipe expresses Tk 8.6 (sources.config tk ref / dir mismatch?)", .{tk_h_version}); |
||||
} |
||||
const tk_nodot = "86"; |
||||
const dll_name = "tk" ++ tk_nodot ++ "t"; //rules.vc TKLIBNAME, TCL_MAJOR_VERSION==8 arm |
||||
const dll_file = dll_name ++ ".dll"; |
||||
const script_dir_rel = "lib/tk8.6"; //rules.vc SCRIPT_INSTALL_DIR for DOING_TK |
||||
|
||||
const lib = b.addLibrary(.{ |
||||
.linkage = .dynamic, |
||||
.name = dll_name, |
||||
.root_module = b.createModule(.{ |
||||
.target = target, |
||||
.optimize = optimize, |
||||
}), |
||||
}); |
||||
|
||||
//-- flag classes (rules.vc pkgcflags for PROJECT=tk: cflags + INCLUDES + |
||||
//TCL_DEFINES + PRJ_DEFINES + OPTDEFINES + USE_STUBS_DEFS + /DBUILD_tk) |
||||
var flags = std.array_list.Managed([]const u8).init(b.allocator); |
||||
defer flags.deinit(); |
||||
try flags.appendSlice(&.{ |
||||
"-Wall", |
||||
"-O3", |
||||
"-fomit-frame-pointer", |
||||
"-finput-charset=UTF-8", |
||||
//the tcl 8.6 recipe's finding, kept here: clang UBSan traps must stay |
||||
//fully off on windows |
||||
"-fno-sanitize=undefined", |
||||
"-fno-sanitize-trap=undefined", |
||||
//project defines: makefile.vc PRJ_DEFINES (/DBUILD_ttk + CONFIG_DEFS; |
||||
//inline=__inline and the _CRT_*_NO_DEPRECATE pair are MSVC-isms) |
||||
"-DBUILD_tk", |
||||
"-DBUILD_ttk", |
||||
"-DSTDC_HEADERS=1", |
||||
"-DHAVE_SYS_TYPES_H=1", |
||||
"-DHAVE_SYS_STAT_H=1", |
||||
"-DHAVE_STDLIB_H=1", |
||||
"-DHAVE_STRING_H=1", |
||||
"-DHAVE_MEMORY_H=1", |
||||
"-DHAVE_STRINGS_H=1", |
||||
"-DHAVE_UXTHEME_H=1", //makefile default (OPTS=noxp turns it off) |
||||
//rules.vc USE_STUBS_DEFS for a non-tcl project |
||||
"-DUSE_TCL_STUBS=1", |
||||
"-DUSE_TCLOO_STUBS=1", |
||||
//OPTDEFINES equivalents, matching the flag set the 8.6 core was built with |
||||
"-DTCL_THREADS=1", |
||||
"-DNDEBUG=1", |
||||
"-DTCL_CFG_OPTIMIZED=1", |
||||
"-DTCL_CFG_DO64BIT=1", |
||||
"-DHAVE_NO_SEH=1", //gcc-class: no __try/__except |
||||
}); |
||||
|
||||
var sources = std.array_list.Managed([]const u8).init(b.allocator); |
||||
inline for (generic_names) |n| try sources.append(subdir ++ "/generic/" ++ n ++ ".c"); |
||||
inline for (unix_names) |n| try sources.append(subdir ++ "/unix/" ++ n ++ ".c"); |
||||
inline for (xlib_names) |n| try sources.append(subdir ++ "/xlib/" ++ n ++ ".c"); |
||||
inline for (win_names) |n| try sources.append(subdir ++ "/win/" ++ n ++ ".c"); |
||||
inline for (ttk_names) |n| try sources.append(subdir ++ "/generic/ttk/" ++ n ++ ".c"); |
||||
|
||||
//tkUuid.h overlay: makefile.vc concatenates win/tkUuid.h.in + the checkout's |
||||
//manifest.uuid; wrapfiletofile reproduces exactly that. |
||||
const wrapfilecmd = b.addExecutable(.{ |
||||
.name = "wrapfiletofile", |
||||
.root_module = b.createModule(.{ |
||||
.root_source_file = b.path("tools/wrapfiletofile.zig"), |
||||
.target = b.graph.host, |
||||
}), |
||||
}); |
||||
const uuidcmd_step = b.addRunArtifact(wrapfilecmd); |
||||
uuidcmd_step.addArgs(&.{ |
||||
"-prefix", |
||||
"#define TK_VERSION_UUID \\", |
||||
"-prefixnl", |
||||
"1", |
||||
"-input", |
||||
}); |
||||
uuidcmd_step.addFileArg(b.path(subdir ++ "/manifest.uuid")); |
||||
uuidcmd_step.addArg("-output"); |
||||
const tkuuid_file = uuidcmd_step.addOutputFileArg("tkUuid.h"); |
||||
lib.root_module.addIncludePath(tkuuid_file.dirname()); //overlay first |
||||
|
||||
lib.root_module.addIncludePath(b.path(subdir ++ "/generic")); |
||||
lib.root_module.addIncludePath(b.path(subdir ++ "/generic/ttk")); |
||||
lib.root_module.addIncludePath(b.path(subdir ++ "/win")); |
||||
lib.root_module.addIncludePath(b.path(subdir ++ "/xlib")); //PRJ_INCLUDES |
||||
lib.root_module.addIncludePath(b.path(subdir ++ "/bitmaps")); //PRJ_INCLUDES |
||||
lib.root_module.addIncludePath(b.path(tcldir ++ "/generic")); |
||||
lib.root_module.addIncludePath(b.path(tcldir ++ "/win")); |
||||
|
||||
lib.root_module.addCSourceFiles(.{ |
||||
.files = sources.items, |
||||
.flags = flags.items, |
||||
}); |
||||
|
||||
//tkMain.c twice - ansi (forced) + UNICODE 'tkMain2' (makefile.vc parity) |
||||
var mainansi_flags = std.array_list.Managed([]const u8).init(b.allocator); |
||||
defer mainansi_flags.deinit(); |
||||
try mainansi_flags.appendSlice(flags.items); |
||||
try mainansi_flags.appendSlice(&.{ "-UUNICODE", "-U_UNICODE" }); |
||||
lib.root_module.addCSourceFile(.{ |
||||
.file = b.path(subdir ++ "/generic/tkMain.c"), |
||||
.flags = mainansi_flags.items, |
||||
}); |
||||
var mainw_flags = std.array_list.Managed([]const u8).init(b.allocator); |
||||
defer mainw_flags.deinit(); |
||||
try mainw_flags.appendSlice(flags.items); |
||||
try mainw_flags.appendSlice(&.{ "-DUNICODE", "-D_UNICODE" }); |
||||
lib.root_module.addCSourceFile(.{ |
||||
.file = b.path(subdir ++ "/generic/tkMain.c"), |
||||
.flags = mainw_flags.items, |
||||
}); |
||||
|
||||
//wish.exe.manifest overlay: win/rc/tk.rc embeds it as RT_MANIFEST (that is |
||||
//what enables comctl32 v6 themed scrollbars in the DLL), and RT_MANIFEST |
||||
//file references resolve through the rc include paths. 8.6's makefile |
||||
//substitutes @TK_WIN_VERSION@ with $(DOTVERSION).0.0. |
||||
const tk_win_version = b.fmt("{s}.0.0", .{tk_h_version}); |
||||
const wish_manifest_content = common.replaceAll(b, common.replaceAll(b, common.readSourceFile(b, subdir ++ "/win/wish.exe.manifest.in"), "@TK_WIN_VERSION@", tk_win_version), "@MACHINE@", "AMD64"); |
||||
const wf_tkrc = b.addWriteFiles(); |
||||
_ = wf_tkrc.add("wish.exe.manifest", wish_manifest_content); |
||||
lib.root_module.addWin32ResourceFile(.{ |
||||
.file = b.path(subdir ++ "/win/rc/tk.rc"), |
||||
//TCL_THREADS drives the rc's OriginalFilename suffix (tk86t.dll) |
||||
.flags = &.{"-DTCL_THREADS=1"}, |
||||
.include_paths = &.{ |
||||
wf_tkrc.getDirectory(), |
||||
b.path(subdir ++ "/win"), |
||||
b.path(subdir ++ "/win/rc"), |
||||
b.path(subdir ++ "/generic"), |
||||
b.path(tcldir ++ "/generic"), |
||||
}, |
||||
}); |
||||
|
||||
lib.root_module.linkLibrary(stublib); |
||||
lib.root_module.link_libc = true; |
||||
//rules.vc winlibs + makefile.vc PRJ_LIBS, plus the OLE/dialog/IME imports the |
||||
//win sources pull in (tkWinSendCom, tkWinDialog, tkWinX) |
||||
inline for (.{ "netapi32", "gdi32", "user32", "userenv", "winspool", "shell32", "ole32", "oleaut32", "uuid", "comctl32", "comdlg32", "imm32", "uxtheme", "advapi32", "kernel32" }) |l| { |
||||
lib.root_module.linkSystemLibrary(l, .{}); |
||||
} |
||||
|
||||
b.installArtifact(lib); //bin/tk86t.dll (+ tk86t.lib import lib -> lib/) |
||||
|
||||
//tk script library -> <prefix>/lib/tk8.6 (whole-tree copy: stock splits the |
||||
//demos out to a separate dir, this keeps them inside - same simplification |
||||
//the tcl-side library install makes) |
||||
const install_tk_library = b.addInstallDirectory(.{ |
||||
.source_dir = b.path(subdir ++ "/library"), |
||||
.install_dir = .prefix, |
||||
.install_subdir = script_dir_rel, |
||||
}); |
||||
b.getInstallStep().dependOn(&install_tk_library.step); |
||||
|
||||
//pkgIndex.tcl per makefile.vc install-binaries (windows arm of its two-branch |
||||
//text - the unix DISPLAY branch cannot apply to a windows-only suite; |
||||
//'file normalize' added as in the 9.0 recipe so the load path is cwd-proof). |
||||
const wf_pkgidx = b.addWriteFiles(); |
||||
const pkgidx = wf_pkgidx.add("pkgIndex.tcl", b.fmt( |
||||
\\if {{![package vsatisfies [package provide Tcl] 8.6.0]}} return |
||||
\\package ifneeded Tk {s} [list load [file normalize [file join $dir .. .. bin {s}]]] |
||||
\\ |
||||
, .{ tk_h_patchlevel, dll_file })); |
||||
const pkgidx_install = b.addInstallFileWithDir(pkgidx, .prefix, script_dir_rel ++ "/pkgIndex.tcl"); |
||||
b.getInstallStep().dependOn(&pkgidx_install.step); |
||||
|
||||
return .{ .lib = lib, .pkgidx = pkgidx, .patchlevel = tk_h_patchlevel, .libdir = "tk8.6", .dll_file = dll_file }; |
||||
} |
||||
@ -0,0 +1,36 @@
|
||||
# suite_tcl86 critcl configuration: zig cc as the C toolchain (G-100). |
||||
# Forked from suite_tcl90/critcl_zig.config - generation-neutral content: critcl |
||||
# compiles against whichever tcl headers/stubs the DRIVING shell reports, so the |
||||
# 8.6 suite needs no flag differences here. '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). |
||||
# |
||||
# 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 - suite_tcl90 G-102 finding). |
||||
|
||||
platform win32-x86_64 |
||||
|
||||
win32-x86_64-zig platform win32-x86_64 |
||||
win32-x86_64-zig compile zig cc -target x86_64-windows-gnu -c -fPIC |
||||
win32-x86_64-zig version zig version |
||||
win32-x86_64-zig link zig cc -target x86_64-windows-gnu -shared |
||||
win32-x86_64-zig include -I |
||||
win32-x86_64-zig libinclude -L |
||||
win32-x86_64-zig object .o |
||||
win32-x86_64-zig output -o [list $outfile] |
||||
win32-x86_64-zig optimize -O2 |
||||
win32-x86_64-zig noassert -DNDEBUG |
||||
win32-x86_64-zig tclstubs -DUSE_TCL_STUBS |
||||
win32-x86_64-zig tkstubs -DUSE_TK_STUBS |
||||
win32-x86_64-zig debug_symbols -g |
||||
win32-x86_64-zig strip -Wl,-s |
||||
win32-x86_64-zig link_debug |
||||
win32-x86_64-zig link_release |
||||
win32-x86_64-zig embed_manifest |
||||
win32-x86_64-zig ldoutput |
||||
win32-x86_64-zig link_preload |
||||
win32-x86_64-zig sharedlibext .dll |
||||
@ -0,0 +1,50 @@
|
||||
#accel_bench.tcl (G-100): tcllibc accelerator evidence under a suite-built shell. |
||||
#Hashes the same payload twice through tcllib's sha1 - once on the critcl |
||||
#accelerator (tcllibc), once on the pure-Tcl implementation - asserts the two |
||||
#digests match and prints the timings plus the speedup ratio. This is the |
||||
#punkcheck-relevant comparison (punkcheck hashing is the workload that made the |
||||
#accelerators worth building). |
||||
# |
||||
#Both implementations are made available with ::sha1::LoadAccelerator (the |
||||
#package itself stops loading at the FIRST working accelerator, so 'tcl' is |
||||
#normally not registered when critcl won) and selected with ::sha1::SwitchTo. |
||||
# |
||||
#args: ?-mb <payload megabytes>? (default 4) |
||||
|
||||
proc fail {msg} {puts stderr "accel_bench FAIL: $msg"; flush stderr; exit 1} |
||||
|
||||
set mb 4 |
||||
for {set i 0} {$i < [llength $argv]} {incr i} { |
||||
switch -- [lindex $argv $i] { |
||||
-mb {incr i; set mb [lindex $argv $i]} |
||||
default {fail "unknown argument: [lindex $argv $i]"} |
||||
} |
||||
} |
||||
|
||||
if {[catch {package require sha1} sha1ver]} {fail "package require sha1: $sha1ver"} |
||||
if {[catch {package require tcllibc} tcllibcver]} {fail "package require tcllibc: $tcllibcver"} |
||||
|
||||
if {![::sha1::LoadAccelerator critcl]} {fail "sha1 critcl accelerator not available (tcllibc $tcllibcver loaded but sha1c missing?)"} |
||||
if {![::sha1::LoadAccelerator tcl]} {fail "sha1 pure-tcl implementation not available"} |
||||
|
||||
#payload: incompressible-ish repeated block, built once, hashed by both |
||||
set block [string repeat "punkshell-suite_tcl86-accel-bench-0123456789abcdef" 1024] |
||||
set data "" |
||||
set target [expr {$mb * 1024 * 1024}] |
||||
while {[string length $data] < $target} {append data $block} |
||||
set bytes [string length $data] |
||||
|
||||
::sha1::SwitchTo critcl |
||||
set t_critcl [lindex [time {set d_critcl [::sha1::sha1 -hex -- $data]}] 0] |
||||
::sha1::SwitchTo tcl |
||||
set t_tcl [lindex [time {set d_tcl [::sha1::sha1 -hex -- $data]}] 0] |
||||
|
||||
if {$d_critcl ne $d_tcl} {fail "digest mismatch: critcl $d_critcl vs pure-tcl $d_tcl"} |
||||
if {$t_critcl <= 0} {set t_critcl 1} |
||||
|
||||
set speedup [format %.1f [expr {double($t_tcl) / double($t_critcl)}]] |
||||
set ms_critcl [format %.1f [expr {$t_critcl / 1000.0}]] |
||||
set ms_tcl [format %.1f [expr {$t_tcl / 1000.0}]] |
||||
puts "accel_bench OK: sha1 over $bytes bytes - critcl ${ms_critcl}ms vs pure-tcl ${ms_tcl}ms = ${speedup}x (digests identical, sha1 $sha1ver, tcllibc $tcllibcver)" |
||||
flush stdout |
||||
exit 0 |
||||
@ -0,0 +1,64 @@
|
||||
#tk_smoke.tcl (G-100): Tk window-station smoke under a suite-built shell. |
||||
#Goes beyond 'package require Tk' (a load-only check passes even when no usable |
||||
#display exists): it maps a real toplevel with a widget in it, forces a display |
||||
#update, then destroys it - the create/destroy-window verification the G-100 |
||||
#acceptance asks for, run on every build rather than once by hand. |
||||
# |
||||
#args: ?-expect <tk patchlevel>? |
||||
#Exits 1 with a 'tk_smoke FAIL:' line on any failure; prints one evidence line |
||||
#on success (version, screen geometry/depth, windowingsystem, widget classes). |
||||
|
||||
proc fail {msg} {puts stderr "tk_smoke FAIL: $msg"; flush stderr; exit 1} |
||||
|
||||
set expect {} |
||||
for {set i 0} {$i < [llength $argv]} {incr i} { |
||||
switch -- [lindex $argv $i] { |
||||
-expect {incr i; set expect [lindex $argv $i]} |
||||
default {fail "unknown argument: [lindex $argv $i]"} |
||||
} |
||||
} |
||||
|
||||
if {[catch {package require Tk} tkver]} {fail "package require Tk: $tkver"} |
||||
if {$expect ne "" && $tkver ne $expect} {fail "Tk version $tkver, expected $expect"} |
||||
if {[catch {package require Ttk} ttkver]} {set ttkver "-"} |
||||
|
||||
#the root window itself: geometry facts prove a real window station/display |
||||
if {[catch { |
||||
wm title . "tk_smoke" |
||||
wm geometry . 320x120+80+80 |
||||
set screen "[winfo screenwidth .]x[winfo screenheight .] depth [winfo screendepth .]" |
||||
set wsys [tk windowingsystem] |
||||
} err]} {fail "root window setup: $err"} |
||||
|
||||
#create: a classic widget, a themed widget and a child toplevel |
||||
if {[catch { |
||||
label .l -text "tk_smoke" |
||||
pack .l |
||||
ttk::button .b -text "ok" |
||||
pack .b |
||||
toplevel .t |
||||
wm title .t "tk_smoke child" |
||||
wm geometry .t 200x80+420+80 |
||||
label .t.l -text "child" |
||||
pack .t.l |
||||
update |
||||
} err]} {fail "widget create/map: $err"} |
||||
|
||||
foreach {label w} {root . classic .l themed .b child .t} { |
||||
if {![winfo ismapped $w]} {fail "window not mapped after update: $label ($w)"} |
||||
} |
||||
set classes [list [winfo class .l] [winfo class .b] [winfo class .t]] |
||||
|
||||
#destroy: the child toplevel first, then every root child - a clean teardown |
||||
if {[catch { |
||||
destroy .t |
||||
update |
||||
if {[winfo exists .t]} {fail "child toplevel survived destroy"} |
||||
destroy .l .b |
||||
update |
||||
if {[llength [winfo children .]]} {fail "root children survived destroy: [winfo children .]"} |
||||
} err]} {fail "widget destroy: $err"} |
||||
|
||||
puts "tk_smoke OK: Tk $tkver (Ttk $ttkver) windowingsystem $wsys screen $screen widgets [join $classes /] create+map+destroy clean" |
||||
flush stdout |
||||
exit 0 |
||||
Loading…
Reference in new issue