views:

79

answers:

2

I have a shared library "libwiston.so". I am using this to create another shared library called "libAnimation.so", which will be used by another project. Now, the second library "libAnimation.so" can't be used in test code correctly. So I doubt that the creation of the second lib "libAnimation.so" is right. The gcc command to create this lib is "g++ -g -shared -Wl,-soname,libwiston.so -o libAnimation.so $(objs) -lc". Has someone come across this problem?

+2  A: 

That looks like a weird link line - you are creating libAnimation.so, but its internal DT_SONAME name is libwiston.so.

I don't think that what you wanted to do. Don't you want to link libAnimation.so against libwiston.so (-lwiston)?

g++ -g -shared -o libAnimation.so $(objs) -lc -lwiston

I think it would be easier to wrap your build in automake/autoconf and rely on libtool to get the shared library creation correct.

Douglas Leeder
Thank you very much, I tested this command, but I will use automake/autoconf to create this shared lib
mpouse
@mpouse check for some libwiston stuff copypasted for libAnimation in your Makefile.am
Dmitry Yudakov
A: 

I'll do a humble review on the process of creating shared libraries.

Let's begin by creating libwiston.so. First we implement the function we would like to export and then define it on a header so other programs knows how to call it.

/* file libwiston.cpp
 * Implementation of hello_wiston(), called by libAnimation.so
 */
#include "libwiston.h"

#include <iostream>

int hello_wiston(std::string& msg)
{
    std::cout << msg << std::endl;

    return 0;
}

and:

/* file libwiston.h
 * Exports hello_wiston() as a C symbol.
 */
#include <string>

extern "C" {
int hello_wiston(std::string& msg);
};

This code can be compiled with: g++ libwiston.cpp -o libwiston.so -shared

Now we implement the second shared library, named libAnimation.so that calls the function exported by the first library.

/* file libAnimation.cpp
 * Implementation of call_wiston(). 
 * This function is a simple wrapper around hello_wiston().
 */
#include "libAnimation.h"
#include "libwiston.h"

#include <iostream>

int call_wiston(std::string& param)
{
    hello_wiston(param);

    return 0;
}

and header:

/* file libAnimation.h
 * Exports call_wiston() as a C symbol.
 */
#include <string>

extern "C" {
int call_wiston(std::string& param);
};

Compile it with: g++ libAnimation.cpp -o libAnimation.so -shared -L. -lwiston

Finally, we create a small application to test libAnimation.

/* file demo.cpp
 * Implementation of the test application.
 */
#include "libAnimation.h"
int main()
{
    std::string msg = "hello stackoverflow!";
    call_wiston(msg);
}

And compile it with: g++ demo.cpp -o demo -L. -lAnimation

There's an interesting tool named nm that you can use to list the symbols exported by your shared library. Using these examples, you could execute the following commands to check for the symbols:

nm libAnimation.so | grep call_wiston

outputs:

00000634 t _GLOBAL__I_call_wiston
000005dc T call_wiston

and also:

nm libwiston.so | grep hello_wiston

outputs:

0000076c t _GLOBAL__I_hello_wiston
000006fc T hello_wiston
karlphillip
@karlphillip I think the linking of the application will fail with undefined reference to `hello_wiston` if you don't link it to `libwiston.so`. It would work though if you had `libwiston.a`.
Dmitry Yudakov
@Dmitry The linking will succeed and the demo will work! The only binary that needs to be linked with libwiston.so is libAnimation and that's being done.
karlphillip
@karlphillip What system you've tested it on? On debian gcc-4.4.5, ld-2.20.1 it gives `./libAnimation.so: undefined reference to `hello_wiston'` like I mentioned.
Dmitry Yudakov
@Dmitry Ubuntu 10.04 and gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
karlphillip