I'm trying to compile gnupg-2.1.0 for Debian Wheezy, I've downloaded and compiled the required libraries (libgpg-error-1.17
, libgcrypt-1.6.2
, libksba-1.3.2
, libassuan-2.1.3
, and pth-2.0.7
in that order) via ./configure
, make
, make install
. I then added /usr/local/lib
to /etc/ld.so.conf
and then ran ldconfig
so that gnupg could find the libraries.
Gpupg compiles fine but upon attempting to run either ./agent/gpg-agent
or ./g10/g
I am greated with this error:
alpha@virtual:~/gnupg-2.1.0$ ./agent/gpg-agent --version
./agent/gpg-agent: /lib/i386-linux-gnu/libgpg-error.so.0: no version information available (required by ./agent/gpg-agent)
./agent/gpg-agent: /lib/i386-linux-gnu/libgpg-error.so.0: no version information available (required by /usr/local/lib/libgcrypt.so.20)
./agent/gpg-agent: relocation error: ./agent/gpg-agent: symbol gpgrt_set_alloc_func, version GPG_ERROR_1.0 not defined in file libgpg-error.so.0 with link time reference
ldd ./agent/gpg-agent
produces
root@virtual:/home/alpha/gnupg-2.1.0# ldd ./agent/gpg-agent
./agent/gpg-agent: /lib/i386-linux-gnu/libgpg-error.so.0: no version information available (required by ./agent/gpg-agent)
./agent/gpg-agent: /lib/i386-linux-gnu/libgpg-error.so.0: no version information available (required by /usr/local/lib/libgcrypt.so.20)
linux-gate.so.1 => (0xb7750000)
libgcrypt.so.20 => /usr/local/lib/libgcrypt.so.20 (0xb7698000)
libgpg-error.so.0 => /lib/i386-linux-gnu/libgpg-error.so.0 (0xb7694000)
libassuan.so.0 => /usr/lib/i386-linux-gnu/libassuan.so.0 (0xb7681000)
libnpth.so.0 => /usr/local/lib/libnpth.so.0 (0xb767d000)
libpthread.so.0 => /lib/i386-linux-gnu/i686/cmov/libpthread.so.0 (0xb7664000)
libc.so.6 => /lib/i386-linux-gnu/i686/cmov/libc.so.6 (0xb74ff000)
librt.so.1 => /lib/i386-linux-gnu/i686/cmov/librt.so.1 (0xb74f6000)
/lib/ld-linux.so.2 (0xb7751000)
Why is this error occuring and how could I fix it?
Resolution
Resolved by adding /usr/local/lib to LD_LIBRARY_PATH via export LD_LIBRARY_PATH=/usr/local/lib:${LD_LIBRARY_PATH}
and echo /usr/local/lib > /etc/ld.so.conf.d/local.conf
Best Answer
Root cause of problem
The error is occurring because at compile time, it is properly searching the
/usr/local/lib
path before it is searching the system default path, thus at link time, all symbols resolve. However at runtime, your/usr/local/lib
path is not searched before the pre-existing/lib/i386-linux-gnu
so it is finding the identically named library in the latter directory before your desired library in/usr/local/lib
.Solution, easy version: Global library search path (with caveat)
The easy version is to insert
/usr/local/lib
in yourLD_LIBRARY_PATH
environment variable or/etc/ld.so.conf
config then runldconfig
. For the "fast" solution, you want/usr/local/lib
before anything else.However, this is the unfortunate bit, you do not want to force all of your programs to search
/usr/local/lib
before the system library path (eg:/lib/i386-linux-gnu
) -- this makes it highly likely you will cause a version conflict with a system library used by another program provided by your system or package manager and cause the system program to fail. This means to "do things right", you do not want to useLD_LIBRARY_PATH
,LD_PRELOAD
or/etc/ld.so.conf
to force your search path. (In fact,LD_PRELOAD
should be avoided outside of development work)Solution, stable version: Update ELF RPATH
Instead, when compiling your own versions of applications, you can use the
LD_RUN_PATH
environment variable (gnu ld & gold) or settingLDFLAGS
to-Wl,-rpath /usr/local/lib
to manage the internal library-search-path of your binaries (including .so shared library dependencies)So for example, you could run the following to configure your library:
My experience with this technique has been on HP-UX where the
chatr
utility will show you the embedded rpath (and the link flag is+b
instead of -rpath).readelf
orobjdump
will probably show the rpath on linux.patchelf claims to be able to update the rpath in existing binaries on linux x86, but I haven't tested it myself.