E-xyza / zigler

zig nifs in elixir
MIT License
753 stars 40 forks source link

build failing because of 'undefined reference to symbol' #439

Closed dvic closed 3 weeks ago

dvic commented 6 months ago

Using this simple example:

defmodule ZiglerDemo do
  use Zig, otp_app: :zigler_demo

  ~Z"""
  pub fn example_fun(value1: f64, value2: f64) bool {
    return value1 > value2;
  }
  """
end

I get all kinds of undefined references:

zig build-lib Elixir.ZiglerDemo Debug native: error: error(link): undefined reference to symbol '_enif_alloc'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_new_binary'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_free'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_list_from_array'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_tuple_from_array'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_get_double'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_term_type'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_list_cell'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_get_atom'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_get_uint'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_uint'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_make_atom_len'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error(link): undefined reference to symbol '_enif_raise_exception'
error(link):   first referenced in '/private/var/folders/k9/zz7w5p9x7cv5ft__g9tn1cr80000gn/T/Elixir.ZiglerDemo/zig-cache/o/7eac732c90abce37e4736b4049c1e67c/libElixir.ZiglerDemo.0.0.0.dylib.o'
error: UndefinedSymbolReference

This is the generated build.zig:

const std = @import("std");

pub fn build(b: *std.Build) void {
    const target = b.standardTargetOptions(.{});
    const optimize = b.standardOptimizeOption(.{});

    const erl_nif = b.createModule(.{
        .source_file = .{ .cwd_relative = "/Users/dvic/Development/temp/zigler_demo/_build/test/lib/zigler/priv/beam/erl_nif.zig" },
        .dependencies = &[_]std.Build.ModuleDependency{},
    });

    const beam = b.createModule(.{ .source_file = .{ .cwd_relative = "/Users/dvic/Development/temp/zigler_demo/_build/test/lib/zigler/priv/beam/beam.zig" }, .dependencies = &[_]std.Build.ModuleDependency{.{ .name = "erl_nif", .module = erl_nif }} });

    const nif = b.createModule(.{ .source_file = .{ .cwd_relative = "/Users/dvic/Development/temp/zigler_demo/lib/.Elixir.ZiglerDemo.zig" }, .dependencies = &[_]std.Build.ModuleDependency{ .{ .name = "erl_nif", .module = erl_nif }, .{ .name = "beam", .module = beam } } });

    const lib = b.addSharedLibrary(.{
        .name = "Elixir.ZiglerDemo",
        .root_source_file = .{ .path = "module.zig" },
        .version = .{ .major = 0, .minor = 0, .patch = 0 },
        .target = target,
        .optimize = optimize,
    });

    const beam_system_dir = "/Users/dvic/.config/local/share/mise/installs/erlang/26.2.2/erts-14.2.2/include";

    lib.addSystemIncludePath(.{ .cwd_relative = beam_system_dir });

    lib.linkLibC();

    lib.addModule("erl_nif", erl_nif);
    lib.addModule("beam", beam);
    lib.addModule("nif", nif);

    b.installArtifact(lib);
}

Does anything stand out here? The include directory exists:

❯ ls /Users/dvic/.config/local/share/mise/installs/erlang/26.2.2/erts-14.2.2/include
driver_int.h               erl_drv_nif.h              erl_int_sizes_config.h     erl_nif_api_funcs.h
erl_driver.h               erl_fixed_size_int_types.h erl_nif.h                  internal
ityonemo commented 5 months ago

ok this is a macosx issue, are you on intel macos? i'm away from my arm macos dev box until monday, but will be able to take a look then.

dvic commented 5 months ago

No I’m on a M1 Macbook Pro. Thanks for looking into this! Let me know if you need anything else from me.

ityonemo commented 5 months ago

apologies, but I'm going to punt this to 0.12.0, which should be out soon (there are only 40 issues left)

dvic commented 5 months ago

No worries, no rush 👍

dvic commented 5 months ago

I think I have a clue what might be the issue here: I encountered the same issue with Rustler projects (e.g., ), and putting this config in the Rust crate fixed the issue:

❯ cat .cargo/config.toml
[target.'cfg(target_os = "macos")']
rustflags = [
    "-C", "link-arg=-undefined",
    "-C", "link-arg=dynamic_lookup",
]

Could this be the issue for Zig as well? I haven't tried it because I don't know how to set linker args using the Zig build system, if I have some time left I can look into it :)

ityonemo commented 3 weeks ago

this is fixed in 0.12.1. Issue is that I forgot to tell the compiler to ignore unknown references when building a .so file. For some reason doesn't complain in linux.