From 8236cb910bb5e1b38cec3ba4d5694bd649287f91 Mon Sep 17 00:00:00 2001 From: Stevie Hryciw Date: Mon, 20 Feb 2023 20:26:21 -0800 Subject: [PATCH 1/2] Prepare Zig package - Add build.zig.zon - Refactor build.zig to expose module and artifacts by usual means - Add version info to Lua shared/static lib - Define LUA_USE_APICHECK if and only if opitimize=Debug - Pass target and optimize mode to lib - Install headers with lib As it is, `zig build test -Dtarget=...` will create a cross-compiled test executable which cannot be run. This should be fixed, probably by disallowing `-Dtarget` in the test step, or providing a custom test runner. --- .gitignore | 1 + build.zig | 163 +++++++++++++++++++++----------------------------- build.zig.zon | 5 ++ 3 files changed, 73 insertions(+), 96 deletions(-) create mode 100644 build.zig.zon diff --git a/.gitignore b/.gitignore index 3cef7be..e73c965 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ zig-cache/ +zig-out/ diff --git a/build.zig b/build.zig index b2b8776..26c124b 100644 --- a/build.zig +++ b/build.zig @@ -1,7 +1,6 @@ const std = @import("std"); const Build = std.Build; -const CompileStep = std.build.CompileStep; pub const LuaVersion = enum { lua_51, @@ -11,98 +10,48 @@ pub const LuaVersion = enum { // lua_jit, }; -fn libPath(version: LuaVersion) []const u8 { - return switch (version) { - .lua_51 => "src/ziglua-5.1/lib.zig", - .lua_52 => "src/ziglua-5.2/lib.zig", - .lua_53 => "src/ziglua-5.3/lib.zig", - .lua_54 => "src/ziglua-5.4/lib.zig", - }; -} - pub fn build(b: *Build) void { - const version = b.option(LuaVersion, "version", "lua version to test") orelse .lua_54; - - const tests = b.addTest(.{ - .root_source_file = switch (version) { - .lua_51 => .{ .path = "src/ziglua-5.1/tests.zig" }, - .lua_52 => .{ .path = "src/ziglua-5.2/tests.zig" }, - .lua_53 => .{ .path = "src/ziglua-5.3/tests.zig" }, - .lua_54 => .{ .path = "src/ziglua-5.4/tests.zig" }, + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + const lua_version = b.option(LuaVersion, "version", "Lua API and library version") orelse .lua_54; + const shared = b.option(bool, "shared", "Build shared library instead of static") orelse false; + + const lib_opts = .{ + .name = "lua", + .target = target, + .optimize = optimize, + .version = switch (lua_version) { + .lua_51 => std.builtin.Version{ .major = 5, .minor = 1, .patch = 5 }, + .lua_52 => std.builtin.Version{ .major = 5, .minor = 2, .patch = 4 }, + .lua_53 => std.builtin.Version{ .major = 5, .minor = 3, .patch = 6 }, + .lua_54 => std.builtin.Version{ .major = 5, .minor = 4, .patch = 4 }, }, - }); - link(b, tests, .{ .use_apicheck = true, .version = version }); - - const test_step = b.step("test", "Run ziglua tests"); - test_step.dependOn(&tests.step); -} - -fn dir() []const u8 { - return std.fs.path.dirname(@src().file) orelse "."; -} - -pub const Options = struct { - /// Defines the macro LUA_USE_APICHECK in debug builds - use_apicheck: bool = false, - /// Defines the Lua version to build and link - version: LuaVersion = .lua_54, - - shared: bool = false, -}; - -pub fn compileAndCreateModule(b: *Build, step: *CompileStep, options: Options) *std.build.Module { - link(b, step, options); - - const lib_path = libPath(options.version); - return b.createModule(.{ - .source_file = .{ .path = std.fs.path.join(b.allocator, &.{ dir(), lib_path }) catch unreachable }, - }); -} - -// TODO: expose the link and package steps separately for advanced use cases? -fn link(b: *Build, step: *CompileStep, options: Options) void { - const lua = buildLua(b, step, options); - step.linkLibrary(lua); -} - -// TODO: how to test all versions? May need a make/help script to test all -// versions separately because there might be name collisions -fn buildLua(b: *Build, step: *CompileStep, options: Options) *CompileStep { - const lib_dir = switch (options.version) { - .lua_51 => "lib/lua-5.1.5/src/", - .lua_52 => "lib/lua-5.2.4/src/", - .lua_53 => "lib/lua-5.3.6/src/", - .lua_54 => "lib/lua-5.4.4/src/", }; - - const lua = brk: { - if (options.shared) break :brk b.addSharedLibrary(.{ - .name = "lua", - .target = step.target, - .optimize = step.optimize, - }); - - break :brk b.addStaticLibrary(.{ - .name = "lua", - .target = step.target, - .optimize = step.optimize, - }); + const lib = if (shared) + b.addSharedLibrary(lib_opts) + else + b.addStaticLibrary(lib_opts); + const lib_dir = switch (lua_version) { + .lua_51 => "lib/lua-5.1.5/src", + .lua_52 => "lib/lua-5.2.4/src", + .lua_53 => "lib/lua-5.3.6/src", + .lua_54 => "lib/lua-5.4.4/src", }; - - lua.linkLibC(); - - const apicheck = step.optimize == .Debug and options.use_apicheck; - - step.addIncludePath(std.fs.path.join(b.allocator, &.{ dir(), lib_dir }) catch unreachable); - - const target = (std.zig.system.NativeTargetInfo.detect(step.target) catch unreachable).target; - + const lua_source_files = switch (lua_version) { + .lua_51 => &lua_51_source_files, + .lua_52 => &lua_52_source_files, + .lua_53 => &lua_53_source_files, + .lua_54 => &lua_54_source_files, + }; + lib.addIncludePath(lib_dir); + const os_tag = target.os_tag orelse + (std.zig.system.NativeTargetInfo.detect(target) catch unreachable).target.os.tag; const flags = [_][]const u8{ // Standard version used in Lua Makefile "-std=gnu99", // Define target-specific macro - switch (target.os.tag) { + switch (os_tag) { .linux => "-DLUA_USE_LINUX", .macos => "-DLUA_USE_MACOSX", .windows => "-DLUA_USE_WINDOWS", @@ -110,22 +59,44 @@ fn buildLua(b: *Build, step: *CompileStep, options: Options) *CompileStep { }, // Enable api check if desired - if (apicheck) "-DLUA_USE_APICHECK" else "", - }; - - const lua_source_files = switch (options.version) { - .lua_51 => &lua_51_source_files, - .lua_52 => &lua_52_source_files, - .lua_53 => &lua_53_source_files, - .lua_54 => &lua_54_source_files, + if (optimize == .Debug) "-DLUA_USE_APICHECK" else "", }; - for (lua_source_files) |file| { - const path = std.fs.path.join(b.allocator, &.{ dir(), lib_dir, file }) catch unreachable; - lua.addCSourceFile(path, &flags); + const path = std.fs.path.join(b.allocator, &.{ lib_dir, file }) catch unreachable; + lib.addCSourceFile(path, &flags); } + lib.linkLibC(); + lib.install(); + lib.installHeader(b.pathJoin(&.{ lib_dir, "lua.h" }), "lua/lua.h"); + lib.installHeader(b.pathJoin(&.{ lib_dir, "lualib.h" }), "lua/lualib.h"); + lib.installHeader(b.pathJoin(&.{ lib_dir, "lauxlib.h" }), "lua/lauxlib.h"); + + b.addModule(.{ + .name = "ziglua", + .source_file = switch (lua_version) { + .lua_51 => .{ .path = "src/ziglua-5.1/lib.zig" }, + .lua_52 => .{ .path = "src/ziglua-5.2/lib.zig" }, + .lua_53 => .{ .path = "src/ziglua-5.3/lib.zig" }, + .lua_54 => .{ .path = "src/ziglua-5.4/lib.zig" }, + }, + }); + // TODO: mod.addIncludePath(lib_dir); + // https://github.com/ziglang/zig/issues/14719 + + const tests = b.addTest(.{ + .root_source_file = switch (lua_version) { + .lua_51 => .{ .path = "src/ziglua-5.1/tests.zig" }, + .lua_52 => .{ .path = "src/ziglua-5.2/tests.zig" }, + .lua_53 => .{ .path = "src/ziglua-5.3/tests.zig" }, + .lua_54 => .{ .path = "src/ziglua-5.4/tests.zig" }, + }, + .optimize = optimize, + }); + tests.addIncludePath(lib_dir); + tests.linkLibrary(lib); - return lua; + const test_step = b.step("test", "Run ziglua tests"); + test_step.dependOn(&tests.step); } const lua_51_source_files = [_][]const u8{ diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..05b7979 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,5 @@ +.{ + .name = "ziglua", + .description = "Zig bindings for the Lua C API", + .version = "0.1.0", +} From b4e665ba1c3c9adad42951116876b862c8819566 Mon Sep 17 00:00:00 2001 From: Stevie Hryciw Date: Wed, 12 Apr 2023 18:31:29 -0700 Subject: [PATCH 2/2] build: update for API changes --- build.zig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/build.zig b/build.zig index 26c124b..cbc9c34 100644 --- a/build.zig +++ b/build.zig @@ -66,13 +66,12 @@ pub fn build(b: *Build) void { lib.addCSourceFile(path, &flags); } lib.linkLibC(); - lib.install(); + b.installArtifact(lib); lib.installHeader(b.pathJoin(&.{ lib_dir, "lua.h" }), "lua/lua.h"); lib.installHeader(b.pathJoin(&.{ lib_dir, "lualib.h" }), "lua/lualib.h"); lib.installHeader(b.pathJoin(&.{ lib_dir, "lauxlib.h" }), "lua/lauxlib.h"); - b.addModule(.{ - .name = "ziglua", + _ = b.addModule("ziglua", .{ .source_file = switch (lua_version) { .lua_51 => .{ .path = "src/ziglua-5.1/lib.zig" }, .lua_52 => .{ .path = "src/ziglua-5.2/lib.zig" },