1
votes

I have the following files:

file liba.c

#include <stdio.h>

void foo() {printf("foo\n"); }
void bar() {printf("bar\n"); }

file libb.c

void foo();
void abc() { foo(); }

main.c

void abc();
void foo();
void bar();

int main()
{
   abc();
   foo();
   bar();
}

I am compiling the files as follows:

gcc -shared -fPIC -o liba.so liba.c
gcc -shared -fPIC -Wl,-rpath,. -Wl,--no-undefined -o libb.so libb.c liba.so
gcc -Wl,-rpath,. main.c libb.so

Now the linker reports an error when linking the executable:

/usr/bin/ld: /tmp/cc4De1Xu.o: undefined reference to symbol 'bar'  
./liba.so: error adding symbols: DSO missing from command line  
collect2: error: ld returned 1 exit status  

Now the question is: Why doesn't the linker find the symbol bar? main.c is linked against libb.so which in turn has been linked against liba.so and liba.so does have the symbol bar. Also main.c uses symbol foo and this also resides in liba.so and this is found during linking.

So both symbols, foo and bar, are defined in liba.so but only foo is found during linking. Why?

It looks like only symbols from liba.so are found that are used in libb.so. But why is this the case?

1
without further analysis, last line should read gcc -L. -Wl,-rpath,. -lb main.c - user2371524
This is even worse as it reports abc, foo and bar as undefined since main.c is listed after -lb. Moving -lb after main.c results in the same error message as my invocation above. - Meixner

1 Answers

0
votes

I think it has to do with symbol bar not beeing included in the export table of libb.so but only in liba.so. Why don't you link main.c also against liba.so? Else, declaring void bar(); in libb.c should help..