From 322117be936642210e4d27fc5e4807e970dbecbe Mon Sep 17 00:00:00 2001 From: Robbie Lyman Date: Sat, 14 Dec 2024 14:14:09 -0500 Subject: [PATCH 1/2] feat: add system integration to use system Lua or LuaJIT library enable this by using `--system` or `-fsys=lua` --- build.zig | 126 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/build.zig b/build.zig index 6e585fa..33e4683 100644 --- a/build.zig +++ b/build.zig @@ -8,24 +8,27 @@ const lua_setup = @import("build/lua.zig"); const luau_setup = @import("build/luau.zig"); const luajit_setup = @import("build/luajit.zig"); -pub fn build(b: *Build) void { +pub fn build(b: *Build) !void { // Remove the default install and uninstall steps b.top_level_steps = .{}; const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + const system = b.systemIntegrationOption("lua", .{ .default = false }); const lang = b.option(Language, "lang", "Lua language version to build") orelse .lua54; const shared = b.option(bool, "shared", "Build shared library instead of static") orelse false; 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; - if (lang == .luau and shared) { + if (lang == .luau and (shared or system)) { std.debug.panic("Luau does not support compiling or loading shared modules", .{}); } // Zig module const ziglua = b.addModule("ziglua", .{ .root_source_file = b.path("src/lib.zig"), + .target = if (system) target else null, + .optimize = if (system) optimize else null, }); // Expose build configuration to the ziglua module @@ -39,45 +42,71 @@ pub fn build(b: *Build) void { ziglua.addCMacro("LUA_VECTOR_SIZE", b.fmt("{}", .{vector_size})); } - const upstream = b.dependency(@tagName(lang), .{}); - - const lib = switch (lang) { - .luajit => luajit_setup.configure(b, target, optimize, upstream, shared), - .luau => luau_setup.configure(b, target, optimize, upstream, luau_use_4_vector), - else => lua_setup.configure(b, target, optimize, upstream, lang, shared), - }; - - // Expose the Lua artifact, and get an install step that header translation can refer to - const install_lib = b.addInstallArtifact(lib, .{}); - b.getInstallStep().dependOn(&install_lib.step); - - switch (lang) { - .luau => { - ziglua.addIncludePath(upstream.path("Common/include")); - ziglua.addIncludePath(upstream.path("Compiler/include")); - ziglua.addIncludePath(upstream.path("Ast/include")); - ziglua.addIncludePath(upstream.path("VM/include")); - }, - else => ziglua.addIncludePath(upstream.path("src")), + if (!system) { + const upstream = b.dependency(@tagName(lang), .{}); + + const lib = switch (lang) { + .luajit => luajit_setup.configure(b, target, optimize, upstream, shared), + .luau => luau_setup.configure(b, target, optimize, upstream, luau_use_4_vector), + else => lua_setup.configure(b, target, optimize, upstream, lang, shared), + }; + + // Expose the Lua artifact, and get an install step that header translation can refer to + const install_lib = b.addInstallArtifact(lib, .{}); + b.getInstallStep().dependOn(&install_lib.step); + + switch (lang) { + .luau => { + ziglua.addIncludePath(upstream.path("Common/include")); + ziglua.addIncludePath(upstream.path("Compiler/include")); + ziglua.addIncludePath(upstream.path("Ast/include")); + ziglua.addIncludePath(upstream.path("VM/include")); + }, + else => ziglua.addIncludePath(upstream.path("src")), + } + + ziglua.linkLibrary(lib); + + // lib must expose all headers included by these root headers + const c_header_path = switch (lang) { + .luajit => b.path("include/luajit_all.h"), + .luau => b.path("include/luau_all.h"), + else => b.path("include/lua_all.h"), + }; + const c_headers = b.addTranslateC(.{ + .root_source_file = c_header_path, + .target = target, + .optimize = optimize, + }); + c_headers.addIncludeDir(b.getInstallPath(install_lib.h_dir.?, "")); + c_headers.step.dependOn(&install_lib.step); + ziglua.addImport("c", c_headers.createModule()); + } else { + // system is true + const c_header_path = switch (lang) { + .luajit => b.path("include/luajit_all.h"), + .luau => unreachable, + else => b.path("include/lua_all.h"), + }; + const c_headers = b.addTranslateC(.{ + .root_source_file = c_header_path, + .target = target, + .optimize = optimize, + }); + try addIncludePathsForSystem(b, c_headers, switch (lang) { + .luajit => "luajit", + .luau => unreachable, + else => "lua", + }); + const c_module = c_headers.createModule(); + ziglua.addImport("c", c_module); + switch (lang) { + .luajit => ziglua.linkSystemLibrary("luajit", .{}), + .luau => unreachable, + else => ziglua.linkSystemLibrary("lua", .{}), + } } - ziglua.linkLibrary(lib); - - // lib must expose all headers included by these root headers - const c_header_path = switch (lang) { - .luajit => b.path("include/luajit_all.h"), - .luau => b.path("include/luau_all.h"), - else => b.path("include/lua_all.h"), - }; - const c_headers = b.addTranslateC(.{ - .root_source_file = c_header_path, - .target = target, - .optimize = optimize, - }); - c_headers.addIncludeDir(b.getInstallPath(install_lib.h_dir.?, "")); - c_headers.step.dependOn(&install_lib.step); - ziglua.addImport("c", c_headers.createModule()); - // Tests const tests = b.addTest(.{ .root_source_file = b.path("src/tests.zig"), @@ -150,3 +179,22 @@ pub fn build(b: *Build) void { const define_step = b.step("define", "Generate definitions.lua file"); define_step.dependOn(&run_def_exe.step); } + +fn addIncludePathsForSystem(b: *std.Build, translate_c: *std.Build.Step.TranslateC, name: []const u8) !void { + var code: u8 = undefined; + const stdout = if (b.runAllowFail(&.{ + "pkg-config", + name, + "--cflags-only-I", + }, &code, .Ignore)) |stdout| stdout else |err| switch (err) { + error.ProcessTerminated => return error.PkgConfigCrashed, + error.ExecNotSupported => return error.PkgConfigFailed, + error.ExitCodeFailure => return error.PkgConfigFailed, + error.FileNotFound => return error.PkgConfigNotInstalled, + else => return err, + }; + var arg_it = std.mem.tokenizeAny(u8, stdout, " \r\n\t"); + while (arg_it.next()) |arg| if (std.mem.startsWith(u8, arg, "-I")) { + translate_c.addIncludeDir(arg[2..]); + }; +} From f55457778f0622c4c88fe85f8445f9df0e629c60 Mon Sep 17 00:00:00 2001 From: Robbie Lyman Date: Sat, 14 Dec 2024 14:24:32 -0500 Subject: [PATCH 2/2] fix: force use of pkg_config (since we're already failing with it by using `try`) --- build.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.zig b/build.zig index 33e4683..27312b4 100644 --- a/build.zig +++ b/build.zig @@ -101,9 +101,9 @@ pub fn build(b: *Build) !void { const c_module = c_headers.createModule(); ziglua.addImport("c", c_module); switch (lang) { - .luajit => ziglua.linkSystemLibrary("luajit", .{}), + .luajit => ziglua.linkSystemLibrary("luajit", .{ .use_pkg_config = .force }), .luau => unreachable, - else => ziglua.linkSystemLibrary("lua", .{}), + else => ziglua.linkSystemLibrary("lua", .{ .use_pkg_config = .force }), } }