From 66991d1cecf10e44cda5a965be228aaaee8fd5c7 Mon Sep 17 00:00:00 2001 From: Robbie Lyman Date: Fri, 30 Oct 2026 18:18:43 -0400 Subject: [PATCH 1/3] fix(build): clean up system_lua option This change removes `-Dsystem_lua` in favor of `-fsys=system_lua`. In order to find Lua, the user should pass `--search-prefix {dir}`, where Lua is installed in `{dir}/lib`. In the happy case that `lua.h` is present as `{dir}/include/lua.h`, no further action is needed. Otherwise (for example if `lua.h` is `{dir}/include/lua/lua.h`), the user should pass the path to the directory containing `lua.h` as an argument to `-Dadditional_system_headers`. If `-fsys=system_lua` is present, the default for `-Dshared` is now `true`. Also, rather than panicking the configure stage, I added `addFail` steps. --- build.zig | 46 ++++++++++++++++++++++------------------- build/include/lua_all.h | 8 +++---- 2 files changed, 29 insertions(+), 25 deletions(-) diff --git a/build.zig b/build.zig index cb635cba..369575bf 100644 --- a/build.zig +++ b/build.zig @@ -42,10 +42,11 @@ pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const system_lua = b.systemIntegrationOption("system_lua", .{ .default = false }); + const lang = b.option(Language, "lang", "Lua language version to build") orelse .lua55; const library_name = b.option([]const u8, "library_name", "Library name for lua linking, default is `lua`") orelse "lua"; - const shared = b.option(bool, "shared", "Build shared library instead of static") orelse false; - const system_lua = b.option(bool, "system_lua", "Use system lua") orelse false; + const shared = b.option(bool, "shared", "Build shared library instead of static") orelse system_lua; const luau_use_4_vector = b.option(bool, "luau_use_4_vector", "Build Luau to use 4-vectors instead of the default 3-vector.") orelse false; const lua_user_h = b.option(Build.LazyPath, "lua_user_h", "Lazy path to user supplied c header file") orelse null; const additional_system_headers = b.option([]Build.LazyPath, "additional_system_headers", "Slice of Lazy paths to additional system headers to include when building Lua") orelse null; @@ -53,14 +54,6 @@ pub fn build(b: *Build) void { // TODO: if the stack traces go well and don't error, maybe remove this. Why would someone not want the stack trace? const api_check_type = b.option(ApiCheckType, "apicheck_type", "Whether apicheck should show stack traces or only abort") orelse .stack_trace; - if (lang == .luau and shared) { - std.debug.panic("Luau does not support compiling or loading shared modules", .{}); - } - - if (lua_user_h != null and (lang == .luajit or lang == .luau)) { - std.debug.panic("Only basic lua supports a user provided header file", .{}); - } - // Zig module const zlua = if (system_lua) b.addModule("zlua", .{ .root_source_file = b.path("src/lib.zig"), @@ -88,10 +81,24 @@ pub fn build(b: *Build) void { .luau => b.path("build/include/luau_all.h"), else => b.path("build/include/lua_all.h"), }; + const link_mode: std.builtin.LinkMode = if (shared) .dynamic else .static; + const system_library_name = switch (lang) { + .lua51 => "lua5.1", + .lua52 => "lua5.2", + .lua53 => "lua5.3", + .lua54 => "lua5.4", + .lua55 => "lua5.5", + .luajit => "luajit", + .luau => "luau", + }; const t: Translator = .init(translate_c, .{ .c_source_file = c_header_path, .target = target, .optimize = optimize, + .link_system_libs = if (system_lua) + &.{.{ .name = system_library_name, .options = .{ .preferred_link_mode = link_mode } }} + else + &.{}, }); // If we've been given additional system headers, add them now. @@ -103,18 +110,8 @@ pub fn build(b: *Build) void { zlua.addImport("c", t.mod); if (system_lua) { - const link_mode: std.builtin.LinkMode = if (shared) .dynamic else .static; - const system_library_name = switch (lang) { - .lua51 => "lua5.1", - .lua52 => "lua5.2", - .lua53 => "lua5.3", - .lua54 => "lua5.4", - .lua55 => "lua5.5", - .luajit => "luajit", - .luau => @panic("luau not supported for system lua"), - }; + if (lang == .luau) b.getInstallStep().dependOn(&b.addFail("luau not supported for system lua").step); zlua.linkSystemLibrary(system_library_name, .{ .preferred_link_mode = link_mode }); - t.mod.linkSystemLibrary(system_library_name, .{ .preferred_link_mode = link_mode }); } else if (b.lazyDependency(@tagName(lang), .{})) |upstream| { const lib = switch (lang) { .luajit => luajit_setup.configure(b, target, optimize, upstream, shared, api_check), @@ -129,6 +126,13 @@ pub fn build(b: *Build) void { }), }; + if (lang == .luau and shared) { + lib.step.dependOn(&b.addFail("Luau does not support compiling or loading shared modules").step); + } + + if (lua_user_h != null and (lang == .luajit or lang == .luau)) { + lib.step.dependOn(&b.addFail("Only basic lua supports a user provided header file").step); + } // Expose the Lua artifact. const install_lib = b.addInstallArtifact(lib, .{}); b.getInstallStep().dependOn(&install_lib.step); diff --git a/build/include/lua_all.h b/build/include/lua_all.h index 873d9992..4e4096eb 100644 --- a/build/include/lua_all.h +++ b/build/include/lua_all.h @@ -1,9 +1,9 @@ #ifndef lua_all_h #define lua_all_h -#include "lua.h" -#include "lualib.h" -#include "lauxlib.h" -#include "luaconf.h" +#include +#include +#include +#include #endif // lua_all_h From 1c00a4d8c52ba4cde067a5a7212257694064b20c Mon Sep 17 00:00:00 2001 From: Robbie Lyman Date: Fri, 30 Oct 2026 21:51:57 -0400 Subject: [PATCH 2/3] fix(build): review fixes --- build.zig | 4 ++-- build/include/lua_all.h | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build.zig b/build.zig index 369575bf..04926845 100644 --- a/build.zig +++ b/build.zig @@ -42,7 +42,7 @@ pub fn build(b: *Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const system_lua = b.systemIntegrationOption("system_lua", .{ .default = false }); + const system_lua = b.systemIntegrationOption("lua", .{ .default = false }); const lang = b.option(Language, "lang", "Lua language version to build") orelse .lua55; const library_name = b.option([]const u8, "library_name", "Library name for lua linking, default is `lua`") orelse "lua"; @@ -131,7 +131,7 @@ pub fn build(b: *Build) void { } if (lua_user_h != null and (lang == .luajit or lang == .luau)) { - lib.step.dependOn(&b.addFail("Only basic lua supports a user provided header file").step); + lib.step.dependOn(&b.addFail("Only standard lua supports a user provided header file").step); } // Expose the Lua artifact. const install_lib = b.addInstallArtifact(lib, .{}); diff --git a/build/include/lua_all.h b/build/include/lua_all.h index 4e4096eb..873d9992 100644 --- a/build/include/lua_all.h +++ b/build/include/lua_all.h @@ -1,9 +1,9 @@ #ifndef lua_all_h #define lua_all_h -#include -#include -#include -#include +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +#include "luaconf.h" #endif // lua_all_h From bdd7bfbc2b7ad45d957d5882ab05973685e92435 Mon Sep 17 00:00:00 2001 From: Robbie Lyman Date: Sat, 31 Oct 2026 13:18:00 -0400 Subject: [PATCH 3/3] readme: document -fsys=lua --- readme.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index b58e8254..fc81d88e 100644 --- a/readme.md +++ b/readme.md @@ -63,7 +63,7 @@ This will compile the Lua C sources and link with your project. You can also use `lua_dep.artifact("lua")` to access the compiled lua library. -There are currently three additional options that can be passed to `b.dependency()`: +There are additional options that can be passed to `b.dependency()`: * `.lang`: Set the Lua language to build and embed. Defaults to `.lua55`. Possible values are `.lua51`, `.lua52`, `.lua53`, `.lua54`, `.lua55`, and `luau`. * `.shared`: Defaults to `false` for embedding in a Zig program. Set to `true` to dynamically link the Lua source code (useful for creating shared modules). @@ -103,6 +103,22 @@ pub fn main(init: std.process.Init) anyerror!void { } ``` +## Using System Lua + +Although Ziglua defaults to compiling the Lua C library with Zig, +you can optionally link against a system Lua instead with the `-fsys=lua` option. +On systems where `pkg-config` can find Lua, this might be all that is necessary. + +If not, two useful commands to `zig build` to be aware of are `--search-prefix` +and `-Dadditional_system_headers`. +The former should be used with a directory containing `lib` and/or `include` as a child directory, +for example `/usr/local` on most Unix-like systems as `--search-prefix /usr/local`. +(Note that `/usr/local` itself is usually found without needing `--search-prefix`.) +Many system distributions put `lua.h` in a folder other than `include`, +for example `/opt/homebrew/include/lua/lua.h` on macOS with Homebrew. +The command `-Dadditional_system_headers=/opt/homebrew/include/lua` helps the `translate_c` module find +`lua.h` in cases where `--search-prefix` alone is not enough. + ## Contributing Please make suggestions, report bugs, and create pull requests. Anyone is welcome to contribute!