|
|
Versioning a C++ Shared Object
I have C++ objects in a shared object which I would like to version. I
used nm to get the mangled names of the functions and have added them
to my mapfile. When I link the shared object I get no errors, yet when
I try to link the executable that has the dependency I get an error
saying that it cannot find a referenced symbol with a list of the
symbols I was trying to reference. I am using CC.
Here is the mapfile:
MDSMsgFact_1.1
{
global:
__1cPMsgFactoryTableLgetInstance6F_r0_;
local:
*;
};
Here is the error I get when I try to link my executable:
Undefined first referenced
symbol in file
MsgFactoryTable&MsgFactoryTable::getInstance()
obj/32d/MsgFactoryTest.o
ld: fatal: Symbol referencing errors. No output written to
bin/32d/MsgFactoryTest
Thanks,
Gregg
|
|
0
|
|
|
|
Reply
|
galtschul768 (3)
|
9/13/2004 7:53:30 PM |
|
Gregg Altschul <galtschul@factset.com> wrote:
> I have C++ objects in a shared object which I would like to version. I
> used nm to get the mangled names of the functions and have added them
> to my mapfile. When I link the shared object I get no errors, yet when
> I try to link the executable that has the dependency I get an error
> saying that it cannot find a referenced symbol with a list of the
> symbols I was trying to reference. I am using CC.
>
> Here is the mapfile:
> MDSMsgFact_1.1
> {
> global:
> __1cPMsgFactoryTableLgetInstance6F_r0_;
>
> local:
> *;
> };
>
> Here is the error I get when I try to link my executable:
>
> Undefined first referenced
> symbol in file
> MsgFactoryTable&MsgFactoryTable::getInstance()
> obj/32d/MsgFactoryTest.o
> ld: fatal: Symbol referencing errors. No output written to
> bin/32d/MsgFactoryTest
>
>
> Thanks,
>
> Gregg
What you described here seems to be largely correct.
I'd check whether the correct library is in the search path.
Since ld didn't say it can not find the library,
presumably it found all libraries in the dependency list.
If the symbol is actually defined and global in the library,
then the only other way to see the above failure
is for ld to find a different library with the same name
in its library search path
(assuming correct -l/-L flags are passed to the linker).
You can check using nm against your shared object
to see if the method is really defined and global.
Following is an example of creating a C++ shared library with versioning:
$ cat t.cc
class myclass {
public:
int mymethod(void);
int secondmethod(void);
};
int myclass::mymethod(void) { return 2; }
int myclass::secondmethod(void) { return 3; }
$ cat map
myclass_1.1 {
global:
__1cHmyclassImymethod6M_i_;
local:
*;
};
$ CC -G -M map -o libt.so.1 t.cc
$ nm libt.so.1 | grep myclass
[54] | 1176| 40|FUNC |GLOB |0 |8 |__1cHmyclassImymethod6M_i_
[26] | 1232| 40|FUNC |LOCL |2 |8 |__1cHmyclassMsecondmethod6M_i_
[44] | 0| 0|OBJT |GLOB |0 |ABS |myclass_1.1
$ ln -s libt.so.1 libt.so
$ cat m.cc
class myclass {
public:
int mymethod(void);
int secondmethod(void);
};
int main() {
myclass *p = new myclass();
return p->mymethod();
}
$ CC m.cc -L. -R. -lt -Qoption ld -Dfiles
debug:
debug: file=/set/dist/sparc-S2/prod/lib/crti.o [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/CCrti.o [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/crt1.o [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/misalign.o [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/values-xa.o [ ET_REL ]
debug:
debug: file=m.o [ ET_REL ]
debug:
debug: file=./libt.so [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/lib/v8plus/libCstd.so [ ET_DYN ]
debug:
debug: file=/set/dist/sparc-S2/lib/libCrun.so [ ET_DYN ]
debug:
debug: file=/lib/libm.so [ ET_DYN ]
debug:
debug: file=/lib/libc.so [ ET_DYN ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/CCrtn.o [ ET_REL ]
debug:
debug: file=/set/dist/sparc-S2/prod/lib/crtn.o [ ET_REL ]
debug:
debug: file=/lib/libdl.so.1 [ ET_DYN ]
debug:
debug:
debug:
$ ./a.out
$ echo $?
2
$ CC m.cc -L. -R. -lt -Qoption ld -Dsymbols,-Dlibs,-Dfiles > ld.log 2>&1
$ less ld.log
.....
debug: symbol table processing; input file=m.o [ ET_REL ]
debug: symbol[1]=m.cc
debug: symbol[2]=int myclass::mymethod() (global); adding
debug: symbol[3]=void*operator new(unsigned) (global); adding
debug: symbol[4]=main (global); resolving [7][0]
debug: symbol[5]=__fsr_init_value (global); resolving [7][0]
debug: Library Search Paths (-L updated)
debug: .
debug: /set/dist/sparc-S2/lib/rw7
debug: /set/dist/sparc-S2/lib/v8plus
debug: /set/dist/sparc-S2/prod/lib/rw7
debug: /set/dist/sparc-S2/prod/lib/v8plus
debug: /set/dist/sparc-S2/lib
debug: /set/dist/sparc-S2/prod/lib
debug: /usr/ccs/lib
debug: /lib
debug: /usr/lib
debug:
debug: file=./libt.so [ ET_DYN ]
debug:
debug: symbol table processing; input file=./libt.so [ ET_DYN ]
debug: symbol[3]=myclass_1.1 (global); adding
debug: symbol[4]=void __Cimpl::cplus_init() (global); resolving [16][1]
debug: symbol[7]=void __Cimpl::cplus_fini() (global); resolving [16][1]
debug: symbol[8]=_ex_register (global); resolving [16][1]
debug: symbol[9]=_ex_deregister (global); resolving [16][1]
debug: symbol[10]=void __Crun::do_exit_code_in_range(void*,void*) (global); resolving [16][1]
debug: symbol[11]=_get_exit_frame_monitor (global); resolving [16][1]
debug: symbol[13]=int myclass::mymethod() (global); resolving [16][0]
debug: symbol[14]=atexit (global); resolving [16][1]
debug:
debug: file=/set/dist/sparc-S2/lib/v8plus/libCstd.so [ ET_DYN ]
....
Maybe I'm completely overlooking some detail but it should work...
--
#pragma ident "Seongbae Park, compiler, http://blogs.sun.com/seongbae/"
|
|
0
|
|
|
|
Reply
|
Seongbae
|
9/13/2004 11:20:41 PM
|
|
Seongbae Park <Seongbae.Park@Sun.COM> wrote in message news:<ci5a09$9a3$1@news1nwk.SFbay.Sun.COM>...
> Gregg Altschul <galtschul@factset.com> wrote:
> > I have C++ objects in a shared object which I would like to version. I
> > used nm to get the mangled names of the functions and have added them
> > to my mapfile. When I link the shared object I get no errors, yet when
> > I try to link the executable that has the dependency I get an error
> > saying that it cannot find a referenced symbol with a list of the
> > symbols I was trying to reference. I am using CC.
> >
> > Here is the mapfile:
> > MDSMsgFact_1.1
> > {
> > global:
> > __1cPMsgFactoryTableLgetInstance6F_r0_;
> >
> > local:
> > *;
> > };
> >
> > Here is the error I get when I try to link my executable:
> >
> > Undefined first referenced
> > symbol in file
> > MsgFactoryTable&MsgFactoryTable::getInstance()
> > obj/32d/MsgFactoryTest.o
> > ld: fatal: Symbol referencing errors. No output written to
> > bin/32d/MsgFactoryTest
> >
> >
> > Thanks,
> >
> > Gregg
>
> What you described here seems to be largely correct.
> I'd check whether the correct library is in the search path.
> Since ld didn't say it can not find the library,
> presumably it found all libraries in the dependency list.
> If the symbol is actually defined and global in the library,
> then the only other way to see the above failure
> is for ld to find a different library with the same name
> in its library search path
> (assuming correct -l/-L flags are passed to the linker).
>
> You can check using nm against your shared object
> to see if the method is really defined and global.
>
>
> Following is an example of creating a C++ shared library with versioning:
>
> $ cat t.cc
> class myclass {
> public:
> int mymethod(void);
> int secondmethod(void);
> };
>
> int myclass::mymethod(void) { return 2; }
> int myclass::secondmethod(void) { return 3; }
> $ cat map
> myclass_1.1 {
> global:
> __1cHmyclassImymethod6M_i_;
>
> local:
> *;
> };
> $ CC -G -M map -o libt.so.1 t.cc
> $ nm libt.so.1 | grep myclass
> [54] | 1176| 40|FUNC |GLOB |0 |8 |__1cHmyclassImymethod6M_i_
> [26] | 1232| 40|FUNC |LOCL |2 |8 |__1cHmyclassMsecondmethod6M_i_
> [44] | 0| 0|OBJT |GLOB |0 |ABS |myclass_1.1
> $ ln -s libt.so.1 libt.so
> $ cat m.cc
>
> class myclass {
> public:
> int mymethod(void);
> int secondmethod(void);
> };
>
> int main() {
> myclass *p = new myclass();
> return p->mymethod();
> }
> $ CC m.cc -L. -R. -lt -Qoption ld -Dfiles
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/crti.o [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/CCrti.o [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/crt1.o [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/misalign.o [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/values-xa.o [ ET_REL ]
> debug:
> debug: file=m.o [ ET_REL ]
> debug:
> debug: file=./libt.so [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/lib/v8plus/libCstd.so [ ET_DYN ]
> debug:
> debug: file=/set/dist/sparc-S2/lib/libCrun.so [ ET_DYN ]
> debug:
> debug: file=/lib/libm.so [ ET_DYN ]
> debug:
> debug: file=/lib/libc.so [ ET_DYN ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/CCrtn.o [ ET_REL ]
> debug:
> debug: file=/set/dist/sparc-S2/prod/lib/crtn.o [ ET_REL ]
> debug:
> debug: file=/lib/libdl.so.1 [ ET_DYN ]
> debug:
> debug:
> debug:
> $ ./a.out
> $ echo $?
> 2
> $ CC m.cc -L. -R. -lt -Qoption ld -Dsymbols,-Dlibs,-Dfiles > ld.log 2>&1
> $ less ld.log
> ....
> debug: symbol table processing; input file=m.o [ ET_REL ]
> debug: symbol[1]=m.cc
> debug: symbol[2]=int myclass::mymethod() (global); adding
> debug: symbol[3]=void*operator new(unsigned) (global); adding
> debug: symbol[4]=main (global); resolving [7][0]
> debug: symbol[5]=__fsr_init_value (global); resolving [7][0]
> debug: Library Search Paths (-L updated)
> debug: .
> debug: /set/dist/sparc-S2/lib/rw7
> debug: /set/dist/sparc-S2/lib/v8plus
> debug: /set/dist/sparc-S2/prod/lib/rw7
> debug: /set/dist/sparc-S2/prod/lib/v8plus
> debug: /set/dist/sparc-S2/lib
> debug: /set/dist/sparc-S2/prod/lib
> debug: /usr/ccs/lib
> debug: /lib
> debug: /usr/lib
> debug:
> debug: file=./libt.so [ ET_DYN ]
> debug:
> debug: symbol table processing; input file=./libt.so [ ET_DYN ]
> debug: symbol[3]=myclass_1.1 (global); adding
> debug: symbol[4]=void __Cimpl::cplus_init() (global); resolving [16][1]
> debug: symbol[7]=void __Cimpl::cplus_fini() (global); resolving [16][1]
> debug: symbol[8]=_ex_register (global); resolving [16][1]
> debug: symbol[9]=_ex_deregister (global); resolving [16][1]
> debug: symbol[10]=void __Crun::do_exit_code_in_range(void*,void*) (global); resolving [16][1]
> debug: symbol[11]=_get_exit_frame_monitor (global); resolving [16][1]
> debug: symbol[13]=int myclass::mymethod() (global); resolving [16][0]
> debug: symbol[14]=atexit (global); resolving [16][1]
> debug:
> debug: file=/set/dist/sparc-S2/lib/v8plus/libCstd.so [ ET_DYN ]
> ...
>
> Maybe I'm completely overlooking some detail but it should work...
Yeah, I'm doing exactly the same thing you've described here. Could it
be that the function that it's trying to reference is a static member
function?
MsgFactory.h
class MsgFactoryTable
{
public:
//! getInstance gets the single object
/*!
\returns MsgFactoryTable&
*/
static MsgFactoryTable & getInstance();
.....
MsgFactory.cxx
MsgFactoryTable & MsgFactoryTable::getInstance()
{
// static instance - only created once
static MsgFactoryTable oMsgFactInstance;
// return the only instance of this object
return oMsgFactInstance;
}
Mapfile
MDSMsgFact_1.1
{
global:
__1cPMsgFactoryTableLgetInstance6F_r0_;
local:
*;
};
nm libMSGFACTORY.so.1 | grep MsgFactory | grep GLOB:
[4682] | 799176| 4|OBJT |GLOB |0 |21
|$XD9h0NkL8gRBm5w.__1fPMsgFactoryTableLgetInstance6F_r01AG__CCLC_
[4642] | 786636| 32|OBJT |GLOB |0 |20
|$XD9h0NkL8gRBm5w.__1fPMsgFactoryTableLgetInstance6F_r01AQoMsgFactInstance_
[4720] | 323800| 468|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____Ferase6Mn0HIiterator_6_6_
[6002] | 324704| 3856|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____Ferase6Mn0HIiterator__6_
[5035] | 306040| 832|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____Ginsert6Mrkn0D__n0BEpair4n0HIiterator_Cb___
[4913] | 324536| 148|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____H__erase6Mpn0HO__rb_tree_node__v_
[5236] | 306888| 1544|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____I__insert6Mpn0HO__rb_tree_node_7rkn0D__n0HIiterator__
[6170] | 324288| 228|FUNC |GLOB |0 |9
|__1cH__rwstdJ__rb_tree4CCnDstdEpair4CkCCpnKMsgFactory___n0AL__select1st4n0D_CC__n0BEless4CC__n0BJallocator4n0D____U__deallocate_buffers6M_v_
[5476] | 316104| 164|FUNC |GLOB |0 |9
|__1cPMsgFactoryTableLgetInstance6F_r0_
-Gregg
|
|
0
|
|
|
|
Reply
|
galtschul
|
9/14/2004 2:26:01 PM
|
|
|
2 Replies
241 Views
(page loaded in 0.041 seconds)
|
|
|
|
|
|
|
|
|