Loading linux libraries inside FreeBSD program (Python script)

853 Views Asked by At

I'm trying to use some Linux libs under FreeBSD/PC-BSD, and I have some doubts about how Linux binary compatibility on FreeBSD works.

I have installed the required kernel module for this task, with the additional linux_base package containing the Linux libraries.

The library itself is libspotify, which can be downloaded here (there are no libspotify builds available for FreeBSD, so the Linux one must be used): https://developer.spotify.com/technologies/libspotify/#download

Running this Python code snipped fails:

import ctypes
lib_path = './libspotify.so'
lib = ctypes.cdll.LoadLibrary(lib_path)

It says the following:

OSError: Shared object "libpthread.so.0" not found, required by "libspotify.so"

The handbook says that linux binaries must be tagged using brandelf, and I did so: http://www.freebsd.org/doc/handbook/linuxemu-lbc-install.html#idp74327472

But it does not work yet.

So the question is: Linux binary compatibility is only for Linux executables or is also suitable for loading Linux libraries inside FreeBSD executables?

EDIT: I'm aware that this may require changing the linker configuration as stated on an answer to this similar question, but since the library is going to be loaded inside a Python script, it doesn't seem a suitable approach.

Thanks in advance.

1

There are 1 best solutions below

0
On

So the question is: Linux binary compatibility is only for Linux executables or is also suitable for loading Linux libraries inside FreeBSD executables?

Short answer -- it's only for linux executables. It's not going to work for loading linux shared libraries from FreeBSD executables.

Longer version:

Your problem is that when you load application from a FreeBSD binary, it's FreeBSD's dynamic linker that does the job and it will attempt to resolve the symbols using FreeBSD's libraries which it not what you want to happen.

For comparison, when you launch Linux binaries on FreeBSD, kernel figures out that it's a linux binary (brandelf helps here) and then does two things -- replacess process' syscall table with the one that will handle linux syscalls and redirects filesystem root to /compat/linux. After that it launches linux ld.so which will then load linux dynamic libraries and resolve symbols among them.

Using linux shared object directly from freebsd app is theoretically possible, but hard to do in practice. You'll need to figure out how to handle linux system calls that library may make, deal with functions it may want to call from linux shared libraries, deal with files it may want to open assuming linux filesystem layout, etc.

A more pragmatic solution is to have some sort of 'proxy' linux binary which will load your linux shared library and which would communicate with freebsd binary via some sort of IPC and perform calls into linux code on FreeBSD app's behalf. I believe this is how opera web browser runs Linux plugins on FreeBSD. If you're curious, take a look at NSpluginwrapper which does something similar.