Skip to content

Commit 932db5c

Browse files
committed
feat: add an option to link as a shared library
Fixes the linking code, and adds a new option to the build function to link Ziglua as a shared library rather than as a static library. This is for the use case of creating shared modules to require at runtime in Lua.
1 parent 942afe8 commit 932db5c

File tree

3 files changed

+36
-33
lines changed

3 files changed

+36
-33
lines changed

build.zig

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ const LuaVersion = enum {
88
lua_52,
99
lua_53,
1010
lua_54,
11-
lua_jit,
11+
// lua_jit,
1212
};
1313

1414
fn libPath(version: LuaVersion) []const u8 {
@@ -17,8 +17,6 @@ fn libPath(version: LuaVersion) []const u8 {
1717
.lua_52 => "src/ziglua-5.2/lib.zig",
1818
.lua_53 => "src/ziglua-5.3/lib.zig",
1919
.lua_54 => "src/ziglua-5.4/lib.zig",
20-
else => unreachable,
21-
// .lua_jit => "src/ziglua-jit/lib.zig",
2220
};
2321
}
2422

@@ -30,9 +28,8 @@ pub fn build(b: *Builder) void {
3028
.lua_52 => "src/ziglua-5.2/tests.zig",
3129
.lua_53 => "src/ziglua-5.3/tests.zig",
3230
.lua_54 => "src/ziglua-5.4/tests.zig",
33-
else => unreachable,
3431
});
35-
link(b, tests, libPath(version), .{ .use_apicheck = true, .version = version });
32+
link(b, tests, .{ .use_apicheck = true, .version = version });
3633

3734
const test_step = b.step("test", "Run ziglua library tests");
3835
test_step.dependOn(&tests.step);
@@ -47,47 +44,49 @@ const Options = struct {
4744
use_apicheck: bool = false,
4845
/// Defines the Lua version to build and link
4946
version: LuaVersion = .lua_54,
47+
48+
shared: bool = false,
5049
};
5150

5251
pub fn linkAndPackage(b: *Builder, step: *LibExeObjStep, options: Options) std.build.Pkg {
53-
const lib_path = libPath(options.version);
54-
link(b, step, lib_path, options);
52+
link(b, step, options);
5553

54+
const lib_path = libPath(options.version);
5655
return .{
5756
.name = "ziglua",
5857
.path = .{ .path = std.fs.path.join(b.allocator, &.{ dir(), lib_path }) catch unreachable },
5958
};
6059
}
6160

6261
// TODO: expose the link and package steps separately for advanced use cases?
63-
fn link(b: *Builder, step: *LibExeObjStep, lib_path: []const u8, options: Options) void {
64-
const lib = buildLua(b, step, lib_path, options);
62+
fn link(b: *Builder, step: *LibExeObjStep, options: Options) void {
63+
const lib = buildLua(b, step, options);
6564
step.linkLibrary(lib);
6665
step.linkLibC();
6766
}
6867

6968
// TODO: how to test all versions? May need a make/help script to test all
7069
// versions separately because there might be name collisions
71-
fn buildLua(b: *Builder, step: *LibExeObjStep, lib_path: []const u8, options: Options) *LibExeObjStep {
70+
fn buildLua(b: *Builder, step: *LibExeObjStep, options: Options) *LibExeObjStep {
7271
const lib_dir = switch (options.version) {
7372
.lua_51 => "lib/lua-5.1.5/src/",
7473
.lua_52 => "lib/lua-5.2.4/src/",
7574
.lua_53 => "lib/lua-5.3.6/src/",
7675
.lua_54 => "lib/lua-5.4.4/src/",
77-
else => unreachable,
78-
// .lua_jit => "lib/lua-5.4.4/src/",
7976
};
8077

81-
const absolute_lib_path = std.fs.path.join(b.allocator, &.{ dir(), lib_path }) catch unreachable;
82-
const lib = b.addStaticLibrary("lua", absolute_lib_path);
83-
lib.setBuildMode(step.build_mode);
84-
lib.setTarget(step.target);
78+
const lua = brk: {
79+
if (options.shared) break :brk b.addSharedLibrary("lua", null, .unversioned);
80+
break :brk b.addStaticLibrary("lua", null);
81+
};
82+
lua.setBuildMode(step.build_mode);
83+
lua.setTarget(step.target);
8584

8685
const apicheck = step.build_mode == .Debug and options.use_apicheck;
8786

8887
step.addIncludeDir(std.fs.path.join(b.allocator, &.{ dir(), lib_dir }) catch unreachable);
8988

90-
const target = (std.zig.system.NativeTargetInfo.detect(b.allocator, lib.target) catch unreachable).target;
89+
const target = (std.zig.system.NativeTargetInfo.detect(b.allocator, step.target) catch unreachable).target;
9190

9291
const flags = [_][]const u8{
9392
// Standard version used in Lua Makefile
@@ -110,16 +109,14 @@ fn buildLua(b: *Builder, step: *LibExeObjStep, lib_path: []const u8, options: Op
110109
.lua_52 => &lua_52_source_files,
111110
.lua_53 => &lua_53_source_files,
112111
.lua_54 => &lua_54_source_files,
113-
else => unreachable,
114-
// .lua_jit => &lua_jit_source_files,
115112
};
116113

117114
for (lua_source_files) |file| {
118115
const path = std.fs.path.join(b.allocator, &.{ dir(), lib_dir, file }) catch unreachable;
119-
step.addCSourceFile(path, &flags);
116+
lua.addCSourceFile(path, &flags);
120117
}
121118

122-
return lib;
119+
return lua;
123120
}
124121

125122
const lua_51_source_files = [_][]const u8 {

docs.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,12 +126,14 @@ pub fn build(b: *Builder) void {
126126

127127
This makes the `ziglua` package available in your project. Access with `@import("ziglua")`.
128128

129-
There are currently two options that can be passed in the third argument to `ziglua.link()`:
129+
There are currently three options that can be passed in the third argument to `ziglua.link()`:
130130

131131
* `.use_apicheck`: defaults to **false**. When **true** defines the macro `LUA_USE_APICHECK` in debug builds. See [The C API docs](https://www.lua.org/manual/5.4/manual.html#4) for more information on this macro.
132132

133133
* `.version`: Set the Lua version to build and embed. Defaults to `.lua_54`. Possible values are `.lua_51`, `.lua_52`, `.lua_53`, and `.lua_54`.
134134

135+
* `.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).
136+
135137
For example, here is a `ziglua.linkAndPackage()` call that enables api check and embeds Lua 5.2:
136138

137139
```

readme.md

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,36 @@
1-
# ziglua
1+
# Ziglua
22

3-
A Zig library that provides a lightweight wrapper around the [Lua C API](https://www.lua.org/manual/5.4/manual.html#4) to embed the Lua virtual machine into your Zig programs. Currently tracks the latest Lua version (5.4.4).
3+
A Zig library that provides a complete yet lightweight wrapper around the [Lua C API](https://www.lua.org/manual/5.4/manual.html#4). Ziglua currently supports the latest releases of Lua 5.1, 5.2, 5.3, and 5.4.
44

5-
Like the Lua C API, the ziglua API "emphasizes flexibility and simplicity... common tasks may involve several API calls. This may be boring, but it gives us full control over all the details" (_Programming In Lua 4th Edition_). However, ziglua takes advantage of Zig's features to make it easier and safer to interact with the Lua API.
5+
Ziglua offers two approaches as a library:
6+
* **embedded**: used to embed the Lua VM in a Zig program
7+
* **module**: used to create shared Lua modules that can be loaded at runtime in other Lua-based software
8+
9+
Like the Lua C API, the Ziglua API "emphasizes flexibility and simplicity... common tasks may involve several API calls. This may be boring, but it gives us full control over all the details" (_Programming In Lua 4th Edition_). However, Ziglua takes advantage of Zig's features to make it easier and safer to interact with the Lua API.
610

711
* [Docs](https://github.com/natecraddock/ziglua/blob/master/docs.md)
812
* [Examples](https://github.com/natecraddock/ziglua/blob/master/docs.md#examples)
913

10-
## Why use ziglua?
14+
## Why use Ziglua?
1115

12-
In a nutshell, ziglua is a simple wrapper around the C API you would get by using Zig's `@cImport()`. ziglua aims to mirror the [Lua C API](https://www.lua.org/manual/5.4/manual.html#4) as closely as possible, while improving ergonomics using Zig's features. For example:
16+
In a nutshell, Ziglua is a simple wrapper around the C API you would get by using Zig's `@cImport()`. Ziglua aims to mirror the [Lua C API](https://www.lua.org/manual/5.4/manual.html#4) as closely as possible, while improving ergonomics using Zig's features. For example:
1317

1418
* Zig error unions to require failure state handling
1519
* Null-terminated slices instead of C strings
1620
* Type-checked enums for parameters and return values
1721
* Compiler-enforced checking of optional pointers
1822
* More precise types (e.g. `bool` instead of `int`)
1923

20-
While there are some helper functions added to complement the C API, ziglua aims to remain low-level. This allows full access to the Lua API through a layer of Zig's improvements over C.
24+
While there are some helper functions added to complement the C API, Ziglua aims to remain low-level. This allows full access to the Lua API through a layer of Zig's improvements over C.
2125

2226
If you want something higher-level (but doesn't expose the full API), perhaps try [zoltan](https://github.com/ranciere/zoltan).
2327

2428
## Getting Started
2529

26-
Adding ziglua to your project is easy. First add this repo as a git submodule, or copy the source into your repo. Then add the following to your `build.zig` file (assuming cloned/copied into a `lib/` subdirectory):
30+
Adding Ziglua to your project is easy. First add this repo as a git submodule, or copy the source into your repo. Then add the following to your `build.zig` file (assuming cloned/copied into a `lib/` subdirectory):
2731

2832
```zig
29-
// use the path to the ziglua build.zig file
33+
// use the path to the Ziglua build.zig file
3034
const ziglua = @import("lib/ziglua/build.zig");
3135
3236
pub fn build(b: *Builder) void {
@@ -56,13 +60,13 @@ pub fn main() anyerror!void {
5660
}
5761
```
5862

59-
See [docs.md](https://github.com/natecraddock/ziglua/blob/master/docs.md) for documentation and detailed [examples](https://github.com/natecraddock/ziglua/blob/master/docs.md#examples) of using ziglua.
63+
See [docs.md](https://github.com/natecraddock/ziglua/blob/master/docs.md) for documentation and detailed [examples](https://github.com/natecraddock/ziglua/blob/master/docs.md#examples) of using Ziglua.
6064

6165
## Status
6266

63-
Nearly all functions, types, and constants in the C API have been wrapped in ziglua. Only a few exceptions have been made when the function doesn't make sense in Zig (like functions using `va_list`).
67+
Nearly all functions, types, and constants in the C API have been wrapped in Ziglua. Only a few exceptions have been made when the function doesn't make sense in Zig (like functions using `va_list`).
6468

65-
All functions have been type checked, but only the standard C API has been tested fully. ziglua should be relatively stable and safe to use now, but is still new and changing frequently.
69+
All functions have been type checked, but only the standard C API has been tested fully. Ziglua should be relatively stable and safe to use now, but is still new and changing frequently.
6670

6771
## Acknowledgements
6872

0 commit comments

Comments
 (0)