Preventing library conflicts when attempting to install Linux binaries

When trying to install linux binaries, there are sometimes libraries with the same name, one in /linux/compat/lib and one in /usr/lib. How do you go about getting the linux binaries to use the libraries in /compat without using a symbolic link to /usr/lib which would cause problems for the freeBSD applications that use that library?
 
Look into /etc/libmap.conf, see also the libmap.conf(5) manual page. Apart from the more obvious solutions (like virtual environments such as Jails) I think this is probably the best approach.

Thanks for the help, ShelLuser. I read up on /etc/libmap.conf and how to use it. I think that's what I needed, but I'm thinking there may be a problem. When I source /etc/libmap.conf I get an error:
Code:
/etc/libmap.conf:2: command not found: includedir
for this line:
Code:
includedir /usr/local/etc/libmap.d
because there is no /usr/local/etc/libmap.d

in fact, there is no libmap.d anywhere on my system that I can find.
 
When I source /etc/libmap.conf I get an error:
Code:
/etc/libmap.conf:2: command not found: includedir
It's a configuration file, not something you need to execute.

As mentioned in the manualpage; what this does is allow you to map object dependencies. It's not something you execute yourself, it's something eventually used by the link editor (see ld.so(1)) so that you can tell it to use a specific library instead of the default.

So... you install your Linux stuff somewhere separated from the rest, you then set up a constrain so that the linker will know that whenever such a binary (or library) tries to load something it needs to be mapped. Lets say you installed your Linux stuff (executables) in /usr/local/linux/bin. You also know that your Linux programs shouldn't be trying to use /usr/lib/ncurses.so but instead /linux/compat/lib/ncurses.so.

Please note that these are examples only which I totally made up.

So this is what I would put into /etc/libmap.conf:

Code:
[/usr/local/linux/bin/]
libncurses.so /linux/compat/lib/ncurses.so

After that all binaries in /usr/local/linux/bin which try to access libncurses.so should be immediately (re)directed to /linux/compat/lib/ncurses.so instead of the linker searching through the library path and eventually coming across /usr/lib/libncurses.so.

That's all there is to it.

Add the right mappings to the config file, and then check that the binary is using the right path. Use ldd to check.

Because this is also somewhat new to me (I never bother with Linux stuff anymore and I seldomly use this feature) I decided to set up a test case. I'll share, hopefully this will can clear up any remaining confusing. Lets look what libraries /usr/local/bin/tmux uses:

Code:
macron:/usr/local/bin $ ldd tmux
tmux:
        libutil.so.9 => /lib/libutil.so.9 (0x280ec000)
        libulog.so.0 => /lib/libulog.so.0 (0x280fe000)
        libncurses.so.6 => /usr/local/lib/libncurses.so.6 (0x28101000)
        libtinfo.so.6 => /usr/local/lib/libtinfo.so.6 (0x28122000)
        libc.so.7 => /lib/libc.so.7 (0x2814d000)
        libmd.so.6 => /lib/libmd.so.6 (0x282cb000)
That's no good. I want it to ignore the 3rd party stuff and instead use the base library (/lib/libncurses.so.8). Warning: This is a totally horrible idea and the perfect recipe to create problems. The only reason I'm doing this is to show you how to use libmap.conf. It's bad to do this to tmux but this is exactly what you want for your Linux binaries.

So... I now tell the system that whenever tmux tries to load libncurses.so.6 it should not use the default but the one in /lib, namely libncurses.so.8. So I add this to /etc/libmap.conf:

Code:
[tmux]
libncurses.so.6 libncurses.so.8
So: I restrained the next rule solely to tmux only. So any other binary which is using libncurses.so.6 won't be affected.

And what do you know?

Code:
root@macron:/usr/local/bin # ldd tmux
tmux:
        libutil.so.9 => /lib/libutil.so.9 (0x280ec000)
        libulog.so.0 => /lib/libulog.so.0 (0x280fe000)
        libncurses.so.6 => /lib/libncurses.so.8 (0x28101000)
        libtinfo.so.6 => /usr/local/lib/libtinfo.so.6 (0x2813f000)
        libc.so.7 => /lib/libc.so.7 (0x2816a000)
        libmd.so.6 => /lib/libmd.so.6 (0x282e8000)
root@macron:/usr/local/bin # ldd irssi | grep ncurs
        libncurses.so.6 => /usr/local/lib/libncurses.so.6 (0x28648000)
(ignore me for being root here, I just edited /etc/libmap.conf and got lazy ;)).

As you can see: the changes are instant. And this is basically how you do it. Use ldd, and set up a re-route. I used specific names here, you can do the same, but you can also re-map complete pathnames if you so desire.
 
It's a configuration file, not something you need to execute.

As mentioned in the manualpage; what this does is allow you to map object dependencies. It's not something you execute yourself, it's something eventually used by the link editor (see ld.so(1)) so that you can tell it to use a specific library instead of the default.

So... you install your Linux stuff somewhere separated from the rest, you then set up a constrain so that the linker will know that whenever such a binary (or library) tries to load something it needs to be mapped. Lets say you installed your Linux stuff (executables) in /usr/local/linux/bin. You also know that your Linux programs shouldn't be trying to use /usr/lib/ncurses.so but instead /linux/compat/lib/ncurses.so.

Please note that these are examples only which I totally made up.

So this is what I would put into /etc/libmap.conf:

Code:
[/usr/local/linux/bin/]
libncurses.so /linux/compat/lib/ncurses.so

After that all binaries in /usr/local/linux/bin which try to access libncurses.so should be immediately (re)directed to /linux/compat/lib/ncurses.so instead of the linker searching through the library path and eventually coming across /usr/lib/libncurses.so.

That's all there is to it.

Add the right mappings to the config file, and then check that the binary is using the right path. Use ldd to check.

Because this is also somewhat new to me (I never bother with Linux stuff anymore and I seldomly use this feature) I decided to set up a test case. I'll share, hopefully this will can clear up any remaining confusing. Lets look what libraries /usr/local/bin/tmux uses:

Code:
macron:/usr/local/bin $ ldd tmux
tmux:
        libutil.so.9 => /lib/libutil.so.9 (0x280ec000)
        libulog.so.0 => /lib/libulog.so.0 (0x280fe000)
        libncurses.so.6 => /usr/local/lib/libncurses.so.6 (0x28101000)
        libtinfo.so.6 => /usr/local/lib/libtinfo.so.6 (0x28122000)
        libc.so.7 => /lib/libc.so.7 (0x2814d000)
        libmd.so.6 => /lib/libmd.so.6 (0x282cb000)
That's no good. I want it to ignore the 3rd party stuff and instead use the base library (/lib/libncurses.so.8). Warning: This is a totally horrible idea and the perfect recipe to create problems. The only reason I'm doing this is to show you how to use libmap.conf. It's bad to do this to tmux but this is exactly what you want for your Linux binaries.

So... I now tell the system that whenever tmux tries to load libncurses.so.6 it should not use the default but the one in /lib, namely libncurses.so.8. So I add this to /etc/libmap.conf:

Code:
[tmux]
libncurses.so.6 libncurses.so.8
So: I restrained the next rule solely to tmux only. So any other binary which is using libncurses.so.6 won't be affected.

And what do you know?

Code:
root@macron:/usr/local/bin # ldd tmux
tmux:
        libutil.so.9 => /lib/libutil.so.9 (0x280ec000)
        libulog.so.0 => /lib/libulog.so.0 (0x280fe000)
        libncurses.so.6 => /lib/libncurses.so.8 (0x28101000)
        libtinfo.so.6 => /usr/local/lib/libtinfo.so.6 (0x2813f000)
        libc.so.7 => /lib/libc.so.7 (0x2816a000)
        libmd.so.6 => /lib/libmd.so.6 (0x282e8000)
root@macron:/usr/local/bin # ldd irssi | grep ncurs
        libncurses.so.6 => /usr/local/lib/libncurses.so.6 (0x28648000)
(ignore me for being root here, I just edited /etc/libmap.conf and got lazy ;)).

As you can see: the changes are instant. And this is basically how you do it. Use ldd, and set up a re-route. I used specific names here, you can do the same, but you can also re-map complete pathnames if you so desire.


That's got to be to most helpful reply I've ever been given to a question. Thank you so much!

I wasn't trying to execute libmap.conf. I'm used to having to source config files with Linux to have the system read the modifications without a reboot. Is that not necessary with FreeBSD? I'm sure it's blatantly obvious that I'm new to BSD, but I'm trying to learn the better way. :D
 
I'm used to having to source config files with Linux to have the system read the modifications without a reboot. Is that not necessary with FreeBSD?
The source(1) command is a shell command. It 'sources' shell scripts, i.e. it reads and interprets them. Which, in essence, means you're executing them. This has nothing to do with FreeBSD, it is a function of the shell and it works in exactly the same way on Linux, Solaris, AIX, HP-UX, OS-X and every other UNIX and UNIX-like system, even that odd Ubuntu on Windows stuff.
 
Back
Top