How does --search-prefix work in termux android

I’m trying to build a C library with zig that links libm and libdl-- easy enough, I just added

lib.linkSystemLibrary("m");
lib.linkSystemLibrary("dl");

Which works fine on my linux desktop, but not on my android in termux. I get this error:

error: unable to find dynamic system library 'm' using strategy 'paths_first'. searched paths:
  /usr/local/lib64/libm.so
  /usr/local/lib64/libm.a
  /usr/local/lib/libm.so
  /usr/local/lib/libm.a
  /usr/lib/aarch64-linux-android/libm.so
  /usr/lib/aarch64-linux-android/libm.a
  /lib64/libm.so
  /lib64/libm.a
  /lib/libm.so
  /lib/libm.a
  /usr/lib64/libm.so
  /usr/lib64/libm.a
  /usr/lib/libm.so
  /usr/lib/libm.a
  /lib/aarch64-linux-android/libm.so
  /lib/aarch64-linux-android/libm.a

android apparently stores libm and libdl in a folder called /system/lib64/, so I tried zig build --search-prefix /system/lib64/ and got the same error as above. There was no indication that it searched this extra folder. Am I using --search-prefix correctly? Or is there another config option I can use? I would rather not hard code it into build.zig, but I can if necessary.

lib.addLibraryPath(.{ .cwd_relative = "/system/lib64" });
1 Like

I have not verified the behavior by actually trying to compile code, but from looking the code for build_runner.zig, Build.zig and searching for references to search_prefixes, it appears that the only things --search-prefix do are adding the path to the list of paths searched by b.findProgram and adding <prefix>/lib and <prefix>/include to the library/include search paths when compiling artifacts.

You could check if the target is Android using target.result.isAndroid() and hard-code a path like @dimdin suggests. If you want the SDK path to be configurable by the user, you could consider doing something like this:

// assume the user passes --search-prefix /system/
if (target.result.isAndroid()) {
    for (b.search_prefixes.items) |search_prefix| {
        // add library and include paths as needed
        lib.addLibraryPath(.{ .cwd_relative = b.pathJoin(&.{ search_prefix, "lib64" }) });
    }
}

There’s also --sysroot option, which sets b.sysroot which subsequently can be used to join paths, but it’s a bit unclear exactly how the option is supposed to work and it has a different behavior for library search paths and include search paths.

2 Likes

Thanks, I added

if (target.result.isAndroid()) {
    lib.addLibraryPath(.{ .cwd_relative = "/system/lib64" });
}

And that got it to work (also side note, I wrapped this as a static library and depended on it for a separate exe. The exe’s build.zig also needed the additional library path). Thanks for the help!

2 Likes