Not-Nik / raylib-zig

Manually tweaked, auto-generated raylib bindings for zig. https://github.com/raysan5/raylib
MIT License
459 stars 101 forks source link

How to use dependency as dynamic library? #113

Open gluax opened 5 days ago

gluax commented 5 days ago

Hey all! Sorry if this is a newbie question, but I am trying to figure out if there's an out of the box way to compile this as dynamic library?

Wondering because I wanted to set up hot reloading with this.

When I tried having a game dynamic library and an executable I build that reloads the game dynamic library it seemed the raylib instances were separate with the dependency artifact and module.

So I tried hacking around building this dependency dynamically and using it in both, without having to do a cImport, but not sure that's possible or if I'm doing something wrong as I keep running into different errors of all kinds.

I didn't see any examples or older issues on this as well.

Not-Nik commented 5 days ago

This isn't supported currently, but maybe we can add an option that makes the artifact dependency build as a dynamic library. I'm not awfully familiar with all the build options you can pass as they aren't documented to my knowledge, but maybe someone else knows if this is possible

gluax commented 5 days ago

I did actually manage to get it to build as a dynamic library. Though I'm not sure I did it the proper way this was how I managed to accomplish it:

const raylib_dep = b.dependency("raylib-zig", .{
  .target = target,
  .optimize = optimize,
});

const raylib = b.addSharedLibrary(.{
  .name = "raylib",
  .root_source_file = raylib_dep.path("lib/raylib.zig"),
  .target = target,
  .optimize = optimize,
});
raylib.linkLibC();
b.installArtifact(raylib);

You can then do something like:

exe.linkLibC();
exe.addLibraryPath(b.path("zig-out/lib"));
exe.linkSystemLibrary("raylib");

This required using a @cImport instead of an @import. I couldn't figure out a way to use a regular import and the dynamic lib, but if anyone has any ideas that'd be great :).

gluax commented 4 days ago

I stand corrected. What I did above did not produce a correct dynamic library file. I checked the symbol table of what I built with nm.

While I'm not sure how to get the dependency to build the dynamic library I learned you can force both instances to use the same instance of raylib(in this instance the library is one I built from the raylib source) via:

const raylib_dep = b.dependency("raylib-zig", .{
   .target = target,
   .optimize = optimize,
});
const raylib_mod = raylib_dep.module("raylib");

// Create the DLL for the game library.
const gamelib = b.addSharedLibrary(.{
  .name = "game",
  .root_source_file = b.path("src/game.zig"),
  .target = target,
  .optimize = optimize,
  .version = .{ .major = 1, .minor = 0, .patch = 0 },
});
gamelib.linkLibC();
// gamelib.addLibraryPath(b.path("zig-out/lib"));
gamelib.linkSystemLibrary("raylib");
gamelib.root_module.addImport("raylib", raylib_mod);
b.installArtifact(gamelib);

const exe = b.addExecutable(.{
  .name = "hotreload",
  .root_source_file = b.path("src/main.zig"),
  .target = target,
  .optimize = optimize,
});
exe.linkLibC();
// exe.addLibraryPath(b.path("zig-out/lib"));
exe.linkSystemLibrary("raylib");
exe.root_module.addImport("raylib", raylib_mod);
b.installArtifact(exe);