Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to build a shared library (.so) without hardcoded full dependency paths?

I need to build two 3rd party shared libraries, so their .so files will be reused by other projects. However, after build one of these libraries contains hardcoded path to another. This path is invalid on other machines and causes linker warnings. How can I prevent the full path from being embedded in the resulting .so files?

Details:

First library source: ~/dev/A
Second library source: ~/dev/B

Both of them have configure script to generate make files. Library B depends on A. So, first I build A:

$ ~/dev/A/configure --prefix=~/dev/A-install
$ make && make install

Then I build B:

$ ~/dev/B/configure --prefix=~/dev/B-install --with-A=~/dev/A-install
$ make && make install

Then I want to upload the contents of ~/dev/A-install and ~/dev/B-install to our file server, so other teams and build machines can use the binaries. But they get linker warnings when they try to use B:

/usr/bin/ld: warning: libA.so.2, needed by /.../deps/B/lib/libB.so, not found (try using -rpath or -rpath-link)

When I run ldd libB.so it gives:

...
libA.so.2 => /home/alex/dev/A-install/lib/libA.so.2

Obviously this path exists only on my machine and cannot be found on other machines.

How can I remove full hardcoded path from libB.so?

Thanks.

like image 746
Alex Blekhman Avatar asked Oct 27 '11 04:10

Alex Blekhman


People also ask

How are shared libraries loaded?

Static Libraries are linked into a compiled executable (or another library). After the compilation, the new artifact contains the static library's content. Shared Libraries are loaded by the executable (or other shared library) at runtime.


1 Answers

You have to use --prefix value that will be valid in the runtime environment for both packages!

Than you override prefix or DESTDIR (prefix replaces the prefix, DESTDIR is prepended to it, but works more reliably) on the make command-line when installing. Like:

~/dev/A$ ./configure
~/dev/A$ make 
~/dev/A$ make install prefix=~/dev/A-install
~/dev/B$ ./configure --with-A=~/dev/A-install
~/dev/B$ make
~/dev/B$ make install prefix=~/dev/B-install

or (which is preferred and is how all package-building tools use it):

~/dev/A$ ./configure
~/dev/A$ make 
~/dev/A$ make install DESTDIR=~/dev/A-install
~/dev/B$ ./configure --with-A=~/dev/A-install/usr/local
~/dev/B$ make
~/dev/B$ make install prefix=~/dev/B-install

because this way you are installing to ~/dev/A-install/$prefix, so with default prefix ~/dev/A-install/usr/local. The advantage of this later option is, that if you redefine some specific installation paths without refering to prefix (say --sysconfdir=/etc), DESTDIR will still get prepended to it, while it won't be affected by prefix.

like image 150
Jan Hudec Avatar answered Oct 05 '22 13:10

Jan Hudec