diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index af7b1fa..6bd4ef5 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -19,8 +19,6 @@ jobs: steps: - name: Clone the repository uses: actions/checkout@v4 - with: - submodules: recursive - name: Install OTP and Elixir uses: erlef/setup-beam@v1 @@ -102,23 +100,18 @@ jobs: steps: - name: Clone the repository uses: actions/checkout@v4 - with: - submodules: recursive - name: Fetch TigerBeetle for Linux if: runner.os == 'Linux' - working-directory: ./src/tigerbeetle run: | curl -Lo tigerbeetle.zip https://linux.tigerbeetle.com && unzip tigerbeetle.zip - name: Fetch TigerBeetle for Mac if: runner.os == 'macOS' - working-directory: ./src/tigerbeetle run: | curl -Lo tigerbeetle.zip https://mac.tigerbeetle.com && unzip tigerbeetle.zip - name: Start TigerBeetle - working-directory: ./src/tigerbeetle run: | ./tigerbeetle format --cluster=0 --replica=0 --replica-count=1 --development 0_0.tigerbeetle ./tigerbeetle start --addresses=3000 --development 0_0.tigerbeetle & diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 0a06adf..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "src/tigerbeetle"] - path = src/tigerbeetle - url = git@github.com:tigerbeetledb/tigerbeetle.git diff --git a/README.md b/README.md index 03f522b..ee6c84d 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ The package can be installed by adding `tigerbeetlex` to your list of dependenci ```elixir def deps do [ - {:tigerbeetlex, github: "rbino/tigerbeetlex", submodules: true} + {:tigerbeetlex, github: "rbino/tigerbeetlex"} ] end ``` diff --git a/build.zig b/build.zig index c911404..03be638 100644 --- a/build.zig +++ b/build.zig @@ -3,7 +3,7 @@ const std = @import("std"); // Although this function looks imperative, note that its job is to // declaratively construct a build graph that will be executed by an external // runner. -pub fn build(b: *std.Build) void { +pub fn build(b: *std.Build) !void { // Standard target options allows the person running `zig build` to choose // what target to build for. Here we do not override the defaults, which // means any target is allowed, and the default is native. Other options @@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); // Get ERTS_INCLUDE_DIR from env, which should be passed by :build_dot_zig - const erts_include_dir = std.process.getEnvVarOwned(b.allocator, "ERTS_INCLUDE_DIR") catch blk: { + const erts_include_dir = b.graph.env_map.get("ERTS_INCLUDE_DIR") orelse blk: { // Fallback to extracting it from the erlang shell so we can also execute zig build manually const argv = [_][]const u8{ "erl", @@ -31,6 +31,28 @@ pub fn build(b: *std.Build) void { break :blk b.run(&argv); }; + // This is passed from mix.exs, which extracts it by "parsing" build.zig.zon + const release = b.option( + []const u8, + "tigerbeetle_release", + "The release of TigerBeetle targeted by the client", + ) orelse { + std.log.err("tigerbeetle_release option is required", .{}); + return error.MissingTigerBeetleRelease; + }; + + // This is hardcoded in TigerBeetle in src/scripts/release.zig + const release_client_min: []const u8 = "0.15.3"; + + const opts = .{ + .target = target, + .@"config-release" = release, + .@"config-release-client-min" = release_client_min, + // The rest of VSR options will use the default value + // TODO: should we expose other VSR build options here? + }; + const vsr_mod = b.dependency("tigerbeetle", opts).module("vsr"); + const lib = b.addSharedLibrary(.{ .name = "tigerbeetlex", // In this case the main source file is merely a path, however, in more @@ -41,6 +63,8 @@ pub fn build(b: *std.Build) void { .link_libc = true, }); lib.addSystemIncludePath(.{ .cwd_relative = erts_include_dir }); + // TigerBeetle imports + lib.root_module.addImport("vsr", vsr_mod); // This is needed to avoid errors on MacOS when loading the NIF lib.linker_allow_shlib_undefined = true; diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..d4176d0 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,36 @@ +.{ + // This is the default name used by packages depending on this one. For + // example, when a user runs `zig fetch --save `, this field is used + // as the key in the `dependencies` table. Although the user can choose a + // different name, most users will stick with this provided value. + // + // It is redundant to include "zig" in this name because it is already + // within the Zig package namespace. + .name = "tigerbeetlex", + + // This is a [Semantic Version](https://semver.org/). + // In a future version of Zig it will be used for package deduplication. + .version = "0.0.0", + + // This field is optional. + // This is currently advisory only; Zig does not yet do anything + // with this value. + .minimum_zig_version = "0.13.0", + + // This field is optional. + // Each dependency must either provide a `url` and `hash`, or a `path`. + // `zig build --fetch` can be used to fetch all dependencies of a package, recursively. + // Once all dependencies are fetched, `zig build` no longer requires + // internet connectivity. + .dependencies = .{ + .tigerbeetle = .{ + .url = "https://github.com/tigerbeetle/tigerbeetle/archive/refs/tags/0.15.4.tar.gz", + .hash = "1220df4340b291f24f4bb7346b7ed6fe06109eb79526c56b6ac85738e25519ad2ed7", + }, + }, + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + }, +} diff --git a/mix.exs b/mix.exs index 1bee2fa..c7ad54d 100644 --- a/mix.exs +++ b/mix.exs @@ -1,6 +1,12 @@ defmodule TigerBeetlex.MixProject do use Mix.Project + @release_regex ~r{https://github.com/tigerbeetle/tigerbeetle/archive/refs/tags/(?[0-9]+\.[0-9]+\.[0-9]+)\.tar\.gz} + + @tigerbeetle_release File.read!("build.zig.zon") + |> then(&Regex.named_captures(@release_regex, &1)) + |> Map.fetch!("release") + def project do [ app: :tigerbeetlex, @@ -8,6 +14,7 @@ defmodule TigerBeetlex.MixProject do elixir: "~> 1.14", install_zig: "0.13.0", zig_build_mode: zig_build_mode(Mix.env()), + zig_extra_options: [tigerbeetle_release: @tigerbeetle_release], compilers: [:build_dot_zig] ++ Mix.compilers(), start_permanent: Mix.env() == :prod, dialyzer: [plt_add_apps: [:zig_parser]], diff --git a/src/account_batch.zig b/src/account_batch.zig index 9e0ffbd..519454a 100644 --- a/src/account_batch.zig +++ b/src/account_batch.zig @@ -5,7 +5,7 @@ const batch = @import("batch.zig"); const beam = @import("beam.zig"); const scheduler = beam.scheduler; -const tb = @import("tigerbeetle/src/tigerbeetle.zig"); +const tb = @import("vsr").tigerbeetle; const Account = tb.Account; const AccountFlags = tb.AccountFlags; pub const AccountBatch = batch.Batch(Account); diff --git a/src/batch.zig b/src/batch.zig index 521ee4d..3ec1aaf 100644 --- a/src/batch.zig +++ b/src/batch.zig @@ -4,7 +4,7 @@ const RwLock = std.Thread.RwLock; const beam = @import("beam.zig"); const Resource = beam.resource.Resource; -const tb = @import("tigerbeetle/src/tigerbeetle.zig"); +const tb = @import("vsr").tigerbeetle; const Account = tb.Account; const Transfer = tb.Transfer; diff --git a/src/client.zig b/src/client.zig index da35e17..f060b2e 100644 --- a/src/client.zig +++ b/src/client.zig @@ -6,8 +6,8 @@ const process = beam.process; const resource = beam.resource; const Resource = resource.Resource; -const tb = @import("tigerbeetle/src/tigerbeetle.zig"); -const tb_client = @import("tigerbeetle/src/clients/c/tb_client.zig"); +const tb = @import("vsr").tigerbeetle; +const tb_client = @import("vsr").tb_client; const Account = tb.Account; const Transfer = tb.Transfer; diff --git a/src/tigerbeetle b/src/tigerbeetle deleted file mode 160000 index 14abaea..0000000 --- a/src/tigerbeetle +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 14abaeabd09bd7c78a95b6b990748f3612b3e4cc diff --git a/src/tigerbeetlex.zig b/src/tigerbeetlex.zig index ffb246f..155487d 100644 --- a/src/tigerbeetlex.zig +++ b/src/tigerbeetlex.zig @@ -17,19 +17,6 @@ const AccountBatchResource = account_batch.AccountBatchResource; const IdBatchResource = id_batch.IdBatchResource; const TransferBatchResource = transfer_batch.TransferBatchResource; -pub const vsr_options = .{ - .config_base = .default, - .config_log_level = std.log.Level.info, - .tracer_backend = .none, - .hash_log_mode = .none, - .git_commit = null, - // TODO: take these from a proper place - .release = "0.15.4", - .release_client_min = "0.15.4", - .config_aof_record = false, - .config_aof_recovery = false, -}; - pub const std_options = .{ .log_level = .err, }; diff --git a/src/transfer_batch.zig b/src/transfer_batch.zig index 54e12ee..4125983 100644 --- a/src/transfer_batch.zig +++ b/src/transfer_batch.zig @@ -5,7 +5,7 @@ const batch = @import("batch.zig"); const beam = @import("beam.zig"); const scheduler = beam.scheduler; -const tb = @import("tigerbeetle/src/tigerbeetle.zig"); +const tb = @import("vsr").tigerbeetle; const Transfer = tb.Transfer; const TransferFlags = tb.TransferFlags; pub const TransferBatch = batch.Batch(Transfer);