Ian Liu Rodrigues
Ian Liu Rodrigues

Reputation: 642

Symbol is lost after linking shared library

Consider the two files listed below:

file a.c

extern int foovar;
int foobarize() {
    return foovar * foovar;
}

and file b.c

int foovar = 10;

I compile the static library liba.a and the shared library libb.so as follows:

# liba.a
gcc -fPIC -c a.c -o a.o
ar cr liba.a a.o
ranlib liba.a

# libb.so
gcc -fPIC -c b.c -o b.o
gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o liba.a

Note that the function foobarize defined in a.c is present in liba.a but it isn't present in libb.so. I can guarantee that by issuing the nm program:

$ nm liba.a

a.o:
0000000000000000 T foobarize
                 U foovar
                 U _GLOBAL_OFFSET_TABLE_

$ nm libb.so
000000000020088c B __bss_start
000000000020088c b completed.6617
                 w __cxa_finalize@@GLIBC_2.2.5
0000000000000530 t deregister_tm_clones
00000000000005c0 t __do_global_dtors_aux
0000000000200650 t __do_global_dtors_aux_fini_array_entry
0000000000200880 d __dso_handle
0000000000200660 d _DYNAMIC
000000000020088c D _edata
0000000000200890 B _end
0000000000000630 T _fini
0000000000200888 D foovar
0000000000000600 t frame_dummy
0000000000200648 t __frame_dummy_init_array_entry
0000000000000640 r __FRAME_END__
0000000000200858 d _GLOBAL_OFFSET_TABLE_
                 w __gmon_start__
00000000000004d8 T _init
                 w _ITM_deregisterTMCloneTable
                 w _ITM_registerTMCloneTable
0000000000200658 d __JCR_END__
0000000000200658 d __JCR_LIST__
                 w _Jv_RegisterClasses
0000000000000570 t register_tm_clones
0000000000200890 d __TMC_END__

How can I get the foobarize function in the libb.so shared library?

Upvotes: 2

Views: 1195

Answers (1)

n. m. could be an AI
n. m. could be an AI

Reputation: 119847

What you need:

# force all symbols

gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
           -Wl,--whole-archive liba.a -Wl,--no-whole-archive

#force just a specific symbol

gcc -fPIC -shared -Wl,-soname,libb.so -o libb.so b.o \
           -u foobarize liba.a

Why you need it:

A static library is a simple collection of object files. The one major difference from a bunch of object files is the following: when an undefined symbol needs to be resolved, the library is searched and only the object file that actually defines the symbol is linked. No undefined symbols? Nothing is searched, nothing is linked. To override this default behaviour, the GNU linker implements --whole-archive. Most linkers implement -u to force a particular symbol to be treated as undefinmed.

Upvotes: 5

Related Questions