Browse Source
Land the ready-to-land fork records in both flows and build the mk4
candidate's loadable shape as a suite battery:
- sources.config: source metakit git (gitea jn/metakit) pinned at
6a92b479 (the G-153-verified tree); matching build.zig.zon .metakit
lazy record (url+hash re-verified live via zig fetch at landing).
- build_mk4tcl86/: new extension module (build_tclvfs86 conventions) -
engine static lib (q4_UNIV set, -fno-exceptions -fno-rtti) + Mk4tcl.dll
(mk4tcl.cpp + bundled mk4too.cpp, USE_TCL_STUBS + BUILD_Mk4tcl) against
the suite stub lib; package version parsed from the staged
Tcl_PkgProvide; installs lib/mk4tcl2.4.9.8/{Mk4tcl.dll,pkgIndex.tcl}.
- build86.zig: build-mk4tcl step + install hook, pkg_smoke gains Mk4tcl,
bootstrapMode source_dirs/recipe_items rows; suite.tcl required-source
+ staged recipe item lists; README deliverable + selection records.
- goal detail: Progress increment record with the verification transcript
facts.
VERIFIED: suite.tcl build -steps {install install-libraries smoke} clones
the fork from the record, builds the dll, and pkg_smoke reports
Mk4tcl:2.4.9.8 in BOTH shells (tclsh86t dynamic AND tclsh86ts static).
Assisted-by: harness=claude; primary-model=claude-fable-5; api-location=anthropic.com
master
7 changed files with 210 additions and 3 deletions
@ -0,0 +1,125 @@
|
||||
const std = @import("std"); |
||||
const common = @import("../build_common.zig"); |
||||
|
||||
//build_mk4tcl86 - Mk4tcl (metakit_punk fork) loadable extension for the 8.6 |
||||
//suite (G-101). The metakit port itself lives in the fork-as-upstream repo |
||||
//(gitea jn/metakit; G-153 - built, regress-tested and smoke-verified standalone |
||||
//under the pinned zig, win32-x86_64 + win32-ix86). This module re-expresses the |
||||
//fork's own 'mk4tcl' build step in suite shape (build_tclvfs86 conventions: |
||||
//staged source tree beside the recipe, the suite's stub lib, install hooked onto |
||||
//the default step) so the suite's kit-container work consumes suite-built bytes. |
||||
// |
||||
//Fork facts carried over (decision records: metakit fork src/AGENTS.md + |
||||
//build.zig - keep the two recipes in step): |
||||
// - engine sources = upstream CMake metakit_SOURCES (q4_UNIV default set: |
||||
// univ.cpp in, std.cpp out), compiled -fno-exceptions -fno-rtti (the ported |
||||
// core is exception- and RTTI-free); mk4tcl.cpp keeps exceptions ON (real |
||||
// try/catch). |
||||
// - mk4too.cpp is bundled: a hard link dependency of mk4tcl.cpp (mk::view |
||||
// open/new construct MkView unguarded) and the oomk consumer needs it - |
||||
// matching both upstream builds (CMake and KitCreator). |
||||
// - -fno-sanitize=undefined/-fno-sanitize-trap=undefined everywhere: zig cc's |
||||
// default trapping UBSan fires on 2007-era formal UB (suite tcl/tk/zlib |
||||
// precedent; first site derived.cpp:308). |
||||
// - BUILD_Mk4tcl gates TCL_STORAGE_CLASS = DLLEXPORT in mk4tcl.h (TEA form); |
||||
// USE_TCL_STUBS for the stubs contract (proven cross-patchlevel and |
||||
// cross-CRT in the G-153 smokes). |
||||
// - dll name stays Mk4tcl.dll (fork/upstream-recognizable, no TEA-nmake |
||||
// vfs142t-style renaming): unlike tclvfs there is no script loading |
||||
// @PKG_LIB_FILE8@ by guessed init name - the generated pkgIndex passes the |
||||
// init name explicitly ('load ... Mk4tcl'; load-name guessing stops at |
||||
// digits, the historical Mk_Init quirk). |
||||
|
||||
//upstream src/CMakeLists.txt metakit_SOURCES (q4_UNIV default set) - same list |
||||
//as the fork build.zig core_sources |
||||
const core_sources = [_][]const u8{ |
||||
"column.cpp", "custom.cpp", "derived.cpp", "field.cpp", "fileio.cpp", |
||||
"format.cpp", "handler.cpp", "persist.cpp", "remap.cpp", "store.cpp", |
||||
"string.cpp", "table.cpp", "univ.cpp", "view.cpp", "viewx.cpp", |
||||
}; |
||||
|
||||
const engine_flags = [_][]const u8{ |
||||
"-fno-exceptions", |
||||
"-fno-rtti", |
||||
"-fno-sanitize=undefined", |
||||
"-fno-sanitize-trap=undefined", |
||||
}; |
||||
|
||||
const binding_flags = [_][]const u8{ |
||||
"-DUSE_TCL_STUBS=1", |
||||
"-DBUILD_Mk4tcl", |
||||
"-fno-sanitize=undefined", |
||||
"-fno-sanitize-trap=undefined", |
||||
}; |
||||
|
||||
//package version fact from the staged fork tree (never hardcoded): the |
||||
//Tcl_PkgProvide call in mk4tcl.cpp is the authority for what the built dll |
||||
//actually provides ('package provide stays 2.4.9.8' is the fork's recorded |
||||
//version policy - the upstream metakit version, not a fork-local number). |
||||
pub fn packageVersion(b: *std.Build, comptime subdir: []const u8) []const u8 { |
||||
const src = common.readSourceFile(b, subdir ++ "/src/tcl/mk4tcl.cpp"); |
||||
const marker = "Tcl_PkgProvide(interp, \"Mk4tcl\", \""; |
||||
const at = std.mem.indexOf(u8, src, marker) orelse @panic("Tcl_PkgProvide(\"Mk4tcl\", ...) not found in mk4tcl.cpp (staged metakit tree mismatch?)"); |
||||
const rest = src[at + marker.len ..]; |
||||
const end = std.mem.indexOfScalar(u8, rest, '"') orelse @panic("unterminated Tcl_PkgProvide version string in mk4tcl.cpp"); |
||||
return b.dupe(rest[0..end]); |
||||
} |
||||
|
||||
//install the package dir (lib/mk4tcl<ver>, suite convention beside |
||||
//lib/thread2.8.13 and lib/vfs1.4.2): the dll + a generated pkgIndex.tcl |
||||
pub fn install_mk4tcl_package(comptime subdir: []const u8, b: *std.Build, mk4tcl_compile: *std.Build.Step.Compile) !void { |
||||
const ver = packageVersion(b, subdir); |
||||
const pkgsub = b.fmt("lib/mk4tcl{s}", .{ver}); |
||||
const dll_inst = b.addInstallFileWithDir(mk4tcl_compile.getEmittedBin(), .prefix, b.fmt("{s}/Mk4tcl.dll", .{pkgsub})); |
||||
b.getInstallStep().dependOn(&dll_inst.step); |
||||
const wf = b.addWriteFiles(); |
||||
const pkgindex = wf.add("pkgIndex.tcl", b.fmt( |
||||
\\package ifneeded Mk4tcl {s} [list load [file join $dir Mk4tcl.dll] Mk4tcl] |
||||
\\ |
||||
, .{ver})); |
||||
const inst_pkgindex = b.addInstallFileWithDir(pkgindex, .prefix, b.fmt("{s}/pkgIndex.tcl", .{pkgsub})); |
||||
b.getInstallStep().dependOn(&inst_pkgindex.step); |
||||
} |
||||
|
||||
pub fn build_mk4tcl86(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 { |
||||
//the Tcl-agnostic storage engine as its own static lib so the |
||||
//exceptions-off/rtti-off flag set stays separate from the binding's |
||||
const engine = b.addLibrary(.{ |
||||
.linkage = .static, |
||||
.name = "mk4", |
||||
.root_module = b.createModule(.{ |
||||
.target = target, |
||||
.optimize = optimize, |
||||
}), |
||||
}); |
||||
engine.root_module.addIncludePath(b.path(subdir ++ "/src/include")); |
||||
inline for (core_sources) |nm| { |
||||
engine.root_module.addCSourceFile(.{ |
||||
.file = b.path(subdir ++ "/src/core/" ++ nm), |
||||
.flags = &engine_flags, |
||||
}); |
||||
} |
||||
engine.root_module.link_libcpp = true; |
||||
|
||||
const mk4tcl = b.addLibrary(.{ |
||||
.linkage = .dynamic, |
||||
.name = "Mk4tcl", |
||||
.root_module = b.createModule(.{ |
||||
.target = target, |
||||
.optimize = optimize, |
||||
}), |
||||
}); |
||||
mk4tcl.root_module.addIncludePath(b.path(subdir ++ "/src/include")); |
||||
mk4tcl.root_module.addIncludePath(b.path(subdir ++ "/src/core")); //univ.h (fork-edit note in the fork's mk4tcl.h) |
||||
mk4tcl.root_module.addIncludePath(b.path(tcldir ++ "/generic")); |
||||
inline for (.{ "mk4tcl.cpp", "mk4too.cpp" }) |nm| { |
||||
mk4tcl.root_module.addCSourceFile(.{ |
||||
.file = b.path(subdir ++ "/src/tcl/" ++ nm), |
||||
.flags = &binding_flags, |
||||
}); |
||||
} |
||||
mk4tcl.root_module.linkLibrary(engine); |
||||
mk4tcl.root_module.linkLibrary(stublib); |
||||
mk4tcl.root_module.link_libcpp = true; |
||||
return mk4tcl; |
||||
} |
||||
Loading…
Reference in new issue