# shared libraries



## balanga (Jun 4, 2018)

How does a program find shared libraries, and how do I specify alternative search locations?


----------



## shkhln (Jun 4, 2018)

See ld-elf.so man page.


----------



## SirDice (Jun 4, 2018)

Start here: 
https://en.wikipedia.org/wiki/Dynamic_linker
https://en.wikipedia.org/wiki/Dynamic_loading


----------



## debguy (Jun 26, 2018)

for linux elf?

nm(1)

objdump(1)

> how do I specify alternative search locations

you can't
linux has "RPATH" embedded as an option HARD to remove in almost of of it's libs (i know: i successfully removed them and it requires a special ld wrapper script)

you can edit and re-compile LD to ignore rpath, might be an easier way to get around it.  you may need this if you want to change the default path search order (which is different from mandatory file location), because LD has "/lib /usr/lib" compiled statically as a string it doesn't allow replaced.  i'm unsure if you also have to hack ldconfig for the same static string - perhaps both.


----------



## debguy (Jun 26, 2018)

i made gdeptrace, it's for analysing depends, it would trace a whole lib system and order it if given the right (nm) input.

but NOTE: depends are subjective (half human made) and aren't "real" (don't tell the whole story).  next note that compiling options (for ports) can RADICALLY CHANGE depends, softening them wholey or making them a total B**tch which (ubutnut) tends to do.

libs can be static (no depends, builtin to app, Apple BSD likes these though they take more space) or linked.  any user who hates "dll hell" likes static, per say.

NEXT NOTE: gnu lib system (linux - unsure about freeBSD) with ld(1) are horrific complicated.  libc shares memory with all "daughter libc" (instead of using a petty 1M to have a fresh libc for each app running, and yes - there are security issues resulting of one app breaching the other's libc), it has hooks in for tracers (which can be used to root system remotely on boot), marks regions of application for sharing memory between unfriendly apps or not by "hints" even if app doesn't hint: and expected ... has bugs, while also marking for non-sharing what - in unix - used to be shared by default (all apps a particular user runs as the same login name running) (these now need special libs and hints to share, where before they didn't). but how do you know what got marked which way?  it's really damn complex and you don't.

MOSTLY NOTE: the ld(1) system allows "gnu configure / make" scripts to BYPASS everything like this: replace all calls for a compile program (say printf) with a different function call (so your looking at code thinking, ok simple this codes prints to screen, when actually code after substitution can read: ET PHONE HOME here). it's done at the label/linker level, everything is "hacker friendly"

(keep in mind i was speaking of linux and am %100 correct, linux wise)

SO SLEEP WELL.  forgetta bout it.  libs are not simple and "knowable" like they were in the COFF days.  the good news is if you use freeBSD you have the source and have a chance to know if an app is "marking regions, making linker substitutions"

the best your gonna do here is "get the right depends" which the port should have already installed.  perhaps use a port who's depends isn't broken (assuming your not making a new port)


----------



## shkhln (Jun 26, 2018)

debguy said:


> linux has "RPATH" embedded as an option HARD to remove in almost of of it's libs




Not true, it's relatively rare:

```
% readelf -d /compat/linux/lib64/*.so* | grep File | wc -l
     478
% readelf -d /compat/linux/lib/*.so* | grep File | wc -l
     507
% readelf -d /compat/linux/lib64/*.so* | grep -i rpath | wc -l
      18
% readelf -d /compat/linux/lib/*.so* | grep -i rpath | wc -l
       2
```




debguy said:


> (i know: i successfully removed them and it requires a special ld wrapper script)




https://nixos.org/patchelf.html


----------



## debguy (Jun 29, 2018)

It's in everything that matters in (/lib and many /usr/lib) in (debian) and not rare.  Perhaps it is "less rare" in freeBSD's support of 'lxrun' (run linux under BSD kernel).

But your idea that "if it's only a few" is wrong.  It is either on all libs that matter or none.  'Only on a few that mattered' would be a release error.


----------



## shkhln (Jun 29, 2018)

There are exactly zero ideas in my post above, it's merely a reaction. I would also _gladly_ point out bullshit in your second post, but it is almost incomprehensible. (Thus something other people are not likely to read and not worth disproving. Sorry.)


----------



## Crivens (Jun 29, 2018)

debguy could you please come to grips with the fact that this here is not linux land? Whatever unholy mess glibc is, it does not apply here. Whatever linux memory management does under ubuntu does apply neither. When it comes to sharing dynamic libs, that is done completely by the vm system. You should read it, if you find the time. Nice OO design in plain C.


----------



## jrlevine (Jun 21, 2022)

Just in case anyone was wondering, the answer is that you set the environment variable LD_LIBRARY_PATH to the list of places to look for your libraries. Also look at the ld.so man page for the LD_LIBRARY_PATH_RPATH which lets you override locations set at static link time.


----------



## Holger (Jun 22, 2022)

The Plan 9 operating system show-cased a system without any of the shared-library-madness. Still my wet-dream up to this day.


----------



## Paul Floyd (Jun 22, 2022)

Don't use LD_LIBRARY_PATH. It is a sticking plaster for broken designs. IMO LD_LIBRARY_PATH goes against the UNIX philosophy of having things work out of the box. It's more of a Linuxism where guarding against breakages is a way of life.

If your application uses 'execve()' in any form then you will be inflicting your LD_LIBRARY_PATH on any child processes. That may force the child process to use a wrapper to remove or replace your LD_LIBRARY_PATH. "Freedom" to break any and all child processes is not a big advantage in my book.

I would recommend (assuming that you don't plan to let end users install executables and shared libraries to random directories)
1. Use RPATH and a relative $ORIGIN. This just works. It also insulates your application from breakage by LD_LIBRARY_PATH. Some limitations when running as root though.
2. Use RUNPATH and a relative $ORIGIN. As above, but no longer insulates your application from LD_LIBRARY_PATH breakage.
3. Absolute last resort, use LD_LIBRARY_PATH in a script.

If you do use an absolute R(UN)PATH then you will have to always install there - installing elsewhere will either break things or force the use of LD_LIBRARY_PATH.

I'm not too sure how to get point 1 with ld.lld. --rpath seems to set RUNPATH not RPATH by default. I need to do some testing and will update.

So if you use clang++ as your linker driver then something like

clang++ -o app app.o -L mylibdir -lmylib -rpath $$ORIGIN/../lib -Wl,--disable-new-tags

might do the trick.

and then install to destdir/bin/app and destdir/lib/libmylib.so


----------



## Alain De Vos (Jun 22, 2022)

I have

```
export LIBRARY_PATH=/usr/local/lib
```
Is it good for something ? Or which environment variables are used for what ?


----------

