Browse Source
Generation of the configure-products a fresh checkout lacks moves from suite.tcl tree-writes into the zig recipe as build-cache overlays: - tclUuid.h / tkUuid.h / threadUuid.h: wrapfiletofile Run outputs consumed via overlay include dirs added FIRST per module (stale tree copies from pre-G-102 flows can never shadow; the LazyPath also carries the step dep). The unused addUpdateSourceFiles tree-write variants (build905 prepare-source, build_tclthread) are removed. - tclsh.exe.manifest: configure-time substitution (tcl.h parsed by the new build_common.zig helpers); tclsh.rc compiled from an overlay COPY beside the generated manifest because rc resource references resolve rc-file-relative before include paths. Both tclsh exes switch to .include_paths LazyPaths. - wish.exe.manifest: overlay dir first in tk.rc include_paths (RT_MANIFEST resolves through rc include paths - the arrangement the tk build already relied on). tk.rc itself stays tree-compiled (lives in win/rc, no stale risk). - thread.rc: compiled from an overlay copy with the tcl.h include inserted (the historical checkout edit is normalized if a mutated tree is staged); the staged tclthread checkout's thread.rc edit has been fossil-reverted. - build905.zig: redundant configure-time top-level library install loop removed (install_library_tree already covers it); dead zlib stage copy and the suite.tcl generation blocks removed (read-only version parsing kept for smokes/logging). Verified: full staged-mode rebuild PASS (all smokes incl tklib/tcllib/tcllibc); built binaries carry the overlay products (tcl::build-info reports 9.0.5+1a9c3b9d..., tclsh manifest version 9.0.2.905, tk dll manifest + tk checkout uuid, thread dll uuid; thread dll's empty FileVersion matches the pre-change binary - upstream quirk). Source checkouts stay pristine (fossil changes empty). Core test gate: 69783 run, 12 failed - 11 baselined plus http-4.14.2, a network-timing flake that passes on isolated rerun (528/519/9/0). tclsh90sprzip.exe install into out/bin is currently blocked by an open user application holding the file; the product builds identically into the zig cache and installs on next run once released. Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.commaster
5 changed files with 179 additions and 161 deletions
@ -0,0 +1,61 @@
|
||||
//build_common.zig - shared configure-time helpers for the suite recipe files (G-102). |
||||
//These run while the build graph is being CONSTRUCTED (not as build steps). Reads are |
||||
//of staged/fetched source trees; generated content is never written into a source |
||||
//tree - it goes through b.addWriteFiles() overlays into the build cache and is |
||||
//consumed via overlay include dirs / overlay rc copies. |
||||
const std = @import("std"); |
||||
|
||||
pub fn pathExists(b: *std.Build, path_from_root: []const u8) bool { |
||||
const abs = b.pathFromRoot(path_from_root); |
||||
std.Io.Dir.cwd().access(b.graph.io, abs, .{}) catch return false; |
||||
return true; |
||||
} |
||||
|
||||
pub fn readSourceFile(b: *std.Build, path_from_root: []const u8) []u8 { |
||||
const abs = b.pathFromRoot(path_from_root); |
||||
return std.Io.Dir.cwd().readFileAlloc(b.graph.io, abs, b.allocator, .limited(8 * 1024 * 1024)) catch |err| { |
||||
std.debug.panic("suite recipe: cannot read {s}: {s}", .{ abs, @errorName(err) }); |
||||
}; |
||||
} |
||||
|
||||
//value of a '#define <name> "<value>"' line (e.g TCL_PATCH_LEVEL from tcl.h) |
||||
pub fn parseDefineString(content: []const u8, name: []const u8) ?[]const u8 { |
||||
var it = std.mem.splitScalar(u8, content, '\n'); |
||||
while (it.next()) |line| { |
||||
const trimmed = std.mem.trim(u8, line, " \t\r"); |
||||
if (!std.mem.startsWith(u8, trimmed, "#")) continue; |
||||
const after_hash = std.mem.trimStart(u8, trimmed[1..], " \t"); |
||||
if (!std.mem.startsWith(u8, after_hash, "define")) continue; |
||||
const after_def = std.mem.trimStart(u8, after_hash[6..], " \t"); |
||||
if (!std.mem.startsWith(u8, after_def, name)) continue; |
||||
const after_name = after_def[name.len..]; |
||||
if (after_name.len == 0 or (after_name[0] != ' ' and after_name[0] != '\t')) continue; |
||||
const q1 = std.mem.indexOfScalar(u8, after_name, '"') orelse continue; |
||||
const rest = after_name[q1 + 1 ..]; |
||||
const q2 = std.mem.indexOfScalar(u8, rest, '"') orelse continue; |
||||
return rest[0..q2]; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
pub fn replaceAll(b: *std.Build, input: []const u8, needle: []const u8, replacement: []const u8) []u8 { |
||||
return std.mem.replaceOwned(u8, b.allocator, input, needle, replacement) catch @panic("OOM"); |
||||
} |
||||
|
||||
//TCL_WIN_VERSION / TK_WIN_VERSION as the makefiles derive them: |
||||
//<dotversion>.<releaselevel>.<patchlevel with a/b/. stripped>, releaselevel |
||||
//0=alpha 1=beta 2=final (e.g 9.0 + 9.0.5 -> 9.0.2.905) |
||||
pub fn winResourceVersion(b: *std.Build, dotversion: []const u8, patchlevel: []const u8) []u8 { |
||||
const rlevel: u8 = if (std.mem.indexOfScalar(u8, patchlevel, 'a') != null) |
||||
'0' |
||||
else if (std.mem.indexOfScalar(u8, patchlevel, 'b') != null) |
||||
'1' |
||||
else |
||||
'2'; |
||||
var stripped = std.array_list.Managed(u8).init(b.allocator); |
||||
for (patchlevel) |ch| { |
||||
if (ch == 'a' or ch == 'b' or ch == '.') continue; |
||||
stripped.append(ch) catch @panic("OOM"); |
||||
} |
||||
return std.fmt.allocPrint(b.allocator, "{s}.{c}.{s}", .{ dotversion, rlevel, stripped.items }) catch @panic("OOM"); |
||||
} |
||||
Loading…
Reference in new issue