Browse Source

G-096: suite pinned to official zig 0.14.1 (punkbin-hosted); recipe compat deltas keep dev.2074 working

Recipe: b.host -> b.graph.host; redundant second UNICODE tclMain add into the
objs lib removed; exe's ansi tclMain compiled with -UUNICODE -U_UNICODE
-DTCL_ASCII_MAIN (zig cc windows-default defines made it a duplicate UNICODE
compile under 0.14.1 - lld duplicate Tcl_MainExW/commons). Driver: per-item
recipe staging, per-zig-version local caches (.zig-cache-<ver>; caches must
not be shared across zig versions), zig resolution -zig > PUNK_ZIG > pinned
bin/tools/zig-x86_64-windows-0.14.1 > PATH. Verified: PASS on 0.14.1 AND
regression PASS on 0.14.0-dev.2074; pinned-default no-option run PASS.
Pinned archive minisign-verified and published to punkbin (abcd87c).

Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
Julian Noble 2 weeks ago
parent
commit
a12cdcd2b8
  1. 42
      goals/G-096-zig-buildsuite-piperepl.md
  2. 30
      src/buildsuites/suite_tcl90/README.md
  3. 34
      src/buildsuites/suite_tcl90/build905.zig
  4. 22
      src/buildsuites/suite_tcl90/suite.tcl

42
goals/G-096-zig-buildsuite-piperepl.md

@ -165,13 +165,45 @@ Acceptance: from a clean checkout plus a punk-getzig-fetched pinned zig, the sui
next compile reveals). Pin-path decision put to the user: official 0.14.1 release next compile reveals). Pin-path decision put to the user: official 0.14.1 release
as-is, punkbin-hosted 0.14.0-dev.2074, or completing the 0.15.2 migration. as-is, punkbin-hosted 0.14.0-dev.2074, or completing the 0.15.2 migration.
### 2026-07-20 increment 3: pinned zig 0.14.1 (user-chosen path) validated, hosted on punkbin, wired as suite default
- User decision: pin the first OFFICIAL release in the recipe's line - zig 0.14.1 -
rather than migrating to 0.15.x now or hosting the unreleased dev.2074. Fetched from
a ziglang community mirror (pkg.hexops.org; ziglang.org direct timed out),
minisign-verified against the zig release key (the key punk-getzig embeds), and
extracted to bin/tools/zig-x86_64-windows-0.14.1/.
- Recipe compat deltas for 0.14.1, validated to keep dev.2074 working (regression PASS
on both zigs): b.host -> b.graph.host; the redundant second UNICODE tclMain add into
tcl_objs_static removed (0.14.1 links what dev.2074's archive semantics left
unpulled); the exe's ansi tclMain copy now compiles with -UUNICODE -U_UNICODE
-DTCL_ASCII_MAIN (the zig cc driver can supply windows-default defines - under
0.14.1 the "ansi" copy came out as a duplicate UNICODE compile: lld duplicate
Tcl_MainExW/commons; upstream's TCL_ASCII_MAIN is the intended ascii-variant guard).
- Cache discipline (user insight: zig caches have needed clearing across version
changes): the driver now uses per-zig-version local caches
(.zig-cache-<version> in the staged build dir) and stages the recipe by per-item
sync instead of wholesale delete (windows can hold transient locks on cache trees).
During diagnosis both a fresh local AND isolated global cache were tested - the
0.14.1 duplicate-symbol failure was real recipe/driver behaviour, not stale cache,
but the segregation guards the class going forward.
- punkbin publish (user-directed): zig-x86_64-windows-0.14.1.zip + .minisig added to
punkbin win32-x86_64/tools with sha1sums regenerated per that repo's workflow
(NEW x2, no CHANGED), committed with provenance and PUSHED upstream (abcd87c) - the
suite pin is now fetchable from punk-getzig's primary mirror.
- suite.tcl zig resolution is now: -zig > PUNK_ZIG > pinned
bin/tools/zig-x86_64-windows-0.14.1/zig.exe > PATH; verified end-to-end with no
options (pinned default -> PASS, static+zip shells 9.0.5). README documents the pin,
the compat deltas, and the per-version cache rationale.
- The 0.15.2 migration remains parked (transformer script + findings preserved;
increment-2 record).
Remaining for acceptance: Remaining for acceptance:
- Pin an exact zig version retrievable via punk-getzig and have the suite consume it - punk-getzig per-version fetch argument, so the wrapper itself can materialize the
(driver currently takes -zig / PUNK_ZIG / PATH; validated with 0.14.0-dev.2074; suite's pinned 0.14.1 (currently it installs only its own single pin, 0.15.2, to
pin path = user decision in flight). Note punk-getzig currently pins a single bin/tools/zig; the suite pin was materialized by the same fetch+minisign flow
$releasearchive - a per-version fetch argument (or suite-side fetch) is likely manually and is hosted on punkbin). Payload growth needs the 512-byte spacer
wanted so the suite pin and the general-tools pin can differ. check on re-wrap.
- Rebase the piperepl patch onto current core-9-0-branch sources; build a - Rebase the piperepl patch onto current core-9-0-branch sources; build a
piperepl-enabled variant; behaviour matrix (TCLSH_PIPEREPL unset == stock on piperepl-enabled variant; behaviour matrix (TCLSH_PIPEREPL unset == stock on
tty/piped/script-arg forms; =1 with a script setting ::tclsh(dorepl) 1 -> live tty/piped/script-arg forms; =1 with a script setting ::tclsh(dorepl) 1 -> live

30
src/buildsuites/suite_tcl90/README.md

@ -15,9 +15,25 @@ the repo's existing `_build` globs): staged recipe, source checkouts, zig cache,
tclsh suite.tcl clean tclsh suite.tcl clean
See `suite.tcl`'s header for options (`-zig`, `-optimize`, `-tclbranch`, `-refresh`, See `suite.tcl`'s header for options (`-zig`, `-optimize`, `-tclbranch`, `-refresh`,
`-vqtcl-source`, `-steps`). The zig executable defaults to `$env(PUNK_ZIG)` or `zig` on `-vqtcl-source`, `-steps`). Zig resolution: `-zig` > `$env(PUNK_ZIG)` > the pinned
PATH; the recipe's known-good zig is 0.14.0-dev.2074 (see Lineage) - a punk-getzig toolchain at `bin/tools/zig-x86_64-windows-0.14.1/zig.exe` > `zig` on PATH.
fetched pinned zig is the intended source (G-096 acceptance; wrapper rename pending).
## Pinned zig
The suite pin is **zig 0.14.1** (first official release in the recipe's 0.14 line;
the recipe is validated against BOTH 0.14.1 and the original 0.14.0-dev.2074 - see
Lineage). The pinned archive `zig-x86_64-windows-0.14.1.zip` (+`.minisig`) is hosted
on the punkbin artifact repo (`win32-x86_64/tools/`, sha1sums recorded) - the same
mirror punk-getzig consults - and was minisign-verified against the zig release key
before hosting. To materialize it: download from punkbin (or a ziglang community
mirror), verify the minisig, extract to `bin/tools/zig-x86_64-windows-0.14.1/`.
punk-getzig currently installs only its own single pinned version (0.15.2) to
`bin/tools/zig`; a per-version fetch argument is the intended enhancement so it can
materialize the suite pin directly.
Zig object caches are kept **per zig version** (`.zig-cache-<version>` inside the
staged build dir): caches must never be shared across zig versions (observed
producing stale/duplicate artifacts at link time).
## Layout ## Layout
@ -75,3 +91,11 @@ built 2024-11-27, zig 0.14.0-dev.2074) plus the 2026-07-20 G-076 deltas - source
tclAppInit's `_tmain` is `wmain` under `-DUNICODE`). Full provenance: tclAppInit's `_tmain` is `wmain` under `-DUNICODE`). Full provenance:
`goals/archive/G-076-tcl9-deadconsole-fix-adoption.md` (2026-07-20 entries). Goal `goals/archive/G-076-tcl9-deadconsole-fix-adoption.md` (2026-07-20 entries). Goal
contract for this suite: `goals/G-096-zig-buildsuite-piperepl.md`. contract for this suite: `goals/G-096-zig-buildsuite-piperepl.md`.
zig 0.14.1 compat deltas (2026-07-20, validated to keep dev.2074 working too):
`b.host` -> `b.graph.host`; the redundant second UNICODE tclMain add into the objs
lib removed (0.14.1 links what dev.2074's archiver left unpulled); the exe's ansi
tclMain copy compiles with `-UUNICODE -U_UNICODE -DTCL_ASCII_MAIN` (the zig cc
driver can supply windows-default defines, which made the "ansi" copy a duplicate
UNICODE compile under 0.14.1 - upstream's TCL_ASCII_MAIN guard is the intended
mechanism for the ascii variant).

34
src/buildsuites/suite_tcl90/build905.zig

@ -236,7 +236,7 @@ pub fn build(b: *std.Build) !void {
const wrap_exe = b.addExecutable(.{ const wrap_exe = b.addExecutable(.{
.name = "wrapfiletofile", .name = "wrapfiletofile",
.root_source_file = b.path("tools/wrapfiletofile.zig"), .root_source_file = b.path("tools/wrapfiletofile.zig"),
.target = b.host, .target = b.graph.host,
}); });
//const tool_step = b.addRunArtifact(tool); //const tool_step = b.addRunArtifact(tool);
const wrap_run = b.addRunArtifact(wrap_exe); const wrap_run = b.addRunArtifact(wrap_exe);
@ -1338,13 +1338,17 @@ pub fn build(b: *std.Build) !void {
tcl_objs_static.addIncludePath(b.path(tcl_source_folder ++ "/compat/zlib")); tcl_objs_static.addIncludePath(b.path(tcl_source_folder ++ "/compat/zlib"));
tcl_objs_static.addIncludePath(b.path(tcl_source_folder ++ "/compat/zlib/contrib/minizip")); //only required by tclZipfs - but ok for all? tcl_objs_static.addIncludePath(b.path(tcl_source_folder ++ "/compat/zlib/contrib/minizip")); //only required by tclZipfs - but ok for all?
//tclMain.c needs to be built twice on windows - with and without unicode flags //tclMain.c needs to be built twice on windows - with and without unicode flags.
if (target.result.os.tag == .windows) { //The UNICODE copy is already produced by the generic sources loop (build_specials
tcl_objs_static.addCSourceFile(.{ //maps tclMain -> mainw_flags); the ansi copy is added to the exe below. A second
.file = b.path(tcl_source_folder ++ "/generic/tclMain.c"), //explicit UNICODE add here was harmless under zig 0.14.0-dev.2074 (the duplicate
.flags = mainw_flags.items, //archive member was never extracted) but zig 0.14.1 links it -> duplicate symbols.
}); //if (target.result.os.tag == .windows) {
} // tcl_objs_static.addCSourceFile(.{
// .file = b.path(tcl_source_folder ++ "/generic/tclMain.c"),
// .flags = mainw_flags.items,
// });
//}
var current_flagset: std.ArrayList([]const u8) = undefined; var current_flagset: std.ArrayList([]const u8) = undefined;
for (tcl_objs_static_sources.items) |src| { for (tcl_objs_static_sources.items) |src| {
if (build_specials.get(std.fs.path.stem(src))) |val| { if (build_specials.get(std.fs.path.stem(src))) |val| {
@ -1632,9 +1636,21 @@ pub fn build(b: *std.Build) !void {
//tclMain needs to be compiled twice on windows - with and without unicode //tclMain needs to be compiled twice on windows - with and without unicode
//we have already configured the one in the sources list to compile with mainw_flags (DUNICODE etc) //we have already configured the one in the sources list to compile with mainw_flags (DUNICODE etc)
if (target.result.os.tag == .windows) { if (target.result.os.tag == .windows) {
//The ansi copy must NOT see UNICODE: undefine explicitly (the zig cc driver can
//supply windows-default defines - observed with zig 0.14.1 as duplicate
//Tcl_MainExW/common symbols vs the mainw copy) and use upstream's
//TCL_ASCII_MAIN guard so only the ascii Tcl_MainEx variant is emitted.
var mainansi_flags = std.ArrayList([]const u8).init(b.allocator);
defer mainansi_flags.deinit();
try mainansi_flags.appendSlice(tclobjs_flags.items);
try mainansi_flags.appendSlice(&.{
"-UUNICODE",
"-U_UNICODE",
"-DTCL_ASCII_MAIN",
});
tclsh_exe.addCSourceFile(.{ tclsh_exe.addCSourceFile(.{
.file = b.path(tcl_source_folder ++ "/generic/tclMain.c"), .file = b.path(tcl_source_folder ++ "/generic/tclMain.c"),
.flags = tclobjs_flags.items, .flags = mainansi_flags.items,
}); });
} }
tclsh_exe.addCSourceFile(.{ tclsh_exe.addCSourceFile(.{

22
src/buildsuites/suite_tcl90/suite.tcl

@ -50,7 +50,17 @@ array set opt {
-vqtcl-source C:/buildtcl/2024zig/vqtcl -vqtcl-source C:/buildtcl/2024zig/vqtcl
-steps {install install-libraries make-zipfs} -steps {install install-libraries make-zipfs}
} }
set opt(-zig) [expr {[info exists env(PUNK_ZIG)] ? $env(PUNK_ZIG) : "zig"}] #zig resolution: -zig option > PUNK_ZIG env > the suite's pinned toolchain under
#bin/tools (zig 0.14.1 official release - hosted on punkbin, minisign-verified;
#recipe also validated against the original 0.14.0-dev.2074) > 'zig' on PATH.
set pinned_zig [file normalize [file join $suiteroot .. .. .. bin tools zig-x86_64-windows-0.14.1 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] { foreach {k v} [lrange $argv 1 end] {
if {![info exists opt($k)]} {fail "unknown option '$k'"} if {![info exists opt($k)]} {fail "unknown option '$k'"}
set opt($k) $v set opt($k) $v
@ -93,11 +103,14 @@ proc fossil_source {name url branch dir} {
} }
#-- stage the recipe ------------------------------------------------------ #-- 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 - they are per-zig-version (see --cache-dir below), and windows
#can hold transient locks on recently-used cache trees.
set builddir [file join $stage build] set builddir [file join $stage build]
log "staging recipe -> $builddir" log "staging recipe -> $builddir"
file delete -force $builddir
file mkdir $builddir file mkdir $builddir
foreach item {build905.zig build_libtommath build_zlib build_tclvfs build_vqtcl build_tclthread src tools} { foreach item {build905.zig build_libtommath build_zlib build_tclvfs build_vqtcl build_tclthread src tools} {
file delete -force [file join $builddir $item]
file copy [file join $suiteroot $item] $builddir file copy [file join $suiteroot $item] $builddir
} }
@ -158,9 +171,12 @@ if {![string match "*tcl905/generic/tcl.h*" $rc]} {
#-- build ----------------------------------------------------------------- #-- build -----------------------------------------------------------------
set zigv [exec $opt(-zig) version] set zigv [exec $opt(-zig) version]
log "zig: $opt(-zig) ($zigv)" log "zig: $opt(-zig) ($zigv)"
#Per-zig-version local cache: object caches must never be shared across zig versions
#(observed producing stale/duplicate artifacts in the link; user-confirmed hazard).
set cachedir ".zig-cache-[string map {+ _ / _ : _} $zigv]"
set savedpwd [pwd] set savedpwd [pwd]
cd $builddir cd $builddir
run $opt(-zig) build --build-file build905.zig --prefix [file join $stage out] -Doptimize=$opt(-optimize) {*}$opt(-steps) run $opt(-zig) build --build-file build905.zig --cache-dir $cachedir --prefix [file join $stage out] -Doptimize=$opt(-optimize) {*}$opt(-steps)
cd $savedpwd cd $savedpwd
#-- smoke ----------------------------------------------------------------- #-- smoke -----------------------------------------------------------------

Loading…
Cancel
Save