Using linker command line options passed via 'node-gyp' I specify that the library path and library name that I want the program to link with. But the resulting executable does not reference the file I specified, it references a different name in /usr/lib
.
I'm using the libraries section in binding.gyp
to reference a local lib
directory.
'libraries': [
'-lao-oboe',
'-L<(module_root_dir)/lib/',
'-Wl,-rpath-link,<(module_root_dir)/lib/',
'-Wl,-rpath,<(module_root_dir)/lib/'
],
node-gyp
seems to be passing the options correctly because the linker returns /usr/bin/ld: cannot find -la-oboe
if I change the -L
path to one that doesn't contain libao-oboe.so
. The linker also returns an error if I change the name of the requested library to be different than the one in lib
.
The problem is that the local library will not be loaded at runtime. ldd
shows that the node-gyp
output file is not referencing the file that was specified - it is referencing a library with a different name altogether - /usr/lib/liboboe-1.0.so.1
. See the second line of ldd
output:
linux-vdso.so.1 => (0x00007ffee20f5000)
liboboe-1.0.so.1 => /usr/lib/liboboe-1.0.so.1 (0x00007fa476377000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fa475ff5000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fa475c2b000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fa475a27000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa47580a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fa475501000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa476922000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fa4752eb000)
The local library directory contains:
lrwxrwxrwx 1 bruce bruce 15 Sep 8 02:50 libao-oboe.so -> libao-oboe.so.1`
-rw-r--r-- 2 bruce bruce 1640848 Aug 31 15:01 libao-oboe.so.1
It is the case that the local library file, libao-oboe.so.1
is the same as the system library file being referenced in the executable (as shown by ldd
): /usr/lib/liboboe-1.0.so.1
.
Does the linker somehow notice that the local file is the same (via hashing or some signature) and substituting the library file from the standard location?
Why does node-gyp
's output file reference a library file that was never requested as part of the build process?
According to wikipedia - soname the SONAME field in the .so
file is the "base compatible version". It's clear from the behavior I found in the problem above that ld
inserts the SONAME into the file being linked to the shared library - not the filename specified in the ld
command.
Renaming a .so
file doesn't change the SONAME so an executable linked to a renamed file will try to load a library named by the SONAME field, not the filename.
My solution was to not rename the file.