Skip to content
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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
- name: setup zig
uses: mlugg/setup-zig@v2
with:
version: 0.14.1
version: 0.15.2

- name: zig build
run: zig build --summary all
Expand Down
14 changes: 9 additions & 5 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,25 @@ SPDX-FileCopyrightText: © 2025 Mark Delk <jethrodaniel@gmail.com>
SPDX-License-Identifier: MIT
-->

## [Unreleased]
## Unreleased

## [0.3.0] - 2025-07-15
## `0.4.0` - 2026-04-21

- update to zig 0.15.2

## `0.3.0` - 2025-07-15

- update to zig 0.14.1
- update mruby (still 3.4.0)

## [0.2.0] - 2025-06-01
## `0.2.0` - 2025-06-01

- bump to latest mruby (3.4.0), use upstream instead of a fork

## [0.1.1] - 2025-02-20
## `0.1.1` - 2025-02-20

- fix several small issues

## [0.1.0] - 2025-02-19
## `0.1.0` - 2025-02-19

- initial open-source release
15 changes: 7 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ SPDX-License-Identifier: MIT

# mruby.zig

Build [mruby](https://github.com/mruby/mruby) using [zig](https://ziglang.org) `0.14.1` (no rake!).
Build [mruby](https://github.com/mruby/mruby) using [zig](https://ziglang.org) `0.15.2` (no rake!).

## About

Expand All @@ -18,8 +18,6 @@ This project builds MRuby from source, only using Zig.

This means we emulate MRuby's non-trivial Rake-based build process entirely in Zig.

**NOTE**: We only support zig `0.14.1` at the moment.

## Issues

- Non-standard library gems that use any Ruby logic in their `mrbgem.rake` files aren't supported
Expand All @@ -46,6 +44,8 @@ zig-out/bin/
├── mrbtest
├── mruby
└── mruby-strip

1 directory, 8 files
```

See `zig build -h` for information about everything that's available:
Expand Down Expand Up @@ -79,15 +79,14 @@ zig build mrbtest
```
mrbtest - Embeddable Ruby Test

...............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Total: 1647
OK: 1647
...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
Total: 1659
OK: 1659
KO: 0
Crash: 0
Warning: 0
Skip: 0
Time: 1.07 seconds

Time: 1.4 seconds
```

To use `mirb`, `mruby`, etc:
Expand Down
156 changes: 105 additions & 51 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ pub fn build(b: *std.Build) !void {
index += 1;

if (index == diagnostics.getLine()) {
var prefix = std.ArrayList(u8).init(b.allocator);
var prefix = std.array_list.Managed(u8).init(b.allocator);
defer prefix.deinit();

var prefix_index: usize = 0;
Expand All @@ -167,7 +167,7 @@ pub fn build(b: *std.Build) !void {
@panic("failed to parse gems.json");
};

var gems = std.ArrayList(Mgem).init(b.allocator);
var gems = std.array_list.Managed(Mgem).init(b.allocator);
defer gems.deinit();

var builtin_gem_map = std.StringHashMap(Mgem).init(b.allocator);
Expand Down Expand Up @@ -204,13 +204,17 @@ pub fn build(b: *std.Build) !void {

const mrbc_exe = b.addExecutable(.{
.name = "mrbc",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
const host_mrbc_exe = b.addExecutable(.{
.name = "host-mrbc",
.target = b.graph.host,
.optimize = optimize,
.root_module = b.createModule(.{
.target = b.graph.host,
.optimize = optimize,
}),
});
{
for ([_]*std.Build.Step.Compile{
Expand Down Expand Up @@ -246,10 +250,13 @@ pub fn build(b: *std.Build) !void {

//

const mruby_lib = b.addStaticLibrary(.{
const mruby_lib = b.addLibrary(.{
.name = "libruby",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.root_source_file = null,
.target = target,
.optimize = optimize,
}),
});
{
const lib = mruby_lib;
Expand Down Expand Up @@ -362,7 +369,7 @@ pub fn build(b: *std.Build) !void {
});
}

var gem_init_content = std.ArrayList(u8).init(b.allocator);
var gem_init_content = std.array_list.Managed(u8).init(b.allocator);
defer gem_init_content.deinit();

try gem_init_content.appendSlice(
Expand Down Expand Up @@ -479,7 +486,7 @@ pub fn build(b: *std.Build) !void {
//
// generate mrbgems/gem_init.c
{
var gem_init_content = std.ArrayList(u8).init(b.allocator);
var gem_init_content = std.array_list.Managed(u8).init(b.allocator);
defer gem_init_content.deinit();

try gem_init_content.appendSlice(
Expand Down Expand Up @@ -595,8 +602,10 @@ pub fn build(b: *std.Build) !void {

const mruby_exe = b.addExecutable(.{
.name = "mruby",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
const exe = mruby_exe;
Expand Down Expand Up @@ -626,8 +635,10 @@ pub fn build(b: *std.Build) !void {

const mirb_exe = b.addExecutable(.{
.name = "mirb",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
const exe = mirb_exe;
Expand Down Expand Up @@ -663,8 +674,10 @@ pub fn build(b: *std.Build) !void {
// zig build mrdb -DMRB_USE_DEBUG_HOOK=true -- sample.rb
const mrdb_exe = b.addExecutable(.{
.name = "mrdb",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
const exe = mrdb_exe;
Expand Down Expand Up @@ -698,8 +711,10 @@ pub fn build(b: *std.Build) !void {

const mruby_strip_exe = b.addExecutable(.{
.name = "mruby-strip",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
const exe = mruby_strip_exe;
Expand Down Expand Up @@ -729,8 +744,10 @@ pub fn build(b: *std.Build) !void {

const mrbtest = b.addExecutable(.{
.name = "mrbtest",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
const exe = mrbtest;
Expand Down Expand Up @@ -772,7 +789,7 @@ pub fn build(b: *std.Build) !void {
}

for (mruby_gems) |gem| {
var gem_test_content = std.ArrayList(u8).init(b.allocator);
var gem_test_content = std.array_list.Managed(u8).init(b.allocator);
defer gem_test_content.deinit();

if (gem.test_rbfiles.len == 0) continue;
Expand Down Expand Up @@ -837,7 +854,7 @@ pub fn build(b: *std.Build) !void {
\\
, .{gem.name})[0..]);

var dependencies = std.ArrayList([]const u8).init(b.allocator);
var dependencies = std.array_list.Managed([]const u8).init(b.allocator);
defer dependencies.deinit();

for (gem.dependencies) |dep|
Expand Down Expand Up @@ -967,7 +984,7 @@ pub fn build(b: *std.Build) !void {

// mrbgems/mruby-test/mrbtest.c
{
var mrbtest_content = std.ArrayList(u8).init(b.allocator);
var mrbtest_content = std.array_list.Managed(u8).init(b.allocator);
defer mrbtest_content.deinit();

try mrbtest_content.appendSlice(
Expand Down Expand Up @@ -1070,6 +1087,23 @@ pub fn build(b: *std.Build) !void {

//

const module = b.addModule("mruby", .{
.root_source_file = b.addWriteFiles().add("src/lib.zig",
\\pub const c = @import("c");
),
// // after translate-c supports bitfields...
// .root_source_file = b.addWriteFiles().add("src/lib.zig",
// \\pub const c = @cImport({
// \\ @cInclude("mruby.h");
// \\ @cInclude("mruby/compile.h");
// \\ @cInclude("mruby/data.h");
// \\ @cInclude("mruby/string.h");
// \\ @cInclude("mruby/variable.h");
// \\ @cInclude("mruby/array.h");
// \\});
// ),
});

const translate_c = b.addTranslateC(.{
// every header needed to use MRuby, add more as needed
.root_source_file = b.addWriteFiles().add("input.c",
Expand All @@ -1085,30 +1119,40 @@ pub fn build(b: *std.Build) !void {
});
{
translate_c.addIncludePath(mruby_dep.path("include"));
}

// TODO: this won't be needed after translate-c supports bitfields
const fix_translation_exe = b.addExecutable(.{
.name = "fix-translation",
.target = b.graph.host,
.optimize = .ReleaseFast,
.root_source_file = b.path("src/fix_translation.zig"),
});
const fix_translation = b.addRunArtifact(fix_translation_exe);
{
fix_translation.addFileArg(translate_c.getOutput());
// const install = b.addInstallFile(translate_c.getOutput(), "input.h");
// const step = b.step("fix-translation-header", "Generate translation input");
// step.dependOn(&install.step);
}
const fixed_translation = fix_translation.captureStdOut();

const module = b.addModule("mruby", .{
.root_source_file = b.addWriteFiles().add("src/lib.zig",
\\pub const c = @import("c");
),
});
{
module.addImport("c", b.createModule(.{
.root_source_file = fixed_translation,
}));
// TODO: this won't be needed after translate-c supports bitfields
const fix_translation_exe = b.addExecutable(.{
.name = "fix-translation",
.root_module = b.createModule(.{
.target = b.graph.host,
.optimize = .ReleaseFast,
.root_source_file = b.path("src/fix_translation.zig"),
}),
});
const fix_translation = b.addRunArtifact(fix_translation_exe);
{
fix_translation.addFileArg(translate_c.getOutput());
}
const fixed_translation = fix_translation.captureStdOut();

// const install = b.addInstallFile(fixed_translation, "fixed-translation.zig");
// const step = b.step("fix-translation", "Generate translation output");
// step.dependOn(&install.step);

module.addAnonymousImport("c", .{
// .root_source_file = fixed_translation,
// TODO: why does this work, but not the above?
.root_source_file = b.addWriteFiles().addCopyFile(fixed_translation, "src/lib.zig"),
});

// TODO: when zig-translate-c has bitfield support
// module.addImport("c", translate_c.createModule());

module.linkLibrary(mruby_lib);
}
Expand All @@ -1117,8 +1161,10 @@ pub fn build(b: *std.Build) !void {

const example_c = b.addExecutable(.{
.name = "example-c",
.target = target,
.optimize = optimize,
.root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}),
});
{
example_c.addCSourceFiles(.{
Expand Down Expand Up @@ -1164,13 +1210,21 @@ pub fn build(b: *std.Build) !void {

const example_zig = b.addExecutable(.{
.name = "example-zig",
.target = target,
.optimize = optimize,
.root_source_file = b.path("src/example.zig"),

// TODO: errors without this... :(
// undefined symbol: etext
// undefined symbol: edata
.use_llvm = true,
.root_module = b.createModule(.{
.root_source_file = b.path("src/example.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "mruby", .module = module },
},
}),
});
{
example_zig.root_module.addImport("mruby", module);

b.installArtifact(example_zig);

const run = b.addRunArtifact(example_zig);
Expand Down
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
.name = .mruby,
.fingerprint = 0x4a9e46f0ee99188a,
.version = "0.0.0",
.minimum_zig_version = "0.14.1",
.minimum_zig_version = "0.15.2",
.paths = .{
"src",
"build.zig",
Expand Down
Loading
Loading