You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
161 lines
7.3 KiB
161 lines
7.3 KiB
const std = @import("std"); |
|
const common = @import("../build_common.zig"); |
|
|
|
//build_tclvfs86 - tclvfs (TRUNK, 1.4.2 era) loadable extension for the 8.6 |
|
//suite (G-099). Forked from suite_tcl90/build_tclvfs/build_tclvfs_shared.zig |
|
//(duplication-with-a-note posture) with the 8.6 differences: |
|
// - the dll is BUILT UNDER THE TCL8 TEA-NMAKE NAME (vfs<nodots>t.dll, e.g |
|
// vfs142t.dll - rules.vc PRJLIBNAME8 with PROJECT=vfs, SUFX 't' kept on a |
|
// tcl86 host): the configured library/vfs.tcl.in loads @PKG_LIB_FILE8@ |
|
// with NO explicit init symbol, so Tcl's load-time package-name guessing |
|
// derives the _Init name from the file's alpha prefix - 'vfs...' guesses |
|
// Vfs_Init (correct); a 'tclvfs...' spelling guesses Tclvfs_Init and |
|
// fails. @PKG_LIB_FILE9@ is still substituted so the script is complete. |
|
// - the 9.0 fork's ZIPFS_BUILD / TCL_WIDE_INT_TYPE defines dropped (9-isms). |
|
// - trunk vfs.c uses the same lowercase BUILD_vfs export guard as forTcl9 |
|
// (verified in the staged tree), so the guard define carries over. |
|
//The include-order shim carries over: 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 (8.6 tcl.h uses the same typedef under |
|
//_WIN64). Compiling a generated TU that includes <sys/stat.h> first makes the |
|
//macro visible when tcl.h parses. |
|
|
|
pub const TclvfsInfo = struct { |
|
dotversion: []const u8, //e.g "1.4.2" |
|
nodots: []const u8, //e.g "142" |
|
dll_file: []const u8, //the tcl8-named dll this suite builds, e.g "vfs142t.dll" |
|
dll9_file: []const u8, //tcl9 spelling for template substitution completeness |
|
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("vfs{s}t.dll", .{nodots}), |
|
.dll9_file = b.fmt("tcl9vfs{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. |
|
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@", info.dotversion); |
|
t = common.replaceAll(b, t, "@PKG_LIB_FILE9@", info.dll9_file); |
|
t = common.replaceAll(b, t, "@PKG_LIB_FILE8@", info.dll_file); |
|
return t; |
|
} |
|
|
|
//install the tclvfs script package (lib/vfs<ver>) into the prefix - the two |
|
//generated configure-products, the library scripts + template dir copied, and |
|
//the dll alongside (vfs.tcl loads it from its own dir via ::vfs::self). |
|
pub fn install_tclvfs_package(comptime subdir: []const u8, b: *std.Build, tclvfs_compile: *std.Build.Step.Compile) !void { |
|
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, |
|
.install_subdir = pkgsub, |
|
.include_extensions = &.{".tcl"}, |
|
}); |
|
b.getInstallStep().dependOn(&install_scripts.step); |
|
//template dir wholesale (carries non-.tcl support files such as tclIndex) |
|
const install_template = b.addInstallDirectory(.{ |
|
.source_dir = b.path(subdir ++ "/library/template"), |
|
.install_dir = .prefix, |
|
.install_subdir = b.fmt("{s}/template", .{pkgsub}), |
|
}); |
|
b.getInstallStep().dependOn(&install_template.step); |
|
const wf = b.addWriteFiles(); |
|
inline for (.{ |
|
.{ "library/vfs.tcl.in", "vfs.tcl" }, |
|
.{ "pkgIndex.tcl.in", "pkgIndex.tcl" }, |
|
}) |pair| { |
|
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, b.fmt("{s}/{s}", .{ pkgsub, info.dll_file })); |
|
b.getInstallStep().dependOn(&dll_inst.step); |
|
} |
|
|
|
pub fn build_tclvfs86(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 { |
|
const info = versionInfo(b, subdir); |
|
const lib = b.addLibrary(.{ |
|
.linkage = .dynamic, |
|
.name = b.fmt("vfs{s}t", .{info.nodots}), |
|
.root_module = b.createModule(.{ |
|
.target = target, |
|
.optimize = optimize, |
|
}), |
|
}); |
|
var flags = std.array_list.Managed([]const u8).init(b.allocator); |
|
defer flags.deinit(); |
|
try flags.appendSlice(&.{ "-Wall", "-O3", "-fomit-frame-pointer" }); |
|
try flags.appendSlice(&.{ |
|
"-DPACKAGE_NAME=\"vfs\"", |
|
"-DPACKAGE_TARNAME=\"vfs\"", |
|
b.fmt("-DPACKAGE_VERSION=\"{s}\"", .{info.dotversion}), |
|
b.fmt("-DPACKAGE_STRING=\"vfs {s}\"", .{info.dotversion}), |
|
"-DPACKAGE_BUGREPORT=\"\"", |
|
"-DPACKAGE_URL=\"\"", |
|
//vfs.c guards <sys/stat.h> paths 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", |
|
}); |
|
if (target.result.os.tag == .windows) { |
|
try flags.appendSlice(&.{ |
|
"-DBUILD_vfs=/**/", |
|
}); |
|
} |
|
|
|
lib.root_module.addIncludePath(b.path(subdir)); |
|
lib.root_module.addIncludePath(b.path(subdir ++ "/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")); |
|
} |
|
//Include-order shim (overlay TU - source trees never written): see the |
|
//header comment for the __stat64 macro-vs-tag story. |
|
const wf_shim = b.addWriteFiles(); |
|
const vfs_shim = wf_shim.add("vfs_statorder_shim.c", |
|
\\/* generated include-order shim - see build_tclvfs86.zig */ |
|
\\#include <sys/stat.h> |
|
\\#include "vfs.c" |
|
\\ |
|
); |
|
lib.root_module.addCSourceFile(.{ |
|
.file = vfs_shim, |
|
.flags = flags.items, |
|
}); |
|
|
|
lib.root_module.linkLibrary(stublib); |
|
lib.root_module.link_libc = true; |
|
lib.root_module.addWin32ResourceFile(.{ |
|
.file = b.path(subdir ++ "/win/tclvfs.rc"), |
|
.flags = &.{ |
|
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 |
|
|
|
return lib; |
|
}
|
|
|