@ -2,19 +2,44 @@ const std = @import("std");
const fs = std . fs ;
const common = @import ( " ../build_common.zig " ) ;
const tclvfs_dotversion = " 1.4.2 " ;
const tclvfs_nodotversion = " 142 " ;
pub const dotversion = tclvfs_dotversion ;
pub const dll_file = " tcl9vfs " + + tclvfs_nodotversion + + " .dll " ;
/ / G - 107 - style version derivation ( 2026 - 07 - 22 ) : all version - derived tclvfs names
/ / ( package dir , dll names , rc fields , configured vfs . tcl / pkgIndex . tcl contents )
/ / follow the CHECKOUT ' s AC_INIT - the previously hardcoded 1.4 . 2 stamped
/ / mismatched sources once the tclvfs ref moved to the forTcl9 branch ( 1.5 . 0 ) ,
/ / the same failure class as the thread 3.0 . 1 / 3.0 . 7 case G - 107 fixed .
pub const TclvfsInfo = struct {
dotversion : [ ] const u8 , / / e . g " 1.5.0 "
nodots : [ ] const u8 , / / e . g " 150 "
dll_file : [ ] const u8 , / / e . g " tcl9vfs150.dll "
dll8_file : [ ] const u8 , / / e . g " tclvfs150.dll "
major : [ ] const u8 ,
minor : [ ] const u8 ,
} ;
pub fn versionInfo ( b : * std . Build , comptime tree_from_root : [ ] const u8 ) TclvfsInfo {
const dotversion = common . acInitVersion ( b , tree_from_root ) ;
const nodots = common . stripChars ( b , dotversion , " . " ) ;
var parts = std . mem . splitScalar ( u8 , dotversion , '.' ) ;
const major = parts . next ( ) orelse " 0 " ;
const minor = parts . next ( ) orelse " 0 " ;
return . {
. dotversion = dotversion ,
. nodots = nodots ,
. dll_file = b . fmt ( " tcl9vfs{s}.dll " , . { nodots } ) ,
. dll8_file = b . fmt ( " tclvfs{s}.dll " , . { nodots } ) ,
. major = b . dupe ( major ) ,
. minor = b . dupe ( minor ) ,
} ;
}
/ / configure - products ( vfs . tcl , pkgIndex . tcl ) generated from their . in templates at
/ / configure time . Shared by the prefix install and the G - 103 family staging so the
/ / package is generated from one derivation .
fn configuredContent ( b : * std . Build , comptime subdir : [ ] const u8 , comptime template : [ ] const u8 ) [ ] const u8 {
fn configuredContent ( b : * std . Build , comptime subdir : [ ] const u8 , comptime template : [ ] const u8 , info : TclvfsInfo ) [ ] const u8 {
var t : [ ] const u8 = common . readSourceFile ( b , subdir + + " / " + + template ) ;
t = common . replaceAll ( b , t , " @PACKAGE_VERSION@ " , tclvfs_dotversion ) ;
t = common . replaceAll ( b , t , " @PKG_LIB_FILE9@ " , dll_file ) ;
t = common . replaceAll ( b , t , " @PKG_LIB_FILE8@ " , " tclvfs " + + tclvfs_nodotversion + + " .dll " ) ;
t = common . replaceAll ( b , t , " @PACKAGE_VERSION@ " , info . dotversion ) ;
t = common . replaceAll ( b , t , " @PKG_LIB_FILE9@ " , info . dll_file ) ;
t = common . replaceAll ( b , t , " @PKG_LIB_FILE8@ " , info . dll8_file ) ;
return t ;
}
@ -23,7 +48,8 @@ fn configuredContent(b: *std.Build, comptime subdir: []const u8, comptime templa
/ / dll alongside ( vfs . tcl loads it from its own dir via : : vfs : : self ) . Formerly a
/ / suite . tcl post - build block . Windows dll naming - the cross - target story is G - 105 ' s .
pub fn install_tclvfs_package ( comptime subdir : [ ] const u8 , b : * std . Build , tclvfs_compile : * std . Build . Step . Compile ) ! void {
const pkgsub = " lib/vfs " + + tclvfs_dotversion ;
const info = versionInfo ( b , subdir ) ;
const pkgsub = b . fmt ( " lib/vfs{s} " , . { info . dotversion } ) ;
const install_scripts = b . addInstallDirectory ( . {
. source_dir = b . path ( subdir + + " /library " ) ,
. install_dir = . prefix ,
@ -35,7 +61,7 @@ pub fn install_tclvfs_package(comptime subdir: []const u8, b: *std.Build, tclvfs
const install_template = b . addInstallDirectory ( . {
. source_dir = b . path ( subdir + + " /library/template " ) ,
. install_dir = . prefix ,
. install_subdir = pkgsub + + " /template " ,
. install_subdir = b . fmt ( " {s}/template " , . { pkgsub } ) ,
} ) ;
b . getInstallStep ( ) . dependOn ( & install_template . step ) ;
const wf = b . addWriteFiles ( ) ;
@ -43,57 +69,57 @@ pub fn install_tclvfs_package(comptime subdir: []const u8, b: *std.Build, tclvfs
. { " library/vfs.tcl.in " , " vfs.tcl " } ,
. { " pkgIndex.tcl.in " , " pkgIndex.tcl " } ,
} ) | pair | {
const gen = wf . add ( pair [ 1 ] , configuredContent ( b , subdir , pair [ 0 ] ) ) ;
const inst = b . addInstallFileWithDir ( gen , . prefix , pkgsub + + " / " + + pair [ 1 ] ) ;
const gen = wf . add ( pair [ 1 ] , configuredContent ( b , subdir , pair [ 0 ] , info ) ) ;
const inst = b . addInstallFileWithDir ( gen , . prefix , b . fmt ( " {s}/{s} " , . { pkgsub , pair [ 1 ] } ) ) ;
b . getInstallStep ( ) . dependOn ( & inst . step ) ;
}
const dll_inst = b . addInstallFileWithDir ( tclvfs_compile . getEmittedBin ( ) , . prefix , pkgsub + + " / " + + dll_file ) ;
const dll_inst = b . addInstallFileWithDir ( tclvfs_compile . getEmittedBin ( ) , . prefix , b . fmt ( " {s}/{s} " , . { pkgsub , info . dll_file } ) ) ;
b . getInstallStep ( ) . dependOn ( & dll_inst . step ) ;
}
/ / G - 103 : write the SAME installed - shape vfs package into a family staging tree
/ / ( WriteFiles ) at destsub ( e . g " base/lib/vfs1.4.2 " ) - scripts , template dir ,
/ / ( WriteFiles ) at destsub ( e . g " base/lib/vfs1.5.0 " ) - scripts , template dir ,
/ / generated vfs . tcl / pkgIndex . tcl , dll inside the package dir .
pub fn familyadd_tclvfs_package ( comptime subdir : [ ] const u8 , b : * std . Build , wf : * std . Build . Step . WriteFile , comptime destsub : [ ] const u8 , tclvfs_compile : * std . Build . Step . Compile ) ! void {
pub fn familyadd_tclvfs_package ( comptime subdir : [ ] const u8 , b : * std . Build , wf : * std . Build . Step . WriteFile , destsub : [ ] const u8 , tclvfs_compile : * std . Build . Step . Compile ) ! void {
const info = versionInfo ( b , subdir ) ;
_ = wf . addCopyDirectory ( b . path ( subdir + + " /library " ) , destsub , . { . include_extensions = & . { " .tcl " } } ) ;
_ = wf . addCopyDirectory ( b . path ( subdir + + " /library/template " ) , destsub + + " /template " , . { } ) ;
_ = wf . add ( destsub + + " /vfs.tcl " , configuredContent ( b , subdir , " library/vfs.tcl.in " ) ) ;
_ = wf . add ( destsub + + " /pkgIndex.tcl " , configuredContent ( b , subdir , " pkgIndex.tcl.in " ) ) ;
_ = wf . addCopyFile ( tclvfs_compile . getEmittedBin ( ) , destsub + + " / " + + dll_file ) ;
_ = wf . addCopyDirectory ( b . path ( subdir + + " /library/template " ) , b . fmt ( " {s}/template " , . { destsub } ) , . { } ) ;
_ = wf . add ( b . fmt ( " {s}/vfs.tcl " , . { destsub } ) , configuredContent ( b , subdir , " library/vfs.tcl.in " , info ) ) ;
_ = wf . add ( b . fmt ( " {s}/pkgIndex.tcl " , . { destsub } ) , configuredContent ( b , subdir , " pkgIndex.tcl.in " , info ) ) ;
_ = wf . addCopyFile ( tclvfs_compile . getEmittedBin ( ) , b . fmt ( " {s}/{s} " , . { destsub , info . dll_file } ) ) ;
}
pub fn vfsadd_tclvfs_files ( comptime tcldir : [ ] const u8 , comptime subdir : [ ] const u8 , b : * std . Build , vfswrite : * std . Build . Step . WriteFile ) ! * std . Build . Step . WriteFile {
/ / _ = tcldir ;
/ / const version = " 1.4.2 " ;
/ / recursive copy
/ / _ = make_vfs_root . addCopyDirectory ( b . path ( tcl_source_folder + + " /../tclvfs/library " ) , " base/lib/vfs1.4.2 " , . { } ) ;
_ = vfswrite . addCopyDirectory ( b . path ( tcldir + + " / " + + subdir + + " /library " ) , b . pathJoin ( & . { " base " , " lib " , " vfs " + + tclvfs_dotversion } ) , . { } ) ;
/ / recursive copy of the script library into the szip staging tree ( the
/ / generated configure - products + dll are added by the caller / familyadd paths )
const info = versionInfo ( b , tcldir + + " / " + + subdir ) ;
_ = vfswrite . addCopyDirectory ( b . path ( tcldir + + " / " + + subdir + + " /library " ) , b . fmt ( " base/lib/vfs{s} " , . { info . dotversion } ) , . { } ) ;
return vfswrite ;
}
pub fn build_tclvfs ( 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 {
/ / review - libname Vfs vs vfs ? ? ?
const info = versionInfo ( b , subdir ) ;
const lib = b . addLibrary ( . {
. linkage = . dynamic ,
. name = " tcl9vfs142 " ,
. name = b . fmt ( " tcl9vfs{s} " , . { info . nodots } ) ,
. root_module = b . createModule ( . {
. target = target ,
. optimize = optimize ,
} ) ,
} ) ;
/ / _ = stublib ;
var flags = std . array_list . Managed ( [ ] const u8 ) . init ( b . allocator ) ;
defer flags . deinit ( ) ;
/ / try flags . appendSlice ( & . { " -Wall " , " -O3 " } ) ;
try flags . appendSlice ( & . { " -Wall " , " -O3 " , " -fomit-frame-pointer " } ) ;
try flags . appendSlice ( & . {
" -DPACKAGE_NAME= \" vfs \" " ,
" -DPACKAGE_TARNAME= \" vfs \" " ,
" -DPACKAGE_VERSION= \" " + + tclvfs_dotversion + + " \" " ,
" -DPACKAGE_STRING= \" vfs " + + tclvfs_dotversion + + " \" " ,
b . fmt ( " -DPACKAGE_VERSION= \" {s} \" " , . { info . dotversion } ) ,
b . fmt ( " -DPACKAGE_STRING= \" vfs {s} \" " , . { info . dotversion } ) ,
" -DPACKAGE_BUGREPORT= \" \" " ,
" -DPACKAGE_URL= \" \" " ,
" -DBUILD_VFS=1 " ,
/ / forTcl9 vfs . c guards < sys / stat . h > behind HAVE_SYS_STAT_H and needs the
/ / COMPLETE Tcl_StatBuf - see the include - order shim below .
" -DHAVE_SYS_STAT_H=1 " ,
" -DTCL_CFG_OPTIMIZED=1 " ,
" -DUSE_TCL_STUBS=1 " ,
" -DZIPFS_BUILD=1 " ,
@ -101,24 +127,39 @@ pub fn build_tclvfs(comptime tcldir: []const u8, comptime subdir: []const u8, b:
} ) ;
if ( target . result . os . tag = = . windows ) {
try flags . appendSlice ( & . {
" -static-libgcc " ,
/ / forTcl9 export guard is lowercase BUILD_vfs ( " should be undefined for
/ / Unix " per vfs.c) - the trunk-era BUILD_VFS spelling no longer matches.
/ / ( - static - libgcc dropped from the cflags : a link - stage arg clang
/ / reports unused at compile - zig manages runtime - lib linkage anyway . )
" -DBUILD_vfs=/**/ " ,
} ) ;
}
/ / - DBUILD_VFS only on windows ? value ?
var sources = std . array_list . Managed ( [ ] const u8 ) . init ( b . allocator ) ;
try sources . append ( subdir + + " /generic/vfs.c " ) ;
lib . root_module . addIncludePath ( b . path ( subdir ) ) ;
lib . root_module . addIncludePath ( b . path ( subdir + + " /generic " ) ) ;
lib . root_module . addIncludePath ( b . path ( tcldir + + " /generic " ) ) ;
lib . root_module . addIncludePath ( b . path ( tcldir + + " /generic " ) ) ;
if ( target . result . os . tag = = . windows ) {
lib . root_module . addIncludePath ( b . path ( tcldir + + " /win " ) ) ;
} else {
lib . root_module . addIncludePath ( b . path ( tcldir + + " /unix " ) ) ;
}
lib . root_module . addCSourceFiles ( . {
. files = sources . items ,
/ / Include - order shim ( overlay TU - source trees never written ) : under zig ' s
/ / mingw headers ' __stat64 ' is a MACRO for _stat64 ( _mingw_stat64 . h , pulled in
/ / by < sys / stat . h > ) ; tcl . h ' s ' typedef struct __stat64 Tcl_StatBuf ' parsed
/ / BEFORE that include binds a raw forever - incomplete __stat64 tag and the
/ / forTcl9 vfs . c ' s direct Tcl_StatBuf field accesses then fail . Compiling a
/ / generated TU that includes < sys / stat . h > first makes the macro visible when
/ / tcl . h parses . ( MSVC has a real struct __stat64 tag - upstream never sees
/ / this . A - include flag would be simpler but trips zig cc ' s CacheCheckFailed . )
const wf_shim = b . addWriteFiles ( ) ;
const vfs_shim = wf_shim . add ( " vfs_statorder_shim.c " ,
\\/* generated include-order shim - see build_tclvfs_shared.zig */
\\#include <sys/stat.h>
\\#include "vfs.c"
\\
) ;
lib . root_module . addCSourceFile ( . {
. file = vfs_shim ,
. flags = flags . items ,
} ) ;
@ -127,16 +168,15 @@ pub fn build_tclvfs(comptime tcldir: []const u8, comptime subdir: []const u8, b:
lib . root_module . addWin32ResourceFile ( . {
. file = b . path ( subdir + + " /win/tclvfs.rc " ) ,
. flags = & . {
" -DPACKAGE_MAJOR=1 " ,
" -DPACKAGE_MINOR=4 " ,
" -DPACKAGE_VERSION= " + + tclvfs_dotversion ,
" -DDOTVERSION= " + + tclvfs_dotversion ,
" -DCOMMAVERSION= " + + tclvfs_dotversion ,
" -DVERSION= " + + tclvfs_nodotversion ,
b . fmt ( " -DPACKAGE_MAJOR={s} " , . { info . major } ) ,
b . fmt ( " -DPACKAGE_MINOR={s} " , . { info . minor } ) ,
b . fmt ( " -DPACKAGE_VERSION={s} " , . { info . dotversion } ) ,
b . fmt ( " -DDOTVERSION={s} " , . { info . dotversion } ) ,
b . fmt ( " -DCOMMAVERSION={s} " , . { info . dotversion } ) ,
b . fmt ( " -DVERSION={s} " , . { info . nodots } ) ,
} ,
} ) ; / / ignored for non - windows targets
/ / COMMAVERSION ? ? ? VERSION ? ? ?
b . installArtifact ( lib ) ;
return lib ; / / static library
return lib ;
}