Linking Shared Object Files (.so) in Zig Build

I’m hitting a dead-end with documentation here (and what I can find is out of date). I have compiled a shared object with C calling conventions and I want to link it in the build.zig file. Is there a standard procedure for doing this?

One answer I’ve come up with is:

exe.addLibPath("library/path");
exe.linkSystemLibrary("name");

One caveat here is that you need to name your library “libSomething.so” because it searches for the prefix “lib” for both .so and .a extensions.

1 Like

I am not quite sure, are you satisfied with your solution, or do you want something else?

Because you are saying shared (and using linkSystemLibrary) I assume you compiled a shared library?

I think a static library is just an archive of object files and I believe you could add that with addObjectFile (But other code seems to suggest that dynamic libraries work there too, or is that old code??).

For shared libraries I am not quite sure. I am using raylib like this (it gets built as a static library, but I assume dynamic would work too):

exe.linkLibrary(raylib_dep.artifact("raylib"));

This makes me think that maybe you could create a separate build.zig for your lib that either compiles (or collects the object) into an artifact which you can then depend on.

I think making building of the library part of that build.zig is probably easier and more useful than trying to figure out how to package some manually compiled thing, but I don’t know enough to be sure.

build system - dynamic library
build system - linking to system libraries

Users of zig build may use --search-prefix to provide additional directories that are considered “system directories” for the purposes of finding static and dynamic libraries.

I think one of the points that confuses me is, that I am unsure why you want a dynamic library (instead of a static one) while still specifying an explicit path to the library. If you want the dynamic library so it can be shared between many programs maybe it could also be installed in a standard location, so you don’t have to use addLibPath. If you don’t want to share it, then a static library would be simpler?

I can understand not wanting to specify --search-prefix manually all the time, I wonder whether it can be configured somewhere instead (without having to pollute the project with user/system specific configuration), alternatively maybe system specific things like LD_LIBRARY_PATH could be used to make the library findable (but I am not sure whether zig actually uses those?). I think overall I prefer when everything is using zigs package manager and not using system libraries, so that builds can be completely reproduce-able, but I guess that is just personal preference.

1 Like

rpath could be useful here: embedding inside the library / binary the location of your shared object. Check this link for more information.

1 Like

@Sze No argument from me about the benefits of static linking. Fundamentally, I just wanted to see an example of how linking a .so looks… it’s still surprisingly annoying to dig up clear “do x, y, and z” style examples around build.zig. Now that I’ve got a working example, I can dig through the code and do some more productive reading on the subject. Also, I’m linking to several system libraries (I should have mentioned that, but I kept it to one library that the user compiled).

@gonzo thanks for the link :slight_smile:

4 Likes

Yeah, that’s been my experience too. While I enjoy Zig the Language, I find doing anything at build.zig level to be really frustrating. It’s even hard to explore the build API, I usually don’t really get anywhere when I browse the implementation of build related functions and types.

1 Like