From 10128952aac82b52e2ad784800588e067a7a6048 Mon Sep 17 00:00:00 2001 From: Julian Noble Date: Tue, 21 Jul 2026 13:10:24 +1000 Subject: [PATCH] suite_tcl90: derive thread version from the checkout (was hardcoded 3.0.1) Found by G-107's first library-test census: build_tclthread.zig compiled thread trunk 3.0.7 sources with -DPACKAGE_VERSION="3.0.1", so the dll self-reported the wrong version, and the pkgIndex declared only capital-T Thread 3.0.1 - the thread testsuite's 'package require -exact thread 3.0.7' could never load the package (nothing previously load-tested thread at all). The version now derives from the tree's AC_INIT (new build_common helpers acInitVersion/stripChars) and flows into every version-derived name: dll tcl9thread.dll, install dir lib/thread, PACKAGE_VERSION/ PACKAGE_STRING defines, rc resource fields, and a pkgIndex declaring BOTH 'Thread' and 'thread' (threadCmd.c provides both; the testsuite requires lowercase, existing punkshell consumers the capitalized name). Dead zip-related consts riding the stale version removed. Note for the next kit/vfs refresh: the punk905 kit payload (src/vfs/punk9wintk905.vfs/lib_tcl9/thread3.0.1/) still carries the old self-consistent 3.0.1-stamped copy - refresh to the derived naming then. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com --- src/buildsuites/suite_tcl90/build_common.zig | 34 ++++++++++++++ .../build_tclthread/build_tclthread.zig | 47 ++++++++++++------- 2 files changed, 63 insertions(+), 18 deletions(-) diff --git a/src/buildsuites/suite_tcl90/build_common.zig b/src/buildsuites/suite_tcl90/build_common.zig index 18be5cc3..8ee66331 100644 --- a/src/buildsuites/suite_tcl90/build_common.zig +++ b/src/buildsuites/suite_tcl90/build_common.zig @@ -53,6 +53,40 @@ pub fn scrubTclEnv(run: *std.Build.Step.Run) void { } } +//package version from a TEA tree's configure.ac 'AC_INIT([name],[version])' +//line (thread, tclvfs, ...). G-107: version-derived artifact names must follow +//the checkout - hardcoded versions stamp mismatched sources (the thread recipe +//once compiled 3.0.7 sources as 3.0.1; the dll self-reported the wrong version +//and the thread testsuite's exact-version require could never load it). +pub fn acInitVersion(b: *std.Build, tree_from_root: []const u8) []const u8 { + const data = readSourceFile(b, b.fmt("{s}/configure.ac", .{tree_from_root})); + var it = std.mem.splitScalar(u8, data, '\n'); + while (it.next()) |line| { + const trimmed = std.mem.trim(u8, line, " \t\r"); + if (!std.mem.startsWith(u8, trimmed, "AC_INIT")) continue; + //the second [...] group is the version + var rest = trimmed; + var group: usize = 0; + while (std.mem.indexOfScalar(u8, rest, '[')) |open| { + const after = rest[open + 1 ..]; + const close = std.mem.indexOfScalar(u8, after, ']') orelse break; + group += 1; + if (group == 2) return b.dupe(after[0..close]); + rest = after[close + 1 ..]; + } + } + std.debug.panic("no AC_INIT version in {s}/configure.ac", .{tree_from_root}); +} + +pub fn stripChars(b: *std.Build, input: []const u8, drop: []const u8) []u8 { + var out = std.array_list.Managed(u8).init(b.allocator); + for (input) |ch| { + if (std.mem.indexOfScalar(u8, drop, ch) != null) continue; + out.append(ch) catch @panic("OOM"); + } + return out.items; +} + //tcllib-family installer trees carry 'package_version ' in //support/installation/version.tcl pub fn installerPackageVersion(b: *std.Build, tree_from_root: []const u8) []const u8 { diff --git a/src/buildsuites/suite_tcl90/build_tclthread/build_tclthread.zig b/src/buildsuites/suite_tcl90/build_tclthread/build_tclthread.zig index 1ae2ea82..50324660 100644 --- a/src/buildsuites/suite_tcl90/build_tclthread/build_tclthread.zig +++ b/src/buildsuites/suite_tcl90/build_tclthread/build_tclthread.zig @@ -3,18 +3,24 @@ const fs = std.fs; const builtin = @import("builtin"); const common = @import("../build_common.zig"); -const mkvar_thread_version = "3.0.1"; -const mkvar_thread_zip_file = "libthread" ++ mkvar_thread_version ++ ".zip"; -const mkvar_thread_vfs_root = "libthread.vfs"; -const mkvar_thread_vfs_path = mkvar_thread_vfs_root ++ "/thread_library"; - -const mkvar_pkg_lib_file = "tcl9thread301.dll"; - // Although this function looks imperative, note that its job is to // declaratively construct a build graph that will be executed by an external // runner. //pub fn build(b: *std.Build) !void {} pub fn build_tclthread(comptime tcldir: []const u8, comptime subdir: []const u8, b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, stublib: *std.Build.Step.Compile) !*std.Build.Step.Compile { + //Version derived from the checkout's AC_INIT (G-107): the recipe formerly + //hardcoded 3.0.1, compiling newer trunk sources with a stale PACKAGE_VERSION - + //the dll then self-reported the wrong version and the thread testsuite's + //'package require -exact thread ' could never load it. All + //version-derived names below (dll, install dir, pkgIndex, resource fields) + //follow the tree. + const thread_version = common.acInitVersion(b, subdir); + const thread_vernodots = common.stripChars(b, thread_version, "."); + const pkg_lib_name = b.fmt("tcl9thread{s}", .{thread_vernodots}); + const pkg_lib_file = b.fmt("{s}.dll", .{pkg_lib_name}); + var thread_verparts = std.mem.splitScalar(u8, thread_version, '.'); + const thread_ver_major = thread_verparts.next() orelse "0"; + const thread_ver_minor = thread_verparts.next() orelse "0"; const wrapfilecmd = b.addExecutable(.{ .name = "wrapfiletofile", .root_module = b.createModule(.{ @@ -65,7 +71,7 @@ pub fn build_tclthread(comptime tcldir: []const u8, comptime subdir: []const u8, const lib = b.addLibrary(.{ .linkage = .dynamic, - .name = "tcl9thread301", + .name = pkg_lib_name, .root_module = b.createModule(.{ .target = target, .optimize = optimize, @@ -79,8 +85,8 @@ pub fn build_tclthread(comptime tcldir: []const u8, comptime subdir: []const u8, try flags.appendSlice(&.{ "-DPACKAGE_NAME=\"thread\"", "-DPACKAGE_TARNAME=\"thread\"", - "-DPACKAGE_VERSION=\"3.0.1\"", - "-DPACKAGE_STRING=\"thread 3.0.1\"", + b.fmt("-DPACKAGE_VERSION=\"{s}\"", .{thread_version}), + b.fmt("-DPACKAGE_STRING=\"thread {s}\"", .{thread_version}), "-DPACKAGE_BUGREPORT=\"\"", "-DPACKAGE_URL=\"\"", "-DTCL_CFG_OPTIMIZED=1", @@ -155,9 +161,9 @@ pub fn build_tclthread(comptime tcldir: []const u8, comptime subdir: []const u8, lib.root_module.addWin32ResourceFile(.{ .file = threadrc_overlay, .flags = &.{ - "-DPACKAGE_MAJOR=3", - "-DPACKAGE_MINOR=0", - "-DPACKAGE_VERSION=3.0b2", + b.fmt("-DPACKAGE_MAJOR={s}", .{thread_ver_major}), + b.fmt("-DPACKAGE_MINOR={s}", .{thread_ver_minor}), + b.fmt("-DPACKAGE_VERSION={s}", .{thread_version}), }, .include_paths = &.{ b.path(tcldir ++ "/generic"), @@ -166,13 +172,18 @@ pub fn build_tclthread(comptime tcldir: []const u8, comptime subdir: []const u8, }); //ignored for non-windows targets b.installArtifact(lib); - //G-102: pkgIndex.tcl so 'package require Thread' resolves against the prefix + //G-102: pkgIndex.tcl so package requires resolve against the prefix //(punkshell runtests -jobs and codethread need it) - formerly a suite.tcl - //post-build block. + //post-build block. Both capitalizations are declared (G-107): the dll + //provides 'Thread' AND 'thread' (threadCmd.c PkgProvideEx x2); the thread + //testsuite requires the lowercase name, existing punkshell consumers the + //capitalized one. const wf_pkgidx = b.addWriteFiles(); - const pkgidx = wf_pkgidx.add("pkgIndex.tcl", "package ifneeded Thread " ++ mkvar_thread_version ++ - " [list load [file normalize [file join $dir .. .. bin " ++ mkvar_pkg_lib_file ++ "]] Thread]\n"); - const pkgidx_install = b.addInstallFileWithDir(pkgidx, .prefix, "lib/thread" ++ mkvar_thread_version ++ "/pkgIndex.tcl"); + const pkgidx = wf_pkgidx.add("pkgIndex.tcl", b.fmt( + "package ifneeded Thread {s} [list load [file normalize [file join $dir .. .. bin {s}]] Thread]\n" ++ + "package ifneeded thread {s} [list load [file normalize [file join $dir .. .. bin {s}]] Thread]\n", + .{ thread_version, pkg_lib_file, thread_version, pkg_lib_file })); + const pkgidx_install = b.addInstallFileWithDir(pkgidx, .prefix, b.fmt("lib/thread{s}/pkgIndex.tcl", .{thread_version})); b.getInstallStep().dependOn(&pkgidx_install.step); return lib;