Re: Difference on shared lib installation on NetBSD vs. Linux and others (trying to update openblas packages)
Taylor R Campbell <[email protected]>
| Newsgroups | gmane.os.netbsd.devel.packages |
|---|---|
| Message-ID | <[email protected]> |
> Date: Sun, 22 Feb 2026 16:20:26 +0100 > From: "Dr. Thomas Orgis" <[email protected]> > > Now to my question: Apart from peculiarities of the OpenBLAS build, is > there a difference in the BSDs compared to Linux when it comes to the > custom of having libfoo.so.0 as the actual library file and the .so > being a symlink to it? No. How it works on essentially all ELF platforms: - At build-time, when you link a target program/library with `-lfoo', the linker (ld(1), called the `link editor' in the ELF spec) looks for a file named `libfoo.so' in the -L library path. If it finds libfoo.so, it takes that library's DT_SONAME, typically `libfoo.so.123', and copies it to a DT_NEEED in the target. - At run-time, when you run a program with a DT_NEEDED of `libfoo.so.123' or call dlopen("libfoo.so.123"), the run-time loader (ld.elf_so on NetBSD, sometimes colloquially referred to as rtld; `dynamic linker' in the ELF spec) looks for a file named `libfoo.so.123' in the run-time library path (DT_RPATH as set by -Wl,-R at build-time, or LD_LIBRARY_PATH at run-time). Actually this is often a symlink too, to a .so.N.M or .so.N.M.T file. But the linker and loader don't care about those. So you only need the .so path if you want to link new programs/libraries against the library. But you need the .so.N path if you want to run programs or load libraries that are already linked against the library. Reference: System V Application Binary Interface -- DRAFT, 2010-10-19, Ch. 5: Dynamic Linking: Shared Object Dependencies https://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html#shobj_dependencies https://web.archive.org/web/20260216141035/https://www.sco.com/developers/gabi/2012-12-31/ch5.dynamic.html#shobj_dependencies You can examine the DT_SONAME, DT_NEEDED, and DT_RPATH by running `readelf -d' (which omits the `DT_' prefix). E.g., here's the output for libm.so on netbsd-11 (which is a symlink to libm.so.0, which is a symlink to libm.so.0.14): 0x0000000000000001 (NEEDED) Shared library: [libc.so.12] 0x000000000000000e (SONAME) Library soname: [libm.so.0] 0x000000000000000f (RPATH) Library rpath: [/lib] You may already know all this; I'm just restating it in case it is relevant to the openblas packaging, which I didn't follow all the details of. If there is some CPU-specific optimization available, ideally we would: 1. link everything by default against libopenblas.so which is a library with an SONAME of libopenblas.so.N, where libopenblas.so.N is a library that works on _all_ machines of the same architecture like amd64; 2. ship _all_ the optimized libraries libopenblas_haswell.so.N, libopenblas_skylake.so.N, libopenblas_zenryzenepyc.so.N, &c., unconditionally for amd64 builds; 3. have a sysctl knob to select between them using ld.so.conf(5) so that at _run-time_, the loader can automatically load the optimized libopenblas_haswell.so.N in the place of libopenblas.so.N if the machine it's running on supports it. E.g., on evbarm, there's an alternative to libc.so.N, libc_vfp.so.N, that runs faster but only works if the machine has an FPU, indicated by the sysctl knob machdep.fpu_present: https://nxr.netbsd.org/xref/src/etc/etc.evbarm/ld.so.conf?r=1.1 But that's the ideal case; we might not have the right sysctl knob to make this work, and the openblas build might make it hard to build all of the optimized variants, and so on. In any case, if you want `-lopenblas' to work, then: (a) the package must ship `libopenblas.so' verbatim, and (b) libopenblas.so must have an SONAME pointing to a library the package ships that works for all machines of the same architecture (which could be `libblahblahopenblas-generic.so.N', doesn't really matter what it's called). And if you want dlopen("libopenblas.so.N") to work, the package must also ship `libopenblas.so.N' verbatim.