Haikuports: SONAME symbolic links while porting shared libraries

I’m continuing my journey in learning how to port for Haiku. At first it was hard, but I feel I’m improving (tnx to the support of the community!) and some of my ports were merged already (aye!)

I promise to collect what I’ve discovered so far in a Troubleshooting doc I hope other would benefit

Now with today’s problem.

I’ve ported this shared library: https://github.com/theclue/haikuports/blob/fits2png/sci-libs/cfitsio/cfitsio-3.47.recipe

Build, test and install ok. The produced library is called libcfitsio.so

But I’ve noticed that a couple of apps which make use of this library don’t work as they search for libcfitsio.so.8

Having a look at the Makefile generated for my Darwin host I see that two symbolic links are created:

	@if [ "x${CFITSIO_SHLIB_SONAME}" != x ]; then \
		ln -sf ${CFITSIO_SHLIB_SONAME} $@; \

These links are not created into the Makefile generated for Haiku

Skipping all the intermediate steps, I’ve discovered that these links are not created because Haiku is not in a list of known $host in configure.in.

My questions:

  • What is the purpose of these synbolic links in build?
  • If I update configure.in, reconfigure and repackage, will those symbolic links be added to the package as well?
  • Should I patch configure.in then add autoreconf in BUILD in recipe or execute autoreconf offline and patch the resulting configure script instead?

as usual, tnx for support and happy patching!

Usually one uses “autoreconf -fi” instead of “autoconf”, when default scripts are not Haiku aware.

Whops :no_mouth:

Well, I suppose it’s ok to patch the configure.in files, also. Perhaps it’s more time consuming, I suppose. But since I did it already I won’t change it, if it’s ok for haikuports.

I could also do a pull request upstream now I guess.

We prefer configure.in patches so we (or you!) can upstream them, if they are properly “clean” and respect other OSes :slight_smile:

They are to allow linking by the library short name, but actually using the soname at runtime.

The idea is that when you use a library, you want a simple linker flag, for example you link to libpng by adding -lpng to the linker command line. The linker will look at a file named libpng.so and link to that.

However, there are multiple versions of libpng around. And they have a different ABI: functions were added, removed, or renamed. And the runtime_loader needs to know which version you want.

The way to fix this is by adding “sonames” to libraries. When the linker loads libpng.so, it will look inside the library and find that it has a soname. In libpng case, the soname is something like “libpng.so.15”. And this name is what your program will actually link to.

When the executable is run, the runtime_loader will look for a file named libpng.so.15 and load that. If you have other versions of libpng around, like libpng.so.12, it will ignore them, and load the correct one.

Implementation details: on Linux, there is a database mapping sonames to library names. The library filename does not need to match the soname in any way. This database is updated by ldconfig, which needs to be run everytime you install or remove a library.

On Haiku, we have no such database. What we did is have, in /system/lib, libraries with a filename always exactly matching their soname. This way, the runtime_loader can refer to that directory and look things by filename safely. However, the linker needs the library under its other name (libpng.so) so that you can link using -lpng. We do this by having symlinks in /system/develop/lib, which is where the linker will look.

The symlinks are taken care of in haikuporter by using prepareInstalledDevelLibs. So you can try calling that and see if it manages to put everything in the right place. Maybe no changes to configure.in will be needed.

Tnx allot @PulkoMandy, now it’s stunning clear :slight_smile:

Actually, It didn’t. Digging into configure.in I see that it uses to default soname to the libname when a given $host was not recognized. Otherwise, the Makefile creates these symlinks.

The patch was easy: I’ve just added an haiku block in the $host case block that just set the correct names for those symlinks. The names seems to be the same of Linux and Darwin, at a first look. I assume this is always true (but I will check).

I’ve just read this book (yeah, lockdown side effects…), so it won’t hurt to put my hands on those .in and .ac files finally.

@PulkoMandy meant that you prepareInstalledDevelLibs puts the libs in the correct place, it doesn’t creates any.

That’s ok, the patched configure.in actually do now. I just need prepareInstalledDevelLibs move them in the corrent place together with the .so file.