On 2018/11/28 22:48, George Koehler wrote:
> On Thu, 29 Nov 2018 00:28:11 +0000
> Stuart Henderson <[email protected]> wrote:
> 
> > $ objdump -p /usr/local/bin/zint|grep NEEDED
> >   NEEDED      libzint.so
> >   NEEDED      libpng.so.17.5
> >   NEEDED      libz.so.5.0
> >   NEEDED      libm.so.10.1
> >   NEEDED      libc.so.93.0
> 
> I don't know.  This might happen because some libraries in OpenBSD
> (like libzint and libpng) don't have DT_SONAME.
> 
> In other ELF systems, a shared library has its name and version
> number in DT_SONAME.  The linker opens a symbolic link (like
> libterminfo.so -> libterminfo.so.1.0) and reads the DT_SONAME to know
> the version number.  It copies this DT_SONAME to DT_NEEDED.
> 
> Like in NetBSD:
> $ objdump -p /usr/lib/libterminfo.so | grep SONAME
>   SONAME               libterminfo.so.1
> $ objdump -p /usr/bin/tmux | grep terminfo
>   NEEDED               libterminfo.so.1
> 
> In OpenBSD, there is no libpng.so symlink, so the linker opens
> libpng.so.17.5.  There's no DT_SONAME.  The linker knows that the
> basename is libpng.so.17.5, but the linker might or might not use
> the basename as DT_NEEDED.
> 
> If I remember correctly, if ld.bfd links to a library without
> DT_SONAME, then the rules are:
>  - If you use cc -L/usr/local/lib -lpng, then ld.bfd uses the
>    basename libpng.so.17.5 as DT_NEEDED.  This is correct.
>  - If you use cc /usr/local/lib/libpng.so.17.5, then ld.bfd uses
>    the absolute path /usr/local/lib/libpng.so.17.5 as DT_NEEDED.
>    This is weird but might still work.
>  - If (inside some project) you use cc subdir/libwhat.so.0.0, then
>    ld.bfd uses the relative path subdir/libwhat.so.0.0 as DT_SONAME.
>    This might break the build because some executable has subdir in
>    its rpath, and needs subdir/libwhat.so.0.0 in its rpath, but fails
>    because subdir/subdir/libwhat.so.0.0 doesn't exist.
> 
> The rules in ld.lld might be different.  I don't know.  This weirdness
> only happens on OpenBSD, because other ELF systems always put
> DT_SONAME in their shared libraries.
> 
> Some build systems (like CMake and Meson) like to run cc with absolute
> or relative paths to shared libraries.  They rely on DT_SONAME to set
> DT_NEEDED to just the basename.  OpenBSD's port of devel/cmake has
> local patches:
>  - patch-Modules_CMake{C,CXX}Information_cmake seems to remove the
>    -Wl,-soname=... so shared libraries don't get DT_SONAME.
>  - patch-Source_cmComputeLinkInformation seems to link to libraries
>    with -L... -l... instead of absolute paths.

After some discussions off ports@, it looks like this:

For OpenBSD we either need DT_SONAME with the full library version
including minor:

$ objdump  -p /usr/lib/libc.so.93.0 |grep SONAME
  SONAME      libc.so.93.0

Or we can have a library with no DT_SONAME, *provided* that there's
only the libfoo.so.N.M file and *no* libfoo.so symlink.

(On an system using ld.bfd, it's OK to have the libfoo.so symlink
present while linking a program against that library during the
build, but on a system using LLD that doesn't work correctly).

Is anyone reading who already knows how cmake and the patches in
ports work? I've had a play with removing various chunks of them
but haven't got it emitting -Wl,-soname yet.

Reply via email to