linking problem - "undefined reference to ..."

Chris Bouchard cbouchrd@uiuc.edu
Thu Apr 10 01:14:00 GMT 2008


Brian,

Thanks for the quick response.

---- Original message ----
>Date: Wed, 09 Apr 2008 16:44:47 -0700
>From: Brian Dessent <brian@dessent.net>  
>Subject: Re: linking problem - "undefined reference to  ..."  
>To: Chris Bouchard <cbouchrd@uiuc.edu>
>Cc: gcc-help@gcc.gnu.org
>
>Chris Bouchard wrote:
>
>> #include "/home/theorist/cbouchrd/local/include/tsil.h"
>
>The absolute path is a bad idea, you can simply use #include "tsil.h".
>
>> ---------------------------------------------------------
>> [cbouchrd@lx6 ~/tsil-1.1]$ g++ -t -o fig6.exe fig6.cpp -L. -ltsil
>> ---------------------------------------------------------
>> where I think I'm telling gcc to go to the working directory to look for library files (-L.) and then to link to libtsil.a (-ltsil).
>
>That looks fine, although creating a binary named 'fig6.exe' on a
>platform like Linux that does not typically have an extension for
>executables seems really strange.  But that's neither here nor there,
>and shouldn't be related to the link errors.
>
>> /tmp/ccp26z8w.o(.text+0x96): In function `main':
>> : undefined reference to `TSIL_SetParameters(TSIL_Data*, long double, long double, long double, long double, long double, long double)'
>
>If gcc was unable to find "-ltsil" you would have gotten a different
>error saying as much, so that means that it did find and search
>libtsil.a for the symbol but did not find it.  You need to figure out if
>indeed the library has that symbol in it.  For static archives, 'nm' is
>usually used.  I like to use the idiom
>
>nm -AP libtsil.a | grep ' T ' 
>
>This prints the symbols	in the library, filtered on those marked 'T'
>which are the functions actually contained in the library.  You can add
>on an additional "| grep TSIL_SetParameters" to the end if you want to
>search for that specific function.
>

I searched the library and found:
--------------------------------------------------------
[cbouchrd@lx6 ~/tsil-1.1]$ nm -AP libtsil.a | grep ' T '
[snip other functions]
libtsil.a[initialize.o]: TSIL_SetParameters T 0000030a 00000c6d
[snip other functions]
--------------------------------------------------------
I see the addition of T 0000030a00000c6d at the end of the function name... is this the name mangling you're talking about?

>Since this is C++ you also have to be aware of name mangling.  The
>symbol will not be called as just 'TSIL_SetParameters' but some uglified
>version that encodes its type.  And in fact this is why I suspect the
>link is failing: in C++ due to this name mangling, libraries must all be
>ABI compatible which in most cases means they must have been compiled by
>the same compiler or two compatible versions of the same compiler.  In
>the case of gcc this usually means they must be from the same branch,
>e.g. gcc A.B.x and A.B.y.  You didn't mention if you compiled libtsil.a
>yourself or got it from elsewhere, but if the latter I suspect it's not
>ABI compatible.
>

I did get the library from elsewhere.  Is their a way to enforce compatibility?  Perhaps by forcing compilation by a specific ABI version of gcc using an option I seem to remember reading about... okay I just looked it up... would "-fabi-version=n" fix this?
 
I think the following means I'm using ABI version 2.
------------------------------------------------------
[cbouchrd@lx6 ~/tsil-1.1]$ g++ -E -dM - < /dev/null | awk '/GXX_ABI/ {print $3}'
1002
------------------------------------------------------

>Another related form of this problem is trying to link a C library from
>C++ code.  Again, the mangling makes this impossible unless you
>explicitly declare the functions as 'extern "C"' which disables the C++
>calling conventions.  If the output of 'nm' doesn't show mangled
>function names then the library is actually a C library and you need to
>rethink how you intend to use it.  You'd need to either switch to C for
>your code, or fix the tsil.h header to declare everything extern "C" if
>__cplusplus is true.

>From the website where I downloaded the code, "It is written in C, and can be linked to C/C++ and Fortran applications."  So, perhaps I should alter the tsil.h header to declare all extern "C".

I must admit, I don't know what this means or how to do it but I'll get my books out and start studying.  I also don't know what the statement "if __cplusplus is true" means. 

It sounds like I have two possible options:
1.  maybe using the -fabi flag to use abi version 1 could fix the problem (if the library was compiled under version 1)
2.  maybe the library is a C library and I should declare the functions in tsil.h as extern "C"

If you could point me in the right direction here I'd be grateful!

>
>Brian



More information about the Gcc-help mailing list