const std = @import("std"); 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 { const wrapfilecmd = b.addExecutable(.{ .name = "wrapfiletofile", .root_module = b.createModule(.{ .root_source_file = b.path("tools/wrapfiletofile.zig"), .target = b.graph.host, }), }); const uuidcmd_step = b.addRunArtifact(wrapfilecmd); uuidcmd_step.addArgs(&.{ "-prefix", "#define THREAD_VERSION_UUID \\", "-prefixnl", "1", "-input", }); uuidcmd_step.addFileArg(b.path(subdir ++ "/manifest.uuid")); uuidcmd_step.addArg("-output"); const threaduuid_file = uuidcmd_step.addOutputFileArg("threadUuid.h"); //var interp: []const []const u8 = undefined; ////note we determine the interp based on the machine running the build - not the target //if (builtin.os.tag == .windows) { // interp = &.{ // "wrapfiletofile.cmd", // }; //} else { // interp = &.{ // "bash", //explicitly use bash. Sometimes sh is linked to some other shell such as zsh, or dash (e.g debian,ubuntu) which don't understand substitution syntax like bash and ordinary posix sh do // "wrapfiletofile.cmd", // }; //} //const uuid_cmd = b.addSystemCommand(interp); //uuid_cmd.addArgs(&.{ // "-prefix", // "#define THREAD_VERSION_UUID \\", // "-prefixnl", // "1", // "-input", //}); ////uuid_cmd.addFileArg(.{ .path = b.pathJoin(&.{ b.pathFromRoot(""), "..", "tcl" ++ tcl_version, "manifest.uuid" }) }); //uuid_cmd.addFileArg(b.path(subdir ++ "/manifest.Uuid")); //uuid_cmd.addArg("-output"); //const tcluuid_file1 = uuid_cmd.addOutputFileArg("threadUuid.h"); //(G-102: the former addUpdateSourceFiles copy of threadUuid.h into the checkout //was removed - the include-dir overlay below is the operative delivery and source //trees are never written.) const lib = b.addLibrary(.{ .linkage = .dynamic, .name = "tcl9thread301", .root_module = b.createModule(.{ .target = target, .optimize = optimize, }), }); //lib.step.dependOn(&wf_uuidh.step); var flags = std.array_list.Managed([]const u8).init(b.allocator); defer flags.deinit(); //try flags.appendSlice(&.{ "-Wall", "-O2", "-fomit-frame-pointer", "-DNDEBUG" }); try flags.appendSlice(&.{ "-Wall", "-O3", "-fomit-frame-pointer" }); try flags.appendSlice(&.{ "-DPACKAGE_NAME=\"thread\"", "-DPACKAGE_TARNAME=\"thread\"", "-DPACKAGE_VERSION=\"3.0.1\"", "-DPACKAGE_STRING=\"thread 3.0.1\"", "-DPACKAGE_BUGREPORT=\"\"", "-DPACKAGE_URL=\"\"", "-DTCL_CFG_OPTIMIZED=1", "-DUSE_TCL_STUBS=1", "-DZIPFS_BUILD=1", "-DTCL_WIDE_INT_TYPE=long long", //"-DHAVE_STDIO_H=1", //"-DHAVE_STDLIB_H=1", //"-DHAVE_STRING_H=1", "-DHAVE_INTTYPES_H=1", //"-DHAVE_STDINT_H=1", //"-DHAVE_STRINGS_H=1", //"-DHAVE_SYS_STAT_H=1", //"-DHAVE_SYS_TYPES_H=1", //"-DHAVE_FILE_OFFSET_BITS=64", //"-DHAVE_STRUCT_STAT64=1", //"-DHAVE_LSEEK64=1", "-static-libgcc", }); //BUILD_ needs to be defined for windows if (target.result.os.tag == .windows) { try flags.appendSlice(&.{ "-DBUILD_thread=/**/", }); } var tclthread_sources = std.array_list.Managed([]const u8).init(b.allocator); try tclthread_sources.append(subdir ++ "/generic/threadNs.c"); try tclthread_sources.append(subdir ++ "/generic/threadCmd.c"); try tclthread_sources.append(subdir ++ "/generic/threadSvCmd.c"); try tclthread_sources.append(subdir ++ "/generic/threadSpCmd.c"); try tclthread_sources.append(subdir ++ "/generic/threadPoolCmd.c"); try tclthread_sources.append(subdir ++ "/generic/psGdbm.c"); try tclthread_sources.append(subdir ++ "/generic/psLmdb.c"); try tclthread_sources.append(subdir ++ "/generic/threadSvListCmd.c"); try tclthread_sources.append(subdir ++ "/generic/threadSvKeyListCmd.c"); try tclthread_sources.append(subdir ++ "/generic/tclXkeylist.c"); //if (target.result.os.tag == .windows) { // lib.root_module.linkSystemLibrary("advapi32", .{}); //crypt //} lib.root_module.addIncludePath(b.path(subdir)); lib.root_module.addIncludePath(b.path(subdir ++ "/generic")); //generated threadUuid.h: current thread trunk #includes it (upstream makefiles //generate it into their build dir); using the generator's output dir as an include //path also gives the compile its dependency on the generation step. lib.root_module.addIncludePath(threaduuid_file.dirname()); lib.root_module.addIncludePath(b.path(tcldir ++ "/generic")); //todo - fix lib.root_module.addCSourceFiles(.{ .files = tclthread_sources.items, .flags = flags.items, }); lib.root_module.linkLibrary(stublib); lib.root_module.link_libc = true; //thread.rc overlay (G-102): the version resource needs tcl.h; the recipe //historically carried that as an edit of the checkout's thread.rc - now the rc //is compiled from an overlay copy with the include inserted (and the historical //relative-path edit normalized if a previously-mutated tree is staged), with //tcl.h resolving via the include paths. Source trees are never written. var threadrc_content: []const u8 = common.readSourceFile(b, subdir ++ "/win/thread.rc"); const legacy_edit = "#include \"../../tcl905/generic/tcl.h\""; if (std.mem.indexOf(u8, threadrc_content, legacy_edit) != null) { threadrc_content = common.replaceAll(b, threadrc_content, legacy_edit, "#include \"tcl.h\""); } else if (std.mem.indexOf(u8, threadrc_content, "#include \"tcl.h\"") == null) { threadrc_content = common.replaceAll(b, threadrc_content, "#include ", "#include \n#include \"tcl.h\""); } const wf_threadrc = b.addWriteFiles(); const threadrc_overlay = wf_threadrc.add("thread.rc", threadrc_content); lib.root_module.addWin32ResourceFile(.{ .file = threadrc_overlay, .flags = &.{ "-DPACKAGE_MAJOR=3", "-DPACKAGE_MINOR=0", "-DPACKAGE_VERSION=3.0b2", }, .include_paths = &.{ b.path(tcldir ++ "/generic"), b.path(subdir ++ "/win"), }, }); //ignored for non-windows targets b.installArtifact(lib); //G-102: pkgIndex.tcl so 'package require Thread' resolves against the prefix //(punkshell runtests -jobs and codethread need it) - formerly a suite.tcl //post-build block. 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"); b.getInstallStep().dependOn(&pkgidx_install.step); return lib; }