Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepare Zig package #13

Merged
merged 2 commits into from
Aug 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
zig-cache/
zig-out/
162 changes: 66 additions & 96 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
const std = @import("std");

const Build = std.Build;
const CompileStep = std.build.CompileStep;

pub const LuaVersion = enum {
lua_51,
Expand All @@ -11,121 +10,92 @@ 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",
else => "-DLUA_USE_POSIX",
},

// 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();
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("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{
Expand Down
5 changes: 5 additions & 0 deletions build.zig.zon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.{
.name = "ziglua",
.description = "Zig bindings for the Lua C API",
.version = "0.1.0",
}