mirror of
https://github.com/ziex-dev/ziex.git
synced 2026-07-21 02:59:36 -06:00
338 lines
13 KiB
Zig
338 lines
13 KiB
Zig
const std = @import("std");
|
|
const zx_build_zon = @import("build.zig.zon");
|
|
|
|
pub fn build(b: *std.Build) void {
|
|
const target = b.standardTargetOptions(.{});
|
|
const optimize = b.standardOptimizeOption(.{});
|
|
|
|
// --- ZX Core ---
|
|
const mod = b.addModule("zx", .{
|
|
.root_source_file = b.path("src/root.zig"),
|
|
.target = target,
|
|
});
|
|
const httpz_dep = b.dependency("httpz", .{ .target = target, .optimize = optimize });
|
|
mod.addImport("httpz", httpz_dep.module("httpz"));
|
|
|
|
const options = b.addOptions();
|
|
options.addOption([]const u8, "version_string", zx_build_zon.version);
|
|
options.addOption([]const u8, "description", zx_build_zon.description);
|
|
options.addOption([]const u8, "repository", zx_build_zon.repository);
|
|
mod.addOptions("zx_info", options);
|
|
|
|
// --- ZX CLI (Transpiler, Exporter, Dev Server) ---
|
|
// const transformjs_build_step = buildRustLibs(b, target, optimize);
|
|
const zli_dep = b.dependency("zli", .{ .target = target, .optimize = optimize });
|
|
const exe = b.addExecutable(.{
|
|
.name = "zx",
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path("src/main.zig"),
|
|
.target = target,
|
|
.optimize = optimize,
|
|
.imports = &.{
|
|
.{ .name = "zx", .module = mod },
|
|
.{ .name = "httpz", .module = httpz_dep.module("httpz") },
|
|
.{ .name = "zli", .module = zli_dep.module("zli") },
|
|
},
|
|
}),
|
|
});
|
|
|
|
// linkRustLibs(b, exe, transformjs_build_step, optimize);
|
|
b.installArtifact(exe);
|
|
|
|
// --- Steps: Run ---
|
|
const run_step = b.step("run", "Run the app");
|
|
const run_cmd = b.addRunArtifact(exe);
|
|
run_step.dependOn(&run_cmd.step);
|
|
run_cmd.step.dependOn(b.getInstallStep());
|
|
if (b.args) |args| run_cmd.addArgs(args);
|
|
|
|
// --- ZX Site (Docs, Example, sample) ---
|
|
const is_zx_docsite = b.option(bool, "zx-docsite", "Build the ZX docsite") orelse false;
|
|
if (is_zx_docsite) setupZxDocSite(b, exe, mod, .{
|
|
.name = "zx_site",
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path("site/main.zig"),
|
|
.target = target,
|
|
.optimize = optimize,
|
|
.imports = &.{
|
|
.{ .name = "zx", .module = mod },
|
|
},
|
|
}),
|
|
});
|
|
|
|
// --- Steps: Test ---
|
|
const mod_tests = b.addTest(.{ .root_module = mod });
|
|
const run_mod_tests = b.addRunArtifact(mod_tests);
|
|
|
|
const exe_tests = b.addTest(.{ .root_module = exe.root_module });
|
|
const run_exe_tests = b.addRunArtifact(exe_tests);
|
|
|
|
const testing_mod = b.createModule(.{
|
|
.root_source_file = b.path("test/main.zig"),
|
|
.target = target,
|
|
.optimize = optimize,
|
|
.imports = &.{
|
|
.{ .name = "zx", .module = mod },
|
|
},
|
|
});
|
|
const testing_mod_tests = b.addTest(.{
|
|
.root_module = testing_mod,
|
|
.test_runner = .{ .path = b.path("test/runner.zig"), .mode = .simple },
|
|
});
|
|
const run_transpiler_tests = b.addRunArtifact(testing_mod_tests);
|
|
|
|
const test_step = b.step("test", "Run tests");
|
|
test_step.dependOn(&run_mod_tests.step);
|
|
test_step.dependOn(&run_exe_tests.step);
|
|
test_step.dependOn(&run_transpiler_tests.step);
|
|
|
|
// --- Cross-compilation targets for releases ---
|
|
const release_targets = [_]struct {
|
|
name: []const u8,
|
|
target: std.Target.Query,
|
|
}{
|
|
.{ .name = "linux-x64", .target = .{ .cpu_arch = .x86_64, .os_tag = .linux } },
|
|
.{ .name = "linux-aarch64", .target = .{ .cpu_arch = .aarch64, .os_tag = .linux } },
|
|
.{ .name = "macos-x64", .target = .{ .cpu_arch = .x86_64, .os_tag = .macos } },
|
|
.{ .name = "macos-aarch64", .target = .{ .cpu_arch = .aarch64, .os_tag = .macos } },
|
|
.{ .name = "windows-x64", .target = .{ .cpu_arch = .x86_64, .os_tag = .windows } },
|
|
.{ .name = "windows-aarch64", .target = .{ .cpu_arch = .aarch64, .os_tag = .windows } },
|
|
};
|
|
|
|
const release_step = b.step("release", "Build release binaries for all targets");
|
|
|
|
for (release_targets) |release_target| {
|
|
const resolved_target = b.resolveTargetQuery(release_target.target);
|
|
const release_exe = b.addExecutable(.{
|
|
.name = "zx",
|
|
.root_module = b.createModule(.{
|
|
.root_source_file = b.path("src/main.zig"),
|
|
.target = resolved_target,
|
|
.optimize = .ReleaseFast,
|
|
.imports = &.{
|
|
.{ .name = "zx", .module = mod },
|
|
.{ .name = "httpz", .module = httpz_dep.module("httpz") },
|
|
.{ .name = "zli", .module = zli_dep.module("zli") },
|
|
},
|
|
}),
|
|
});
|
|
|
|
// const release_transformjs_build_step = buildRustLibs(b, resolved_target, .ReleaseFast);
|
|
// linkRustLibs(b, release_exe, release_transformjs_build_step, .ReleaseFast);
|
|
|
|
const exe_ext = if (resolved_target.result.os.tag == .windows) ".exe" else "";
|
|
const install_release = b.addInstallArtifact(release_exe, .{
|
|
.dest_sub_path = b.fmt("release/zx-{s}{s}", .{ release_target.name, exe_ext }),
|
|
});
|
|
|
|
const target_step = b.step(b.fmt("release-{s}", .{release_target.name}), b.fmt("Build release binary for {s}", .{release_target.name}));
|
|
target_step.dependOn(&install_release.step);
|
|
release_step.dependOn(&install_release.step);
|
|
}
|
|
}
|
|
|
|
pub fn setup(b: *std.Build, options: std.Build.ExecutableOptions) void {
|
|
const target = options.root_module.resolved_target;
|
|
const optimize = options.root_module.optimize;
|
|
|
|
const zx_dep = b.dependency("zx", .{ .target = target, .optimize = optimize });
|
|
|
|
// --- ZX Transpilation ---
|
|
const transpile_cmd = b.addRunArtifact(zx_dep.artifact("zx"));
|
|
// const transpile_cmd = b.addSystemCommand(&.{"zx"}); // ZX CLI must installed and in the PATH
|
|
transpile_cmd.addArg("transpile");
|
|
transpile_cmd.addArg(b.pathJoin(&.{"site"}));
|
|
transpile_cmd.addArg("--outdir");
|
|
const outdir = transpile_cmd.addOutputDirectoryArg("site");
|
|
transpile_cmd.expectExitCode(0);
|
|
|
|
// --- ZX File Cache Invalidator ---
|
|
const site_path = b.path("site").getPath3(b, &transpile_cmd.step);
|
|
var site_dir = site_path.root_dir.handle.openDir(site_path.subPathOrDot(), .{ .iterate = true }) catch @panic("OOM");
|
|
var itd = site_dir.walk(transpile_cmd.step.owner.allocator) catch @panic("OOM");
|
|
defer itd.deinit();
|
|
while (itd.next() catch @panic("OOM")) |entry| {
|
|
switch (entry.kind) {
|
|
.directory => {},
|
|
.file => {
|
|
const entry_path = site_path.join(transpile_cmd.step.owner.allocator, entry.path) catch @panic("OOM");
|
|
transpile_cmd.addFileInput(b.path(entry_path.sub_path));
|
|
},
|
|
else => continue,
|
|
}
|
|
}
|
|
|
|
// --- ZX Site Main Executable ---
|
|
const exe = b.addExecutable(options);
|
|
|
|
exe.root_module.addImport("zx", zx_dep.module("zx"));
|
|
var imports = std.array_list.Managed(std.Build.Module.Import).init(b.allocator);
|
|
var import_it = exe.root_module.import_table.iterator();
|
|
while (import_it.next()) |entry| {
|
|
imports.append(.{ .name = entry.key_ptr.*, .module = entry.value_ptr.* }) catch @panic("OOM");
|
|
}
|
|
exe.root_module.addAnonymousImport("zx_meta", .{
|
|
.root_source_file = outdir.path(b, "meta.zig"),
|
|
.imports = imports.items,
|
|
});
|
|
|
|
exe.step.dependOn(&transpile_cmd.step);
|
|
b.installArtifact(exe);
|
|
|
|
// --- Steps: Serve ---
|
|
const serve_step = b.step("serve", "Run the Zx website");
|
|
const serve_cmd = b.addRunArtifact(exe);
|
|
serve_cmd.step.dependOn(&transpile_cmd.step);
|
|
serve_cmd.step.dependOn(b.getInstallStep());
|
|
serve_step.dependOn(&serve_cmd.step);
|
|
if (b.args) |args| serve_cmd.addArgs(args);
|
|
}
|
|
|
|
fn setupZxDocSite(b: *std.Build, zx_exe: *std.Build.Step.Compile, zx_mod: *std.Build.Module, options: std.Build.ExecutableOptions) void {
|
|
var site_outdir = std.fs.cwd().openDir("site/.zx", .{}) catch null;
|
|
if (site_outdir == null) return;
|
|
site_outdir.?.close();
|
|
|
|
// --- ZX Transpilation ---
|
|
const transpile_cmd = b.addRunArtifact(zx_exe);
|
|
transpile_cmd.addArg("transpile");
|
|
transpile_cmd.addArg(b.pathJoin(&.{"site"}));
|
|
transpile_cmd.addArg("--outdir");
|
|
const outdir = b.path("site/.zx");
|
|
transpile_cmd.addArg("site/.zx");
|
|
transpile_cmd.expectExitCode(0);
|
|
|
|
// --- ZX File Cache Invalidator ---
|
|
const site_path = b.path("site").getPath3(b, &transpile_cmd.step);
|
|
var site_dir = site_path.root_dir.handle.openDir(site_path.subPathOrDot(), .{ .iterate = true }) catch @panic("OOM");
|
|
var itd = site_dir.walk(transpile_cmd.step.owner.allocator) catch @panic("OOM");
|
|
defer itd.deinit();
|
|
while (itd.next() catch @panic("OOM")) |entry| {
|
|
switch (entry.kind) {
|
|
.directory => {},
|
|
.file => {
|
|
const entry_path = site_path.join(transpile_cmd.step.owner.allocator, entry.path) catch @panic("OOM");
|
|
transpile_cmd.addFileInput(b.path(entry_path.sub_path));
|
|
},
|
|
else => continue,
|
|
}
|
|
}
|
|
|
|
// --- ZX Site Main Executable ---
|
|
const exe = b.addExecutable(options);
|
|
|
|
exe.root_module.addImport("zx", zx_mod);
|
|
var imports = std.array_list.Managed(std.Build.Module.Import).init(b.allocator);
|
|
var import_it = exe.root_module.import_table.iterator();
|
|
while (import_it.next()) |entry| {
|
|
imports.append(.{ .name = entry.key_ptr.*, .module = entry.value_ptr.* }) catch @panic("OOM");
|
|
}
|
|
exe.root_module.addAnonymousImport("zx_meta", .{
|
|
.root_source_file = outdir.path(b, "meta.zig"),
|
|
.imports = imports.items,
|
|
});
|
|
|
|
exe.step.dependOn(&transpile_cmd.step);
|
|
b.installArtifact(exe);
|
|
|
|
// --- Steps: Run Docs ---
|
|
const run_docs_step = b.step("serve", "Run the site (docs, example, sample)");
|
|
const run_docs_cmd = b.addRunArtifact(exe);
|
|
run_docs_step.dependOn(&run_docs_cmd.step);
|
|
run_docs_cmd.step.dependOn(b.getInstallStep());
|
|
if (b.args) |args| run_docs_cmd.addArgs(args);
|
|
}
|
|
|
|
/// Build the TransformJS Rust library as a C dynamic library
|
|
/// Returns a build step that must be completed before linking
|
|
fn buildRustLibs(
|
|
b: *std.Build,
|
|
target: std.Build.ResolvedTarget,
|
|
optimize: std.builtin.OptimizeMode,
|
|
) *std.Build.Step {
|
|
const transformjs_dir = "packages/transformjs";
|
|
|
|
// Build the Rust library using cargo
|
|
const cargo_build = b.addSystemCommand(&.{ "cargo", "build", "--lib" });
|
|
cargo_build.setCwd(b.path(transformjs_dir));
|
|
|
|
if (optimize == .ReleaseFast or optimize == .ReleaseSafe or optimize == .ReleaseSmall) {
|
|
cargo_build.addArg("--release");
|
|
}
|
|
|
|
// Convert Zig target to Rust target triple for cross-compilation
|
|
const rust_target = zigTargetToRustTarget(target.result);
|
|
if (rust_target) |triple| {
|
|
cargo_build.addArg("--target");
|
|
cargo_build.addArg(triple);
|
|
}
|
|
|
|
return &cargo_build.step;
|
|
}
|
|
|
|
/// Convert Zig target to Rust target triple
|
|
/// Returns null for native target (cargo default)
|
|
fn zigTargetToRustTarget(target: std.Target) ?[]const u8 {
|
|
const builtin = @import("builtin");
|
|
const is_native = target.os.tag == builtin.target.os.tag and
|
|
target.cpu.arch == builtin.target.cpu.arch;
|
|
|
|
if (is_native) {
|
|
return null; // Use cargo default (native target)
|
|
}
|
|
|
|
// Convert to Rust target triple format
|
|
return switch (target.os.tag) {
|
|
.linux => switch (target.cpu.arch) {
|
|
.x86_64 => "x86_64-unknown-linux-gnu",
|
|
.aarch64 => "aarch64-unknown-linux-gnu",
|
|
else => null,
|
|
},
|
|
.macos => switch (target.cpu.arch) {
|
|
.x86_64 => "x86_64-apple-darwin",
|
|
.aarch64 => "aarch64-apple-darwin",
|
|
else => null,
|
|
},
|
|
.windows => switch (target.cpu.arch) {
|
|
.x86_64 => "x86_64-pc-windows-msvc",
|
|
.aarch64 => "aarch64-pc-windows-msvc",
|
|
else => null,
|
|
},
|
|
else => null, // Unsupported OS
|
|
};
|
|
}
|
|
|
|
/// Link TransformJS Rust library to an executable
|
|
fn linkRustLibs(
|
|
b: *std.Build,
|
|
exe: *std.Build.Step.Compile,
|
|
build_step: *std.Build.Step,
|
|
optimize: std.builtin.OptimizeMode,
|
|
) void {
|
|
const target = exe.root_module.resolved_target orelse return;
|
|
const transformjs_dir = "packages/transformjs";
|
|
|
|
exe.step.dependOn(build_step);
|
|
exe.addIncludePath(b.path(transformjs_dir));
|
|
|
|
// Determine library directory - cargo puts cross-compiled libs in target/<triple>/<profile>
|
|
const rust_target_triple = zigTargetToRustTarget(target.result);
|
|
const lib_dir = if (optimize == .ReleaseFast or optimize == .ReleaseSafe or optimize == .ReleaseSmall)
|
|
if (rust_target_triple) |triple|
|
|
b.pathJoin(&.{ transformjs_dir, "target", triple, "release" })
|
|
else
|
|
b.pathJoin(&.{ transformjs_dir, "target", "release" })
|
|
else if (rust_target_triple) |triple|
|
|
b.pathJoin(&.{ transformjs_dir, "target", triple, "debug" })
|
|
else
|
|
b.pathJoin(&.{ transformjs_dir, "target", "debug" });
|
|
|
|
exe.addLibraryPath(b.path(lib_dir));
|
|
exe.linkSystemLibrary("transformjs");
|
|
exe.linkSystemLibrary("c");
|
|
// Only link 'dl' on Unix-like systems (not Windows)
|
|
if (target.result.os.tag != .windows) {
|
|
exe.linkSystemLibrary("dl");
|
|
}
|
|
}
|