Apad
Apad

Reputation: 67

ldd on the binary not showing my shared library

I link a shared library on the command line while building an executable. Running ldd on that executable is not showing the linked shared library.

After looking at some of the output of the linker, I have even tried adding the -Wl,--no-as-needed option and that didn't help either.

foo.c:

#include <stdio.h>
void foo () {
    printf ("Hello world\n");
}

main.c:

#include <stdio.h>

int main () {
    printf ("In main \n");
    foo ();
}

Here's the command I used to compile and link:

$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo
/bin/ld: cannot find -lfoo
collect2: error: ld returned 1 exit status

$ gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so

$ ls -l libfoo.so
-rw-r--r-- 1 apple eng 1488 Jun  4 04:44 libfoo.so

$ gcc -Wl,--no-as-needed main.c -o main -L./ -lfoo

$ ldd main
    linux-vdso.so.1 =>  (0x00007fffbdd6c000)
    libc.so.6 => /lib64/libc.so.6 (0x00007f6367e23000)
    /lib64/ld-linux-x86-64.so.2 (0x00005556e268a000)

libfoo.so does not show up above.

$ objdump -x main | grep NEEDED
  NEEDED               libc.so.6

Why isn't libfoo.so showing up as NEEDED?

Upvotes: 4

Views: 3084

Answers (2)

SHG
SHG

Reputation: 2616

By using the gcc option -c you're telling it to create only object from foo.c, so the only product you're getting from this gcc command is an object file. The fact that its suffix is .so is only because you forced it using -o option. If you run this command without -o you'd see that the output is just foo.o - an object file.

If you omit the -c from the gcc command you'd get the shared object you wanted.

Running file on the output file shows the difference (note that I'm not setting the output name using -o and letting gcc use its default names):

With -c:

> gcc -c foo.c -shared
> file foo.o
foo.o: ELF 64-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped

Without -c:

> gcc foo.c -shared
> file a.out
a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=a63581bfc45f845c501ffb6635, not stripped
                                                                  ^^^
                                                                  |||

Upvotes: 1

DYZ
DYZ

Reputation: 57033

This command does not generate a shared library:

gcc -c foo.c -shared -Wl,-soname,libfoo.so -o libfoo.so

It generates an object file libfoo.so that is later statically linked with your code. Proof: remove the lib file, the program will still run.

Solution:

Compile the object file separately, then convert it into a shared library. You will have to tell the loader where to search for the shared libraries by setting LD_LIBRARY_PATH:

gcc -c foo.c 
gcc foo.o -shared -o libfoo.so
gcc main.c -o main -L./ -lfoo
export LD_LIBRARY_PATH=`pwd`
ldd ./main 
#   linux-vdso.so.1 (0x00007ffe0f7cb000)
#   libfoo.so => /home/---/tmp/libfoo.so (0x00007f9bab6ec000)
#   libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f9bab2fb000)
#   /lib64/ld-linux-x86-64.so.2 (0x00007f9babaf0000)

Upvotes: 1

Related Questions