ld: fatal: Symbol referencing errors. No output written to SNX

Hi all,

I am getting the following error when I try to do a build of a product.

I dont have the dependencies of the binaries involved in the build and thats the reason I was not able to find which library to add or to proceed to the next step to solve the reference problem.

[code]

Undefined first referenced

symbol in file

__1cG__CrunMex_rethrow_q6F_v_ /lib/libiostream.so.1

__1c2K6Fpv_v_ /lib/libiostream.so.1

ld: fatal: Symbol referencing errors. No output written to SNX[/code]

I understand why I am getting this error and I know that some needed library or object should be given as input to solve the problem. But I dont have the build structure and I dont have the dependecy list of the binary.

So Is there a generic way to approach the above problem.

Any help will be greatly appreciated.

Thanks in advance.

-Jerry.

[909 byte] By [jerryragland] at [2007-11-26 9:19:56]
# 1

Either the command you use for linking is incorrect, or you are not compiling and linking using compatible options. The missing symbols are in /usr/lib/libCrun.so.1, which is always linked automatically by default if you use the CC command for linking.

Please show the complete command line you use for a typical compilation, and the complete command line you use for linking the program.

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 2

Thanks Clamage, I added the /usr/lib path and did a rebuild but I got the same error. When I changed the compiler from cc to CC the error is solved but another symbol(sna_arguments) is left unresolved.

When I used cc symbol(sna_arguments) is resolved properly but when CC is used it is not resolved properly.

[code]When cc is used -

Undefinedfirst referenced

symbolin file

__1cG__CrunMex_rethrow_q6F_v_/usr/lib/libiostream.so.1

__1c2K6Fpv_v_/usr/lib/libiostream.so.1

When CC is used -

Undefinedfirst referenced

symbolin file

int snax_args(int,char**) BS-1efa.o [/code]

Since both the errors are during the build of the same target. I am confused to find a way to solve the above.

-Jerry

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 3
I can't help you unless you show the complete command line you use for linking.
clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 4

This is my command I use to builld SNX-

/opt/ss10/SUNWspro/bin/cc CFLAGS= -L/opt/ss10/SUNWspro/lib -L../lib -L../../crm/lib -L/nfs/vol1/homes1/build_test/lcsol13/RP/Build/tuxedo/lib -L/nfs/homes/new/base/BASE_TMASNA81_SOL28-32/lib -L../../lib -L../../api/lib -L/usr/lib -o SNX $TUXDIR/lib/gwserver.o -lgw -lgw -lgws -lengine -lgpnet -lcsxcrm

-Jerry

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 5

This command uses the C compiler to create an executable. The C compiler does not know anything about C++. In particular, it does not know what system files must be linked into a C++ program.

If any of the code, including the libraries listed here, was compiled by Sun C++, you need to use the CC command to link it.

The CC options that you use in linking the program must be compatible with the CC options used in compiling the individual C++ files.

That is, some CC options must be used on every CC command if they are used on any CC command. For example, if any of these options are used during compiling

-compat[=4|5]

-library=stlport4

-library=iostream

-mt

the same options must be used on every CC command, compiling and linking. If -xarch options are used, they must refer to compatible architectures. Refer to the C++ Users Guide option reference (Appendix A) for more details.

If some other compiler, like g++, was used to compile C++ code, you must use that compiler to link the progarm. Refer to that compiler's manuals to determine what options must be used consistently.

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 6

Thanks for the clarification clamage.

I have a few more questions.....

How can I get more information about a library?

How can I find whether the library is 32 or 64 bit?

How can I find whether the library is a c or c++ library?

Is libiostream.so.1 is also available in c objects or build with cc?

-Jerry.

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 7

Jerry,

> How can I get more information about a library?

> How can I find whether the library is 32 or 64 bit?

Use "file" command with your library as an argument.

How can I find whether the library is a c or c++ library?

Naive answer: use "nm mylib.so |less". If you see mangled symbol names (like very long names starting with __1cD), it's C++. Steve will probably give you better answer.

> Is libiostream.so.1 is also available in c objects or build with cc?

I don't think it is, but Steven will say for sure.

Boris

Boris_Ivanovsky at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 8

> How can I get more information about a library?

That depends on what you want to know. A wide variety of Unix tools and Sun Studio tools are available, each providing overlapping sets of information about binaries.

> How can I find whether the library is 32 or 64 bit?

Use the Unix "file" command:

file name-of-library

> How can I find whether the library is a c or c++ library?

Run

nm -C name-of-library

The -C option shows the demangled version of C++ mangled names. If a symbol shows both a mangled and a demangled name, it is a C++ symbol, and the library contains C++ code. Example:

[8]| 0|53|FUNC |GLOB |0|3|foo

[9]| 0|0|NOTY |GLOB |0|UNDEF |std::cout

[__1cDstdEcout_]

In this sample output, the name "foo" is shown in only one form. It is therefore not a mangled name, and could have come from C, C++, or assembler code.

But "std::cout" is shown as the demangled version of "__1cDstdEcout_" and could only have come from C++ source code. This binary therefore contains C++ code.

> Is libiostream.so.1 is also available in c objects or build with cc?

libiostream is a C++ system library, containing the Sun C++ version of "classic" (pre-standard) iostreams. It contains no functions or objects that can reasonably be referenced from a C program. If a program needs libiostream, the program contains C++ code. Furthermore, the C++ code was compiled with the option -library=iostream.

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 9

I now understand that the problem which I am facing right now is due to a mix use of c and c++ libraries.

My project has c programs and my build compiles all the .c programs using cc compiler into .o and then the .o are grouped by [b]CC(c++) [/b]and the library created is gws.so.

In the later stage of the build gws.so and few other libraries are linked to get SNX using

[code]/opt/ss10/SUNWspro/bin/cc CFLAGS= -L/opt/ss10/SUNWspro/lib -L../lib -L../../crm/lib -L/nfs/vol1/homes1/build_test/lcsol13/RP/Build/tuxedo/lib -L/nfs/homes/new/base/BASE_TMASNA81_SOL28-32/lib -L../../lib -L../../api/lib -L/usr/lib -o SNX $TUXDIR/lib/gwserver.o -lgw -lgw -lgws -lengine -lgpnet -lcsxcrm[/code]

During this I got some symbol referenced error in libiostream.so.1 and with your suggestions I did a rebuild with [b]CC[/b] and the unresolved symbols from libiostream.so.1 were solved and I got a new unresolved symbol from BS-1efa.o -

[code]Undefined first referenced

symbol in file

int snax_args(int,char**) BS-1efa.o [/code]

With the help of nm I found snax_args is defined in gws.so and since gws.so has objects built with cc I felt the problem may lie there and started to build the .c file with [b]CC (c++) [/b]compiler. During the [b]CC[/b] compilation I got many implicit declaration errors in many files (which was displayed as warnings with cc(c compiler) ) and the build was terminated.

Please provide me some clues to solve the problem.

Thanks in advance.

-Jerry.

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 10

If you compile C source code with the C++ compiler, you won't get the same result as compiling it with the C compiler, in at least two ways:

1. C++ language rules are different. There are no implicit declarations, and all functions must have prototypes. Unless you write the C code with the idea of being able to compile it as C++, the C++ compiler will typically generate error messages.

It is not difficult to write code that is valid C and C++, but you have to keep in mind the stricter C++ rules. For example, all of the Solaris headers in /usr/include can be compiled by either the C or C++ compiler, and produce the same results either way. (When compiled as C++, some have additional features, but the subset for C works the same for both.)

2. If a function is not declared with the C++ syntax

extern "C" .....

the external name (as seen by the linker) of the function will be "mangled" by the C++ compiler. Example: If you compile

int foo(int);

with the C compiler, it generates a reference to the name "foo".

If you compile it with the Sun C++ compiler, it generates a reference to __1cDfoo6Fi_i_ instead. You will not be able to link modules correctly if they have different spellings for the same function.

You can mix C and C++ code in the same program, but referencing C functions from C++ code requires declaring the C functions using the extern "C" syntax.

That said, I don't see any reason from your descriptions so far why you are using the C++ compiler, or why you are linking libiostream. Where is the C++ code in the program?

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 11

The entire project build is done with cc compiler

I am not explicitly linking libiostream.so.1 in to my build. It is linked automatically I guess to get some definitions.

To solve the unresolved symbol errors raised from libiostream.so.1 I used CC and it also solved the problem but unfortunately raised an another one

[code]Undefined first referenced

symbol in file

int snax_args(int,char**) BS-1efa.o [/code]

with snax_args defined in gws.so. But I dont get the above error when I use cc.

The entire problem is around the automatic linking of libiostream.so.1. If that problem is solved with out changing the compiler from cc to CC I guess the problem can be solved.

-Jerry.

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 12

cc will never link libiostream by itself. Something must be causing it to be linked, like an option on a command line.

Using CC to do a *link* will not cause any non-C++ symbols to become undefined. If the CC command compiles a C file, it can cause in approrpriate references to be generated, as I explained before.

To help sort out what is going on, do this:

1. Make a list of all the .o files that were not created by the C compiler (cc).

2. Make a list of all the libraries mentioned on command lines.

3. For each .o and library, find out whether it contains C++ code (nm -C as I explained previously).

Now you can see where the C++ code is, if any.

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 13

clamage, thanks for your effort in explaining.

Please verify the following -

Point 1. cc Compiler can not be used in the compilation process when a C++ library is used in the process because the C++ library will have the symbols mangled which can't be understand by cc.

Point 2. CC compiler can be used in the compilation process even when a c library is used in linking because the symbols are straight forward to refer.

As per your guidelines I did nm -C to find the mangled symbols in the libraries which I have specified in the command line of my compilation -

/opt/ss10/SUNWspro/bin/cc CFLAGS= -L/opt/ss10/SUNWspro/lib -L../lib -L../../crm/lib -L/nfs/vol1/homes1/build_test/lcsol13/RP/Build/tuxedo/lib -L/nfs/homes/new/base/BASE_TMASNA81_SOL28-32/lib -L../../lib -L../../api/lib -L/usr/lib -o SNX $TUXDIR/lib/gwserver.o -lgw -lgw -lgws -lengine -lgpnet -lcsxcrm

###################

greped output of nm -C

$$$$$$$$$$$$

libgws.so

[1361] | 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_fini(

)

[__1cH__CimplKcplus_fini6

F_v_]

[894]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_init(

)

[__1cH__CimplKcplus_init6

F_v_]

[498]| 0|0|NOTY |WEAK |0|UNDEF |void __Crun::do_exit_code

_in_range(void*,void*)

[__1cG__CrunVdo_exit_code

_in_range6Fpv1_v_]

$$$$$$$$$$$$$

libengine.a

[4591] | 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_fini(

)

[__1cH__CimplKcplus_fini6

F_v_]

[3470] | 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_init(

)

[__1cH__CimplKcplus_init6

F_v_]

[4075] | 0|0|NOTY |WEAK |0|UNDEF |void __Crun::do_exit_code

_in_range(void*,void*)

[__1cG__CrunVdo_exit_code

$$$$$$$$$$$$

libgpnet.a

[341]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_fini(

)

[__1cH__CimplKcplus_fini6

F_v_]

[261]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_init(

)

[__1cH__CimplKcplus_init6

F_v_]

[267]| 0|0|NOTY |WEAK |0|UNDEF |void __Crun::do_exit_code

_in_range(void*,void*)

[__1cG__CrunVdo_exit_code

_in_range6Fpv1_v_]

$$$$$$$$$$$$

libcsxcrm.so

[304]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_fini(

)

[__1cH__CimplKcplus_fini6

F_v_]

[234]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_init(

)

[__1cH__CimplKcplus_init6

F_v_]

[455]| 0|0|NOTY |WEAK |0|UNDEF |void __Crun::do_exit_code

_in_range(void*,void*)

[__1cG__CrunVdo_exit_code

_in_range6Fpv1_v_]

$$$$$$$$$$$$

libgw.a

[1494] | 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_fini(

)

[__1cH__CimplKcplus_fini6

F_v_]

[934]| 0|0|NOTY |WEAK |0|UNDEF |void __Cimpl::cplus_init(

)

[__1cH__CimplKcplus_init6

F_v_]

[1405] | 0|0|NOTY |WEAK |0|UNDEF |void __Crun::do_exit_code

_in_range(void*,void*)

[__1cG__CrunVdo_exit_code

_in_range6Fpv1_v_]

$$$$$$$$$$$$

1. gwserver.o has no mangled symbols in it.

2. libcsxcrm.so and libgws.so are built with CC and the .o files in these libraries are built with cc.

3. The rest of the libraries are from a different product and not built by me.

As to go with point 1, I changed the compiler from cc to CC and restart the compilation with some more flags added.

/opt/ss10/SUNWspro/bin/CC CFLAGS= -I../include -I../../include -I/nfs/home

s/vikumar/new/base/BASE_TMASNA81_SOL28-32/include -I/nfs/vol1/homes1/jragland/build_test/lcsol13/RP/Build/tuxedo/include -I/nfs/vol1/homes1/jragland/build_test/lcsol13/RP/Build/tuxedo/idk/sysinclude -I../../crm/include -DBASE_DEBUG=0 -Dsun -DCICX_MACHINE=53 -library=iostream,no%Cstd -KPIC +p -g -mt -I/usr/openwin/include -I../../wls/wls600/../jdk131/include -I../../wls/wls600/../jdk131/include/solaris -o SNX $TUXDIR/lib/gwserver.o -lgw -lgws -lengine -lgpnet -lcsxcrm

This time the build was succesfull and the binary SNX was created successfully. From the experience I feel that the compiler options also plays a major role. Can you please explain what does no%Cstd do.

Thanks once again for your help.

jerryragland at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...
# 14

> Point 1. cc Compiler can not be used in the

> compilation process when a C++ library is used in the

> process because the C++ library will have the symbols

> mangled which can't be understand by cc.

No, that is not a correct summary.

C source code should be compiled the C compiler.

C++ source code must be compiled by the C++ compiler.

A program or library can contain binaries generated by a mix of C and C++ compilations. C and C++ code can be linked successfully into the same program if you follow the rules for mixing code.

When you build a library or program that contains C++ code, use CC instead of cc in the link phase.

When you build a program or library that does not contains any C++ code, do not use CC.

Here are two articles about how to mix C and C++ code in the same program.

Mixing C and C++ Code in the Same Program

http://developers.sun.com/prodtech/cc/articles/mixing.html

Mixed-Language Programming and External Linkage

http://developers.sun.com/solaris/articles/external_linkage.html

>

> Point 2. CC compiler can be used in the compilation

> process even when a c library is used in linking

> because the symbols are straight forward to refer.

See my answer above.

>

> As per your guidelines I did nm -C to find the

> mangled symbols in the libraries which I have

> specified in the command line of my compilation -

>

> /opt/ss10/SUNWspro/bin/cc CFLAGS=

> -L/opt/ss10/SUNWspro/lib -L../lib -L../../crm/lib

> -L/nfs/vol1/homes1/build_test/lcsol13/RP/Build/tuxedo/

> lib -L/nfs/homes/new/base/BASE_TMASNA81_SOL28-32/lib

> -L../../lib -L../../api/lib -L/usr/lib -o SNX

> $TUXDIR/lib/gwserver.o -lgw -lgw -lgws -lengine

> -lgpnet -lcsxcrm

As we discover below, some of these libraries contain C++ code, so the link should be done with CC, not cc.

In particular, libraries libgws.so libengine.a libgpnet.a libcsxcrm.so libgw.a all contain references to symbols that happen to be in the C++ system library libCrun.so. That means they were created using the CC command. But the odd thing is that the only C++ symbols are for starting and ending a C++ program or library. There are no symbols associated with C++ source code.

> 2. libcsxcrm.so and libgws.so are built with CC and

> the .o files in these libraries are built with cc.

If all the components were compiled with cc, there is no reason to use CC to create the libraries, and very good reasons not to use CC. That is, using CC forces linking to C++ libraries that would not otherwise be needed or used.

> 3. The rest of the libraries are from a different

> product and not built by me.

Well, they contain C++ code, but as I noted above, seem not to involve C++ source code.

>

> As to go with point 1, I changed the compiler from cc

> to CC and restart the compilation with some more

> flags added.

>

>

> /opt/ss10/SUNWspro/bin/CC CFLAGS= -I../include

> -I../../include -I/nfs/home

> s/vikumar/new/base/BASE_TMASNA81_SOL28-32/include

> -I/nfs/vol1/homes1/jragland/build_test/lcsol13/RP/Buil

> d/tuxedo/include

> -I/nfs/vol1/homes1/jragland/build_test/lcsol13/RP/Buil

> d/tuxedo/idk/sysinclude -I../../crm/include

> -DBASE_DEBUG=0 -Dsun -DCICX_MACHINE=53

> -library=iostream,no%Cstd -KPIC +p -g -mt

> -I/usr/openwin/include

> -I../../wls/wls600/../jdk131/include

> -I../../wls/wls600/../jdk131/include/solaris -o SNX

> $TUXDIR/lib/gwserver.o -lgw -lgws -lengine -lgpnet

> -lcsxcrm

When linking object code, the -I options have no effect. They tell the compiler where to look for header files when compiling source code.

The option

-library=iostream,no%Cstd

causes libiostream to be linked, but prevents linking libCstd. The two libraries are not normally used together, libCstd being the C++ Standard Library, and libiostream being the pre-standard version of C++ I/O.

You did not show any code that had references to anything in libiostream, so I still don't understand why you need to link it.

For the libraries that you did not create, do you have any documentation that explains how they are to be linked into a program? Such instructions would have avoided the problems you found.

clamage45 at 2007-7-6 23:50:33 > top of Java-index,Development Tools,Solaris and Linux Development Tools...