diff --git a/goals/G-096-zig-buildsuite-piperepl.md b/goals/G-096-zig-buildsuite-piperepl.md index 7d183d05..39ea401e 100644 --- a/goals/G-096-zig-buildsuite-piperepl.md +++ b/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 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- 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: -- Pin an exact zig version retrievable via punk-getzig and have the suite consume it - (driver currently takes -zig / PUNK_ZIG / PATH; validated with 0.14.0-dev.2074; - pin path = user decision in flight). Note punk-getzig currently pins a single - $releasearchive - a per-version fetch argument (or suite-side fetch) is likely - wanted so the suite pin and the general-tools pin can differ. +- punk-getzig per-version fetch argument, so the wrapper itself can materialize the + suite's pinned 0.14.1 (currently it installs only its own single pin, 0.15.2, to + bin/tools/zig; the suite pin was materialized by the same fetch+minisign flow + manually and is hosted on punkbin). Payload growth needs the 512-byte spacer + check on re-wrap. - Rebase the piperepl patch onto current core-9-0-branch sources; build a piperepl-enabled variant; behaviour matrix (TCLSH_PIPEREPL unset == stock on tty/piped/script-arg forms; =1 with a script setting ::tclsh(dorepl) 1 -> live diff --git a/src/buildsuites/suite_tcl90/README.md b/src/buildsuites/suite_tcl90/README.md index 169dd4f9..8a02b6bf 100644 --- a/src/buildsuites/suite_tcl90/README.md +++ b/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 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 -PATH; the recipe's known-good zig is 0.14.0-dev.2074 (see Lineage) - a punk-getzig -fetched pinned zig is the intended source (G-096 acceptance; wrapper rename pending). +`-vqtcl-source`, `-steps`). Zig resolution: `-zig` > `$env(PUNK_ZIG)` > the pinned +toolchain at `bin/tools/zig-x86_64-windows-0.14.1/zig.exe` > `zig` on PATH. + +## 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-` inside the +staged build dir): caches must never be shared across zig versions (observed +producing stale/duplicate artifacts at link time). ## 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: `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`. + +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). diff --git a/src/buildsuites/suite_tcl90/build905.zig b/src/buildsuites/suite_tcl90/build905.zig index 903b4f88..3cdab10a 100644 --- a/src/buildsuites/suite_tcl90/build905.zig +++ b/src/buildsuites/suite_tcl90/build905.zig @@ -236,7 +236,7 @@ pub fn build(b: *std.Build) !void { const wrap_exe = b.addExecutable(.{ .name = "wrapfiletofile", .root_source_file = b.path("tools/wrapfiletofile.zig"), - .target = b.host, + .target = b.graph.host, }); //const tool_step = b.addRunArtifact(tool); 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/contrib/minizip")); //only required by tclZipfs - but ok for all? - //tclMain.c needs to be built twice on windows - with and without unicode flags - if (target.result.os.tag == .windows) { - tcl_objs_static.addCSourceFile(.{ - .file = b.path(tcl_source_folder ++ "/generic/tclMain.c"), - .flags = mainw_flags.items, - }); - } + //tclMain.c needs to be built twice on windows - with and without unicode flags. + //The UNICODE copy is already produced by the generic sources loop (build_specials + //maps tclMain -> mainw_flags); the ansi copy is added to the exe below. A second + //explicit UNICODE add here was harmless under zig 0.14.0-dev.2074 (the duplicate + //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; for (tcl_objs_static_sources.items) |src| { 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 //we have already configured the one in the sources list to compile with mainw_flags (DUNICODE etc) 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(.{ .file = b.path(tcl_source_folder ++ "/generic/tclMain.c"), - .flags = tclobjs_flags.items, + .flags = mainansi_flags.items, }); } tclsh_exe.addCSourceFile(.{ diff --git a/src/buildsuites/suite_tcl90/suite.tcl b/src/buildsuites/suite_tcl90/suite.tcl index 6489d55d..91ee40f0 100644 --- a/src/buildsuites/suite_tcl90/suite.tcl +++ b/src/buildsuites/suite_tcl90/suite.tcl @@ -50,7 +50,17 @@ array set opt { -vqtcl-source C:/buildtcl/2024zig/vqtcl -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] { if {![info exists opt($k)]} {fail "unknown option '$k'"} set opt($k) $v @@ -93,11 +103,14 @@ proc fossil_source {name url branch dir} { } #-- 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] log "staging recipe -> $builddir" -file delete -force $builddir file mkdir $builddir 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 } @@ -158,9 +171,12 @@ if {![string match "*tcl905/generic/tcl.h*" $rc]} { #-- build ----------------------------------------------------------------- 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 +#(observed producing stale/duplicate artifacts in the link; user-confirmed hazard). +set cachedir ".zig-cache-[string map {+ _ / _ : _} $zigv]" set savedpwd [pwd] 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 #-- smoke -----------------------------------------------------------------