views:

19

answers:

1

I am trying to create a custom TCL interpreter with TclPro according instructions at TclPro User's Guide Chapter 7, but it fails with linking error undefined reference to __ctype_b.

I have downloaded and installed TclPro 1.4 at /opt/ajuba/TclPro1.4/, and here is the custom interpreter I want to build:

// file simple.cpp
#include <proWrap.h>
int main( int argc, char** argv )
{
    Pro_WrapTclMain( argc, argv, &Tcl_Init );
    return 0;
}

So it does nothing but calls Pro_WrapTclMain with standard Tcl_Init.

I am trying to build simple.cpp with this command:

g++ -DNDEBUG -O3 -fpic -Wall -pedantic  -I/opt/ajuba/TclPro1.4/include simple.cpp -static -Wl,-R/opt/ajuba/TclPro1.4/linux-ix86/lib -L/opt/ajuba/TclPro1.4/linux-ix86/lib -lwrapper1.4 -ltcl8.3 -o out

and here is the first error message I get (you can find the full log at the bottom):

/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(envargs.o): In function `envargs':
envargs.c:(.text+0x1e): undefined reference to `__ctype_b'

Seems __ctype_b is a symbol which TclPro expects to be defined at libc.a, but

nm /usr/lib/libc.a | grep __ctype_b

gives

00000080 T __ctype_b_loc

so there is no __ctype_b defined at libc.a.

The question is: how to build a custom TCL interpreter with TclPro in this situation?

If __ctype_b should be defined at libc.a, then how can I obtain an appropriate libc.a?

Here is the full log of compilation:

g++ -DNDEBUG -O3 -fpic -Wall -pedantic  -I/opt/ajuba/TclPro1.4/include simple.cpp -static -Wl,-R/opt/ajuba/TclPro1.4/linux-ix86/lib -L/opt/ajuba/TclPro1.4/linux-ix86/lib -lwrapper1.4 -ltcl8.3 -o out
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixPipe.o): In function `TclpCreateTempFile':
tclUnixPipe.c:(.text+0xe0): warning: the use of `tmpnam' is dangerous, better use `mkstemp'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixFCmd.o): In function `GetGroupAttribute':
tclUnixFCmd.c:(.text+0xb5b): warning: Using 'getgrgid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixFCmd.o): In function `SetGroupAttribute':
tclUnixFCmd.c:(.text+0xd59): warning: Using 'getgrnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixFCmd.o): In function `GetGroupAttribute':
tclUnixFCmd.c:(.text+0xba1): warning: Using 'endgrent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixFCmd.o): In function `SetOwnerAttribute':
tclUnixFCmd.c:(.text+0xe7d): warning: Using 'getpwnam' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixFCmd.o): In function `GetOwnerAttribute':
tclUnixFCmd.c:(.text+0xc14): warning: Using 'getpwuid' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
tclUnixFCmd.c:(.text+0xc5e): warning: Using 'endpwent' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixChan.o): In function `TcpGetOptionProc':
tclUnixChan.c:(.text+0x8de): warning: Using 'gethostbyaddr' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclUnixChan.o): In function `CreateSocketAddress':
tclUnixChan.c:(.text+0xe4c): warning: Using 'gethostbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclIOSock.o): In function `TclSockGetPort':
tclIOSock.c:(.text+0x47): warning: Using 'getservbyname' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(envargs.o): In function `envargs':
envargs.c:(.text+0x1e): undefined reference to `__ctype_b'
envargs.c:(.text+0x5d): undefined reference to `__ctype_b'
envargs.c:(.text+0x193): undefined reference to `__ctype_b'
envargs.c:(.text+0x1c0): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(envargs.o): In function `count_args':
envargs.c:(.text+0x23d): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(envargs.o):envargs.c:(.text+0x29b): more undefined references to `__ctype_b' follow
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(fileio.o): In function `UzpMorePause':
fileio.c:(.text+0x9a8): undefined reference to `__ctype_tolower'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(fileio.o): In function `do_string':
fileio.c:(.text+0xf31): undefined reference to `__ctype_b'
fileio.c:(.text+0xf4a): undefined reference to `__ctype_tolower'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(fileio.o): In function `zstrnicmp':
fileio.c:(.text+0x120c): undefined reference to `__ctype_b'
fileio.c:(.text+0x1215): undefined reference to `__ctype_tolower'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(match.o): In function `recmatch':
match.c:(.text+0x127): undefined reference to `__ctype_tolower'
match.c:(.text+0x15f): undefined reference to `__ctype_b'
match.c:(.text+0x1ad): undefined reference to `__ctype_b'
match.c:(.text+0x24b): undefined reference to `__ctype_b'
match.c:(.text+0x264): undefined reference to `__ctype_tolower'
match.c:(.text+0x28d): undefined reference to `__ctype_b'
match.c:(.text+0x2a6): undefined reference to `__ctype_tolower'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libwrapper1.4.a(unix.o): In function `mapname':
unix.c:(.text+0x441): undefined reference to `__ctype_b'
unix.c:(.text+0x47b): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclIOUtil.o): In function `TclGetOpenMode':
tclIOUtil.c:(.text+0x36): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclListObj.o): In function `SetListFromAny':
tclListObj.c:(.text+0x7e6): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclLoad.o): In function `Tcl_LoadObjCmd':
tclLoad.c:(.text+0x3cc): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclObj.o):tclObj.c:(.text+0x7e8): more undefined references to `__ctype_b' follow
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclLoadDl.o): In function `TclpLoadFile':
tclLoadDl.c:(.text+0x35): undefined reference to `dlopen'
tclLoadDl.c:(.text+0x5a): undefined reference to `dlerror'
tclLoadDl.c:(.text+0xa1): undefined reference to `dlsym'
tclLoadDl.c:(.text+0xe0): undefined reference to `dlsym'
tclLoadDl.c:(.text+0x119): undefined reference to `dlsym'
tclLoadDl.c:(.text+0x158): undefined reference to `dlsym'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclLoadDl.o): In function `TclpUnloadFile':
tclLoadDl.c:(.text+0x19c): undefined reference to `dlclose'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclBinary.o): In function `Tcl_BinaryObjCmd':
tclBinary.c:(.text+0xbe4): undefined reference to `__ctype_b'
tclBinary.c:(.text+0xc5d): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclBinary.o): In function `GetFormatSpec':
tclBinary.c:(.text+0x1617): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclCmdAH.o): In function `Tcl_CaseObjCmd':
tclCmdAH.c:(.text+0x185): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclCmdAH.o): In function `Tcl_FormatObjCmd':
tclCmdAH.c:(.text+0x22f5): undefined reference to `__ctype_b'
/opt/ajuba/TclPro1.4/linux-ix86/lib/libtcl8.3.a(tclCmdAH.o):tclCmdAH.c:(.text+0x23f8): more undefined references to `__ctype_b' follow
collect2: ld returned 1 exit status
make: *** [out] Error 1
A: 

I don't know for sure what the details of your platform are, but this message would seem to hold the answer. In essence, you add this code to simple.cpp and recompile:

#include <ctype.h>

extern "C" {
__const unsigned short int **__wrap___ctype_b (void) {
  return __ctype_b_loc();
}
}

You also apparently need to this option to the linking line: -Wl,--wrap,__ctype_b

Hope this helps...

Donal Fellows
@Donal Fellows Thanks for your answer. I have fixed the issues with `undefined reference to __ctype_b` and `undefined reference to __ctype_tolower` in the way you suggested, how ever the issue with `undefined reference to dlopen` still remains (see the g++ log). I am compiling with `-ldl` to bass the libdl.a to the linker, but it still doesn't recognize `dlopen`, `dlerror`, etc. Maybe you can also suggest a way how to fix this issue? Thanks in advance.
Vahagn
IIRC (and I don't normally build static, so my advice might be a little off here) it's usually not recommended to statically link libc and (especially) libdl. Use dynamic linking for those basic system libraries. I forget the details though; as I said, I don't build statically these days (and tclpro has a reputation for being a nasty build, as you're finding out).
Donal Fellows