diff --git a/build.zig b/build.zig index a6507eb..8d28f74 100644 --- a/build.zig +++ b/build.zig @@ -5,73 +5,21 @@ pub fn build(b: *std.Build) !void { const optimize = b.standardOptimizeOption(.{}); const is_wasm_freestanding = target.result.cpu.arch.isWasm() and target.result.os.tag == .freestanding; + // --- Rust C ABI & Pre-built via temporal-rs subpackage --- // + const libtemporal_src = b.dependency("libtemporal_src", .{ + .target = target, + .optimize = optimize, + }); + // --- Zig Module: temporalz --- // const mod = b.addModule("temporalz", .{ .root_source_file = b.path("src/root.zig"), .target = target, .optimize = optimize, }); - mod.addIncludePath(b.path("src/stubs/c_headers")); - - // --- Rust C ABI: temporal_capi --- // - const temporal_rs_git = b.dependency("temporal_rs", .{ - .target = target, - .optimize = optimize, - }); - mod.addIncludePath(temporal_rs_git.path("temporal_capi/bindings/c")); - - // -- Pre-built library support for temporal_capi --- // - const libtemporal_prebuilt = b.lazyDependency("libtemporal_prebuilt", .{}); - - // --- Rust C ABI: Library --- // - { - // Determine target triple string for pre-built library lookup - const arch_str = @tagName(target.result.cpu.arch); - const os_str = @tagName(target.result.os.tag); - const abi = target.result.abi; - const target_triple = if (abi == .none) - b.fmt("{s}-{s}", .{ arch_str, os_str }) - else - b.fmt("{s}-{s}-{s}", .{ arch_str, os_str, @tagName(abi) }); - const lib_name = if (target.result.os.tag == .windows and abi == .msvc) - "temporal_capi.lib" - else - "libtemporal_capi.a"; - - // Check if pre-built library exists in downloaded artifact - const prebuilt_lib_path = b.fmt("{s}/{s}", .{ target_triple, lib_name }); - - var prebuilt_lib_file: ?std.Build.LazyPath = null; - if (libtemporal_prebuilt) |dep| { - const lib_file_candidate = dep.path(prebuilt_lib_path); - const lib_full_path = lib_file_candidate.getPath(b); - if (std.Io.Dir.cwd().openFile(b.graph.io, lib_full_path, .{})) |lib_check_file| { - lib_check_file.close(b.graph.io); - prebuilt_lib_file = lib_file_candidate; - } else |_| {} - } - - if (prebuilt_lib_file) |lib_file| { - // Use pre-built library (no Rust compiler needed) - mod.addObjectFile(lib_file); - } else { - // Build from source using the local temporal-rs package - const libtemporal_src = b.dependency("libtemporal_src", .{ - .target = target, - .optimize = optimize, - }); - mod.addImport("temporal_rs", libtemporal_src.module("temporal_rs")); - } - - // --- Rust Misc Deps --- // - if (target.result.os.tag == .windows) mod.linkSystemLibrary("userenv", .{}); - const unwind_stubs = b.addLibrary(.{ .linkage = .static, .name = "unwind_stubs", .root_module = b.createModule(.{ - .root_source_file = b.path("src/stubs/unwind.zig"), - .target = target, - .optimize = optimize, - }) }); - mod.linkLibrary(unwind_stubs); - } + + // Use the comprehensive mod from the package + mod.addImport("temporal_rs", libtemporal_src.module("temporal_rs")); // --- Zig Executable: temporalz --- // const exe_root = if (is_wasm_freestanding) diff --git a/build.zig.zon b/build.zig.zon index e2e61fd..1b682a3 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -4,17 +4,9 @@ .fingerprint = 0xd8d79d59acc4faae, .minimum_zig_version = "0.16.0-dev.2860+9c5460316", .dependencies = .{ - .temporal_rs = .{ - .url = "git+https://github.com/boa-dev/temporal#v0.1.2", - .hash = "N-V-__8AANlkNAB77Z946lqp-lgp2qSsOBDADValZC86PhB-", - }, .libtemporal_src = .{ .path = "pkg/temporal-rs", }, - .libtemporal_prebuilt = .{ - .url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.1.2/temporal-rs-libs.tar.gz", - .hash = "N-V-__8AALzG2AXNSf7E7iuZWx7SrTN0PICWYwnu2kIDlf-w", - }, }, .paths = .{ "build.zig", diff --git a/pkg/temporal-rs/build.zig b/pkg/temporal-rs/build.zig index 65df9a1..1d1ef49 100644 --- a/pkg/temporal-rs/build.zig +++ b/pkg/temporal-rs/build.zig @@ -1,31 +1,9 @@ const std = @import("std"); -const build_crab = @import("build_crab"); pub fn build(b: *std.Build) !void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - // --- Rust Crate Build --- // - const build_dir = build_crab.addCargoBuild( - b, - .{ - .manifest_path = b.path("Cargo.toml"), - .cargo_args = if (optimize == .Debug) &.{} else &.{"--release"}, - }, - .{ - .target = target, - .optimize = .ReleaseSafe, - }, - ); - - const lib_name = if (target.result.os.tag == .windows and target.result.abi == .msvc) - "temporal_capi.lib" - else - "libtemporal_capi.a"; - - const lib_file = build_dir.path(b, lib_name); - - // --- Install Step (for publishing) --- // const arch_str = @tagName(target.result.cpu.arch); const os_str = @tagName(target.result.os.tag); const abi = target.result.abi; @@ -34,8 +12,50 @@ pub fn build(b: *std.Build) !void { else b.fmt("{s}-{s}-{s}", .{ arch_str, os_str, @tagName(abi) }); - const install_lib = b.addInstallFile(lib_file, b.fmt("lib/{s}/{s}", .{ target_triple, lib_name })); - b.getInstallStep().dependOn(&install_lib.step); + const lib_name = if (target.result.os.tag == .windows and abi == .msvc) + "temporal_capi.lib" + else + "libtemporal_capi.a"; + + const prebuilt_lib_path = b.fmt("{s}/{s}", .{ target_triple, lib_name }); + + // --- Pre-built resolution --- // + const libtemporal_prebuilt = b.lazyDependency("libtemporal_prebuilt", .{}); + var prebuilt_lib_file: ?std.Build.LazyPath = null; + + if (libtemporal_prebuilt) |dep| { + const lib_file_candidate = dep.path(prebuilt_lib_path); + const lib_full_path = lib_file_candidate.getPath(b); + if (std.Io.Dir.cwd().openFile(b.graph.io, lib_full_path, .{})) |lib_check_file| { + lib_check_file.close(b.graph.io); + prebuilt_lib_file = lib_file_candidate; + } else |_| {} + } + + var selected_lib_file: std.Build.LazyPath = undefined; + if (prebuilt_lib_file) |lib_file| { + // std.debug.print("Using pre-built temporal_capi library from downloaded artifact at: {s}\n", .{prebuilt_lib_path}); + selected_lib_file = lib_file; + } else { + // std.debug.print("building from source: {s}\n", .{prebuilt_lib_path}); + const build_crab = @import("build_crab"); + const build_dir = build_crab.addCargoBuild( + b, + .{ + .manifest_path = b.path("Cargo.toml"), + .cargo_args = if (optimize == .Debug) &.{} else &.{"--release"}, + }, + .{ + .target = target, + .optimize = .ReleaseSafe, + }, + ); + selected_lib_file = build_dir.path(b, lib_name); + + // --- Install Step (for publishing) --- // + const install_lib = b.addInstallFile(selected_lib_file, b.fmt("lib/{s}/{s}", .{ target_triple, lib_name })); + b.getInstallStep().dependOn(&install_lib.step); + } // --- Zig Module --- // const mod = b.addModule("temporal_rs", .{ @@ -43,48 +63,24 @@ pub fn build(b: *std.Build) !void { .target = target, .optimize = optimize, }); - mod.addObjectFile(lib_file); - // --- Steps: Build all platforms --- // - { - const build_lib_step = b.step("lib", "Build libraries for all common platforms"); + // Add Headers + const temporal_rs_git = b.dependency("temporal_rs", .{ + .target = target, + .optimize = optimize, + }); + mod.addIncludePath(temporal_rs_git.path("temporal_capi/bindings/c")); + mod.addIncludePath(b.path("src/stubs/c_headers")); - inline for (platforms) |p| { - const query = try std.Build.parseTargetQuery(.{ .arch_os_abi = p }); - const platform_target = b.resolveTargetQuery(query); + // Add Object/Library + mod.addObjectFile(selected_lib_file); - const platform_build_dir = build_crab.addCargoBuild( - b, - .{ - .manifest_path = b.path("Cargo.toml"), - .cargo_args = &.{"--release"}, - }, - .{ - .target = platform_target, - .optimize = .ReleaseSafe, - }, - ); - - const platform_lib_name = if (platform_target.result.os.tag == .windows and platform_target.result.abi == .msvc) - "temporal_capi.lib" - else - "libtemporal_capi.a"; - - const install_platform_lib = b.addInstallFile( - platform_build_dir.path(b, platform_lib_name), - b.fmt("lib/{s}/{s}", .{ p, platform_lib_name }), - ); - build_lib_step.dependOn(&install_platform_lib.step); - } - } + // --- Rust Misc Deps --- // + if (target.result.os.tag == .windows) mod.linkSystemLibrary("userenv", .{}); + const unwind_stubs = b.addLibrary(.{ .linkage = .static, .name = "unwind_stubs", .root_module = b.createModule(.{ + .root_source_file = b.path("src/stubs/unwind.zig"), + .target = target, + .optimize = optimize, + }) }); + mod.linkLibrary(unwind_stubs); } - -const platforms = [_][]const u8{ - "aarch64-macos", - "x86_64-macos", - "aarch64-linux-gnu", - "x86_64-linux-gnu", - "x86_64-windows-gnu", - "aarch64-windows-gnu", - "wasm32-freestanding", -}; diff --git a/pkg/temporal-rs/build.zig.zon b/pkg/temporal-rs/build.zig.zon index 3149d50..7546a5c 100644 --- a/pkg/temporal-rs/build.zig.zon +++ b/pkg/temporal-rs/build.zig.zon @@ -4,6 +4,14 @@ .fingerprint = 0x4e9d7c35d5fc40c0, .minimum_zig_version = "0.16.0-dev.2565+684032671", .dependencies = .{ + .temporal_rs = .{ + .url = "git+https://github.com/boa-dev/temporal#v0.1.2", + .hash = "N-V-__8AANlkNAB77Z946lqp-lgp2qSsOBDADValZC86PhB-", + }, + .libtemporal_prebuilt = .{ + .url = "https://github.com/nurulhudaapon/temporalz/releases/download/v0.1.2/temporal-rs-libs.tar.gz", + .hash = "N-V-__8AALzG2AXNSf7E7iuZWx7SrTN0PICWYwnu2kIDlf-w", + }, .build_crab = .{ .url = "git+https://github.com/nurulhudaapon/build.crab?ref=zig-dev#1aabc836472d318e9756a43b17853aadc4599800", .hash = "build_crab-0.2.1-U0id_2LFAABPaq1t9eBZ3p0aA87c-HkKZPYCrCVcgvt6", diff --git a/pkg/temporal-rs/src/root.zig b/pkg/temporal-rs/src/root.zig index ad727f9..1103436 100644 --- a/pkg/temporal-rs/src/root.zig +++ b/pkg/temporal-rs/src/root.zig @@ -1 +1,20 @@ -// Empty root file for zig module +pub const c = @cImport({ + @cInclude("AnyCalendarKind.h"); + @cInclude("Calendar.h"); + @cInclude("Duration.h"); + @cInclude("ErrorKind.h"); + @cInclude("I128Nanoseconds.h"); + @cInclude("Instant.h"); + @cInclude("OwnedRelativeTo.h"); + @cInclude("ParsedDate.h"); + @cInclude("ParsedDateTime.h"); + @cInclude("ParsedZonedDateTime.h"); + @cInclude("PlainDate.h"); + @cInclude("PlainDateTime.h"); + @cInclude("PlainMonthDay.h"); + @cInclude("PlainTime.h"); + @cInclude("PlainYearMonth.h"); + @cInclude("RelativeTo.h"); + @cInclude("TimeZone.h"); + @cInclude("ZonedDateTime.h"); +}); diff --git a/src/stubs/c_headers/assert.h b/pkg/temporal-rs/src/stubs/c_headers/assert.h similarity index 100% rename from src/stubs/c_headers/assert.h rename to pkg/temporal-rs/src/stubs/c_headers/assert.h diff --git a/src/stubs/c_headers/stdbool.h b/pkg/temporal-rs/src/stubs/c_headers/stdbool.h similarity index 100% rename from src/stubs/c_headers/stdbool.h rename to pkg/temporal-rs/src/stubs/c_headers/stdbool.h diff --git a/src/stubs/c_headers/stddef.h b/pkg/temporal-rs/src/stubs/c_headers/stddef.h similarity index 100% rename from src/stubs/c_headers/stddef.h rename to pkg/temporal-rs/src/stubs/c_headers/stddef.h diff --git a/src/stubs/c_headers/stdint.h b/pkg/temporal-rs/src/stubs/c_headers/stdint.h similarity index 100% rename from src/stubs/c_headers/stdint.h rename to pkg/temporal-rs/src/stubs/c_headers/stdint.h diff --git a/src/stubs/c_headers/stdio.h b/pkg/temporal-rs/src/stubs/c_headers/stdio.h similarity index 100% rename from src/stubs/c_headers/stdio.h rename to pkg/temporal-rs/src/stubs/c_headers/stdio.h diff --git a/src/stubs/unwind.zig b/pkg/temporal-rs/src/stubs/unwind.zig similarity index 100% rename from src/stubs/unwind.zig rename to pkg/temporal-rs/src/stubs/unwind.zig diff --git a/src/abi.zig b/src/abi.zig index 2a0b1bf..5ea375f 100644 --- a/src/abi.zig +++ b/src/abi.zig @@ -1,25 +1,6 @@ const std = @import("std"); -pub const c = @cImport({ - @cInclude("AnyCalendarKind.h"); - @cInclude("Calendar.h"); - @cInclude("Duration.h"); - @cInclude("ErrorKind.h"); - @cInclude("I128Nanoseconds.h"); - @cInclude("Instant.h"); - @cInclude("OwnedRelativeTo.h"); - @cInclude("ParsedDate.h"); - @cInclude("ParsedDateTime.h"); - @cInclude("ParsedZonedDateTime.h"); - @cInclude("PlainDate.h"); - @cInclude("PlainDateTime.h"); - @cInclude("PlainMonthDay.h"); - @cInclude("PlainTime.h"); - @cInclude("PlainYearMonth.h"); - @cInclude("RelativeTo.h"); - @cInclude("TimeZone.h"); - @cInclude("ZonedDateTime.h"); -}); +pub const c = @import("temporal_rs").c; pub const to_string_rounding_options_auto: c.ToStringRoundingOptions = .{ .precision = .{ .is_minute = false, .precision = toOption(c.OptionU8, null) }, diff --git a/update_zon.js b/update_zon.js new file mode 100644 index 0000000..5e1c7f0 --- /dev/null +++ b/update_zon.js @@ -0,0 +1,15 @@ +const fs = require('fs'); + +const app_zon = fs.readFileSync('build.zig.zon', 'utf8'); +function extractDep(name) { + const regex = new RegExp(`\\.${name}\\s*=\\s*\\{([\\s\\S]*?)\\},`); + return app_zon.match(regex)[0]; +} + +const p1 = extractDep('temporal_rs'); +const p2 = extractDep('libtemporal_prebuilt'); + +const pkg_zon = fs.readFileSync('pkg/temporal-rs/build.zig.zon', 'utf8'); +const new_pkg_zon = pkg_zon.replace(' .dependencies = .{', ` .dependencies = .{\n ${p1}\n ${p2}`); + +fs.writeFileSync('pkg/temporal-rs/build.zig.zon', new_pkg_zon);