Shared Library On Solaris 10 using g++ 3.4.3

B

Bala

Hello,

I am trying to create a shared library on solaris. The inputs to this
library is a source file and then 2 static libraries.

I need to call code within the shared library in another application
which in turn will use the static libraries for further processing.

This is the command i am using to build the shared library

g++ -Wno-deprecated -DSOLARIS -DSUN4 -DSUN -DSVR4 -
D_POSIX_PTHREAD_SEMANTICS
-I/usr/java/include -I/usr/java/include/solaris -I/home1/users/biyer/
Bala/OAPI/include
-I/home1/users/biyer/Bala/OAPI/src ../lib/liba ../lib/libb Common.C -o
Common.o

g++ -fpic -D_REENTRANT -shared Common.o -o libSubscribe.so

Though the file that i have included in Common.C has declaration for
the method ULIST_create that i am calling from Common.C, it still
gives me a compilation error
Undefined first referenced
symbol in file
ULIST_create() /var/tmp//ccxiLplo.o

I get similar errors for every method that i am trying to call from
Common.C which are defined in the static libraries.

Am I creating the shared library the way it should be created? Can you
please let me know where its going wrong?

Thanks in advance
 
J

James Kanze

I am trying to create a shared library on solaris. The inputs
to this library is a source file and then 2 static libraries.

First, this is very, very close to being off topic, although it
happens that you've made a generic error---it would be the same
using Sun CC, or under Linux. But implementation specific
issues such as how to invoke the compiler are generally better
discussed in implementation specific groups---a g++ group, in
your case. And shared libraries are very, very implementation
specific (but your problem here doesn't concern shared
libraries).

I note your second sentence, however, because...
I need to call code within the shared library in another
application which in turn will use the static libraries for
further processing.
This is the command i am using to build the shared library
g++ -Wno-deprecated -DSOLARIS -DSUN4 -DSUN -DSVR4 -
D_POSIX_PTHREAD_SEMANTICS
-I/usr/java/include -I/usr/java/include/solaris -I/home1/users/biyer/
Bala/OAPI/include
-I/home1/users/biyer/Bala/OAPI/src ../lib/liba ../lib/libb Common.C -o
Common.o

It doesn't correspond to these commands.

You start by linking in the libraries before the source that
uses them. That cannot work, since code will only be extracted
from a library if it resolves some undefined external, and the
only undefined external you have when you link in ../lib/liba
and ../lib/libb is main (which you have because the compiler
driver automatically links in crt0.o, which uses it, before any
or your files).

Also, the name Common.o is probably not a good one for an
executable. By convention, if the name ends in .o, it should be
an object file.

(If you just wanted to compile, and not link, you need a -c
option. And there's no point in mentionning libraries at this
point, since they aren't considered until linking.)
g++ -fpic -D_REENTRANT -shared Common.o -o libSubscribe.so

Implementation dependent, but I think pretty universal: you have
to link against the shared libraries in the main. Which means
that you'll have to build it first, and add it to the list of
libraries in the preceding line.

Or if one of your mistakes is that you meant to just compile
in the original line, you'll need to mention the libraries here.
In this case, note too that -fpic controls how the compiler
generates code, and must be specified when you compile, not when
you link.

I'd suggest that you find some good description regarding how
compilers work in general---something that explains the
compile/link phases, and read that. Then read the documentation
for g++ (http://www.gnu.org/software/gcc/onlinedocs/)
thoroughly, to see what options are available, and what effect
they have on each phase. (The g++ documentation supposes that
you already know what is meant by preprocessor, compiler and
linker, so you may not be able to understand it until you've got
that straight.)
Though the file that i have included in Common.C has declaration for
the method ULIST_create that i am calling from Common.C, it still
gives me a compilation error
Undefined first referenced
symbol in file
ULIST_create() /var/tmp//ccxiLplo.o

That's an error from the linker, not from the compiler. It
means that the compiler found the declaration in the include
file, but that the linker couldn't find a definition. Given
that all it's seeing after Common.C are the standard libraries,
and ULIST_create() is not in those, this is to be expected.
 
B

Bala

First, this is very, very close to being off topic, although it
happens that you've made a generic error---it would be the same
using Sun CC, or under Linux. But implementation specific
issues such as how to invoke the compiler are generally better
discussed in implementation specific groups---a g++ group, in
your case. And shared libraries are very, very implementation
specific (but your problem here doesn't concern shared
libraries).

I note your second sentence, however, because...


It doesn't correspond to these commands.

You start by linking in the libraries before the source that
uses them. That cannot work, since code will only be extracted
from a library if it resolves some undefined external, and the
only undefined external you have when you link in ../lib/liba
and ../lib/libb is main (which you have because the compiler
driver automatically links in crt0.o, which uses it, before any
or your files).

Also, the name Common.o is probably not a good one for an
executable. By convention, if the name ends in .o, it should be
an object file.

(If you just wanted to compile, and not link, you need a -c
option. And there's no point in mentionning libraries at this
point, since they aren't considered until linking.)


Implementation dependent, but I think pretty universal: you have
to link against the shared libraries in the main. Which means
that you'll have to build it first, and add it to the list of
libraries in the preceding line.

Or if one of your mistakes is that you meant to just compile
in the original line, you'll need to mention the libraries here.
In this case, note too that -fpic controls how the compiler
generates code, and must be specified when you compile, not when
you link.

I'd suggest that you find some good description regarding how
compilers work in general---something that explains the
compile/link phases, and read that. Then read the documentation
for g++ (http://www.gnu.org/software/gcc/onlinedocs/)
thoroughly, to see what options are available, and what effect
they have on each phase. (The g++ documentation supposes that
you already know what is meant by preprocessor, compiler and
linker, so you may not be able to understand it until you've got
that straight.)


That's an error from the linker, not from the compiler. It
means that the compiler found the declaration in the include
file, but that the linker couldn't find a definition. Given
that all it's seeing after Common.C are the standard libraries,
and ULIST_create() is not in those, this is to be expected.

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Hi,

I was able to create the shared libraries and run it properly. Thanx
for all the help. But i cant g o ahead with g++ because one of those
static libraries has been compiled with Sun studio CC 5.8. The mangled
names are too different and it gives me runtime errors while trying to
resolve those.

I planned to move my application to CC instead but this is giving me
another strange problem.
I created a shared library using CC with the following command

CC -G -D_REENTRANT -DSOLARIS -DSUN4 -DSUN -DSVR4 -
D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
solaris -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/
Bala/OAPI/src Common.cpp liba.a libb.b -o libSubscribe.so

Then i compiled my source as
CC -DSOLARIS -DSUN4 -DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/home1/
users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/src
Main.cpp -o Main.o

Now when i run Main.o it says its not able to open the shared
library. It prints an error message which is part of my code. "Error
Loading the Dynamic Library"

I am also attaching the sample code in here.. The path of the library
that i have mentioned is correct since the same code works fine with g+
+ created shared library.

Please let me know if i need to do something differently if i am using
CC.

Main.cpp
--------
#include <iostream>
#include <Common.h>
#include <dlfcn.h>
#include <link.h>
#include <stdio.h>

using namespace std;

int main ()
{
void *handle;
void (*fptr)();
handle = dlopen ("./libSubscribe.so", RTLD_GLOBAL | RTLD_LAZY);
if (handle == NULL)
printf ("\nError Loading the Dynamic Library\n");
else
{
printf ("\n Library Loaded Successfully\n");
fptr = (void (*) ()) dlsym (handle, "OAPI_main");
if (fptr)
{
(*fptr)();
printf ("\n OAPI_Main Called\n");
}
else
{
printf ("\nCould not find method\n");
}
}
return (0);
}
 
J

James Kanze

[...]
I was able to create the shared libraries and run it properly. Thanx
for all the help. But i cant g o ahead with g++ because one of those
static libraries has been compiled with Sun studio CC 5.8. The mangled
names are too different and it gives me runtime errors while trying to
resolve those.

Not just the mangled names. The class layout is different as
well. The mangled names are intentionally different, because if
you could link, all you'd get is a core dump (or some other
strange behavior) at runtime.
I planned to move my application to CC instead but this is
giving me another strange problem.

Be very, very careful. The libraries (both alternatives)
available with CC are really bad.
I created a shared library using CC with the following command
CC -G -D_REENTRANT -DSOLARIS -DSUN4 -DSUN -DSVR4 -
D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
solaris -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/
Bala/OAPI/src Common.cpp liba.a libb.b -o libSubscribe.so
Then i compiled my source as
CC -DSOLARIS -DSUN4 -DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/home1/
users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/src
Main.cpp -o Main.o
Now when i run Main.o it says its not able to open the shared
library. It prints an error message which is part of my code.
"Error Loading the Dynamic Library"

This is really getting off topic, but what does dlerr() say?

Just a hunch, however: you need a -ldl at the end of your link
line. Otherwise, you just get stubs for dlopen et al. (I'll
admit that I don't understand this. By default, the system
libraries are loaded dynamically, so the guts of libdl must be
there, even if you don't specify it.)

Maybe the g++ driver adds this automatically. (I have it in my
Linux builds with g++, however. I don't know if it's necessary,
however. I know I needed it once, and I probably just threw it
in everywhere.)
 
B

Bala

On Nov 8, 8:50 pm, Bala <[email protected]> wrote:
[...]

I was able to create the shared libraries and run it properly. Thanx
for all the help. But i cant g o ahead with g++ because one of those
static libraries has been compiled with Sun studio CC 5.8. The mangled
names are too different and it gives me runtime errors while trying to
resolve those.

Not just the mangled names. The class layout is different as
well. The mangled names are intentionally different, because if
you could link, all you'd get is a core dump (or some other
strange behavior) at runtime.
I planned to move my application to CC instead but this is
giving me another strange problem.

Be very, very careful. The libraries (both alternatives)
available with CC are really bad.
I created a shared library using CC with the following command
CC -G -D_REENTRANT -DSOLARIS -DSUN4 -DSUN -DSVR4 -
D_POSIX_PTHREAD_SEMANTICS -I/usr/java/include -I/usr/java/include/
solaris -I/home1/users/biyer/Bala/OAPI/include -I/home1/users/biyer/
Bala/OAPI/src Common.cpp liba.a libb.b -o libSubscribe.so
Then i compiled my source as
CC -DSOLARIS -DSUN4 -DSUN -DSVR4 -D_POSIX_PTHREAD_SEMANTICS -I/home1/
users/biyer/Bala/OAPI/include -I/home1/users/biyer/Bala/OAPI/src
Main.cpp -o Main.o
Now when i run Main.o it says its not able to open the shared
library. It prints an error message which is part of my code.
"Error Loading the Dynamic Library"

This is really getting off topic, but what does dlerr() say?

Just a hunch, however: you need a -ldl at the end of your link
line. Otherwise, you just get stubs for dlopen et al. (I'll
admit that I don't understand this. By default, the system
libraries are loaded dynamically, so the guts of libdl must be
there, even if you don't specify it.)

Maybe the g++ driver adds this automatically. (I have it in my
Linux builds with g++, however. I don't know if it's necessary,
however. I know I needed it once, and I probably just threw it
in everywhere.)

--
James Kanze (GABI Software) email:[email protected]
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Haha. I tried that already but doesnt seem to work. I looked at
dlerror() and it says it couldnt find a referenced symbol. the name
of the symbol is mangled. And since the static libraries that i am
using are external, i dont have the source code to find out where and
how its declared. I just linked the static libraries while creating
the shared library using the above command. Not sure though which way
to go ahead :)
 
J

James Kanze

On Nov 8, 8:50 pm, Bala <[email protected]> wrote:
[...]
This is really getting off topic, but what does dlerr() say?
[...]
Haha. I tried that already but doesnt seem to work. I looked at
dlerror() and it says it couldnt find a referenced symbol.

After dlopen()?
the name of the symbol is mangled. And since the static
libraries that i am using are external, i dont have the source
code to find out where and how its declared.

nm libxxx.so | egrep symbol

can be useful in such cases. There is also c++filt, to
demangle. You might try demangling, and greping for the
demangled name in the libs. Just in case the symbol is actually
in C code, but the declaration you pulled in didn't have the
``extern "C"'' linkage specification.

Another possibility is that the library was compiled with a
different compiler, and so mangles differently. (Sun CC
supports at least two different conventions: see the -compat=4
option. Or one of the libraries was compiled with g++; this
would explain why there was no problem with g++.)
I just linked the static libraries while creating the shared
library using the above command. Not sure though which way to
go ahead :)

It sounds like you're in the Unix version of DLL-hell:). The
worst thing about it is that if you get it to work on your
platform, it still might not work when deployed, because one of
the shared objects it depends on doesn't have the same version.
In my experience, you should make very, very sparing use of
shared objects, limiting their use to cases where it actually
has some necessary advantage.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,992
Messages
2,570,220
Members
46,807
Latest member
ryef

Latest Threads

Top