tech-pkg archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Difference on shared lib installation on NetBSD vs. Linux and others (trying to update openblas packages)



> Date: Sun, 22 Feb 2026 16:20:26 +0100
> From: "Dr. Thomas Orgis" <thomas.orgis%uni-hamburg.de@localhost>
> 
> 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.


Home | Main Index | Thread Index | Old Index