summaryrefslogtreecommitdiff
path: root/build.zig
blob: e675859446a65499cdb30a2584a1cca983556baa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const panto_lib_dep = b.dependency("panto", .{
        .target = target,
        .optimize = optimize,
    });

    // Fetch upstream Lua 5.4.7 (source-only tarball from lua.org).
    // Reproducibility comes from the content-addressed hash in build.zig.zon.
    const lua_src = b.dependency("lua_src", .{});
    const lua = buildLua(b, target, optimize, lua_src);

    // CLI executable
    const exe_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });
    exe_mod.addImport("panto", panto_lib_dep.module("panto"));
    exe_mod.linkLibrary(lua);
    exe_mod.addIncludePath(lua_src.path("src"));

    const exe = b.addExecutable(.{
        .name = "panto",
        .root_module = exe_mod,
    });

    b.installArtifact(exe);

    const run_cmd = b.addRunArtifact(exe);
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);

    // CLI unit tests (minimal — most tests live in libpanto)
    const test_mod = b.createModule(.{
        .root_source_file = b.path("src/main.zig"),
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });
    test_mod.addImport("panto", panto_lib_dep.module("panto"));
    test_mod.linkLibrary(lua);
    test_mod.addIncludePath(lua_src.path("src"));

    const unit_tests = b.addTest(.{
        .name = "panto-tests",
        .root_module = test_mod,
    });

    const run_unit_tests = b.addRunArtifact(unit_tests);
    const test_step = b.step("test", "Run unit tests");
    test_step.dependOn(&run_unit_tests.step);

    // Also run libpanto's own tests as part of `zig build test`
    const lib_test_step = panto_lib_dep.builder.top_level_steps.get("test").?;
    test_step.dependOn(&lib_test_step.step);
}

/// Compile Lua 5.4.7 as a static library against the upstream source tarball.
/// Excludes `lua.c` (interpreter REPL) and `luac.c` (bytecode compiler) — we
/// only want the embedded library.
fn buildLua(
    b: *std.Build,
    target: std.Build.ResolvedTarget,
    optimize: std.builtin.OptimizeMode,
    lua_src: *std.Build.Dependency,
) *std.Build.Step.Compile {
    const lua_mod = b.createModule(.{
        .target = target,
        .optimize = optimize,
        .link_libc = true,
    });

    const cflags = [_][]const u8{
        "-std=gnu99",
        "-Wall",
        "-Wextra",
        "-Wno-unused-parameter",
    };

    lua_mod.addCSourceFiles(.{
        .root = lua_src.path("src"),
        .files = &lua_files,
        .flags = &cflags,
    });

    // Tell Lua which platform features are available. The macros change
    // which `dlopen`/readline/etc. paths Lua compiles in.
    switch (target.result.os.tag) {
        .macos => lua_mod.addCMacro("LUA_USE_MACOSX", ""),
        .linux => lua_mod.addCMacro("LUA_USE_LINUX", ""),
        .freebsd, .netbsd, .openbsd => lua_mod.addCMacro("LUA_USE_POSIX", ""),
        else => {},
    }

    return b.addLibrary(.{
        .name = "lua",
        .linkage = .static,
        .root_module = lua_mod,
    });
}

// Lua 5.4.7 core VM + standard library. Excludes lua.c (interpreter entry
// point) and luac.c (compiler entry point).
const lua_files = [_][]const u8{
    // Core VM
    "lapi.c",     "lcode.c",    "lctype.c",  "ldebug.c", "ldo.c",
    "ldump.c",    "lfunc.c",    "lgc.c",     "llex.c",   "lmem.c",
    "lobject.c",  "lopcodes.c", "lparser.c", "lstate.c", "lstring.c",
    "ltable.c",   "ltm.c",      "lundump.c", "lvm.c",    "lzio.c",
    // Auxiliary + standard library
    "lauxlib.c",  "lbaselib.c", "lcorolib.c", "ldblib.c", "liolib.c",
    "lmathlib.c", "loadlib.c",  "loslib.c",   "lstrlib.c", "ltablib.c",
    "lutf8lib.c", "linit.c",
};