Eurydice
Eurydice

Reputation: 8449

linking an executable against a shared library

I have a basic question from which I could not find the solution around. Say that I build a shared library toto made of the following header and source files:

toto.h

void print();

toto.cpp

#include <iostream>
#include "toto.h"
void print()
{
std::cout<<"WHAT A GREAT LIBRARY"<<std::endl;
}

Based on these file I create my shared library using

g++ -fPIC -shared -I. -c toto.cpp -o libtoto.so

Next, I want to use my freshly created shared library in a test file:

test.cpp

#include "toto.h"

int main()
{
    print();
}

to do so, I link my executable against the shared library using

g++ -I. -L. -ltoto test.cpp

and I get my a.out executable file.

When I do a ldd a.out I get the following output:

linux-vdso.so.1 =>  (0x00007fff322f5000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fb7e7c24000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb7e7865000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fb7e7568000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb7e7f4d000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fb7e7352000)

where I do not see any dependency of my executable on toto shared library. Everything seems like during the link process my library has been statically bound to my executable. This seems confirmed by the fact that I can call a.out from everywhere without setting LD_LIBRARY_PATH to the path where my libtoto.so is stored. Is that actually the case ? If so, what did I missed or misunderstand in the aforementioned commands to reach that point?

FYI, this example was run on ubuntu 12.04, g++ 4.6.3

EDIT:

I could find in the meantime that this code produces a "correct" executable in the sense that the ldd displays a dependency on libtoto shared library and that the executable could not be started without setting the LD_LIBRARY_PATH variable:

g++ -I ./mydylib/ -fpic -c mydylib/toto.cpp -o mydylib/toto.o
g++ -shared -o mydylib/libtoto.so mydylib/toto.o
g++ -I ./mydylib/ -L ./mydylib/ test.cpp -ltoto -o ldd_correct

while this one still produces a "wrong" executable with the aforementionned features:

g++ -I ./mydylib -fpic -shared -c mydylib/toto.cpp -o mydylib/libtoto.so
g++ -I ./mydylib -L ./mydylib test.cpp -ltoto -o ldd_wrong

Upvotes: 3

Views: 5677

Answers (2)

Eurydice
Eurydice

Reputation: 8449

I could finally find the reason for my problem:

When compiling and linking my shared library in a single GCC step, I was adding a wrong -c flag for my toto.cpp source file. This seems to break the build for the executable as you can see by comparing the three following building modes:

Two GCC steps building for the shared library

g++ -I. -fpic -c toto.cpp -o toto.o
g++ -shared -o libtoto.so toto.o
g++ -I. -L. test.cpp -ltoto -o ldd_correct

Single GCC step for building the shared library

g++ -I. -fpic -shared -o libtoto.so toto.cpp
g++ -I. -L. test.cpp -ltoto -o ldd_also_correct

Single GCC step for building the shared library --> the -c breaks something

g++ -I. -fpic -shared -o libtoto.so -c toto.cpp
g++ -I. -L. test.cpp -ltoto -o ldd_wrong

Upvotes: 0

texasflood
texasflood

Reputation: 1633

My guess is because it is such a simple library, it was optimised out. Does it still happen with more complex libraries? Have you tried passing a -O0 flag?

I've tried but I can't reproduce the results - my ldd shows

linux-vdso.so.1 =>  (0x00007fffb79fe000)
libtoto.so (0x00007f8a78316000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8a77f2e000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f8a77c2a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8a7851a000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f8a77924000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f8a7770d000)

On Ubuntu 14.04 gcc version 4.8.2

However, as I expected, g++ -I. -L. -ltoto test.cpp did not work - I had to run g++ -I. -L. test.cpp -ltoto instead.

Upvotes: 1

Related Questions