On Fri, Nov 11, 2005 at 04:14:07PM +0100, [EMAIL PROTECTED] wrote: > today, I aptitude installed apache2, which took a new libc6 with it. > Now I can't link against one of my libs anymore: > > /usr/local/lib/libcpdbg.a(cpdebug.o)(.text+0x374): In function > `dbgSprintx': > : undefined reference to `__ctype_b' > ./lib_x86/libtabe.a(tabe_zuyin.o)(.text+0x7c): In function > `tabeZozyKeyToZuYinIndex': > : undefined reference to `__ctype_tolower' > > I might be able to recompile it, but this could take a long time so I may > be forced to go back to the elder libc6 - unfortunately, I don't know > how...
Instead of downgrading your system's libc, you could simply fetch the appropriate old version, and then explicitly link against that libc. It's probably easiest to get the .deb from http://packages.debian.org, e.g. for stable http://packages.debian.org/stable/libdevel/libc6-dev Then, once you've downloaded the package, extract the file you need. For static linking that would be just libc.a: $ dpkg-deb --fsys-tarfile libc6-dev_2.3.2.ds1-22_i386.deb | tar x -O ./usr/lib/libc.a >libc-2.3.2.a (Even though it's unusual to statically link libc, I'd recommend to do so in this particular case -- it might save you from some hair-pulling...) Then use the option -nodefaultlibs and link with the old libc-2.3.2.a. As -nodefaultlibs removes -lc, -lgcc, -lgcc_eh from gcc's internal linker commandline, you might want to re-add -lgcc and -lgcc_eh (but not -lc), if you need them. A simple example probably demonstrates it best. Lacking any better ideas, I'll use a slightly modifed variant of that dreadfully overused "hello world" program: /*--- hello.c ---*/ #include <stdio.h> #include <ctype.h> void print_hello_world() { char *s = "HELLO WORLD!\n"; int c; /* deliberately use one of the problematic symbols... */ while (c = *s++) printf("%c", __ctype_tolower[c]); } That represents your old lib, which you don't want to rebuild. Let's assume you had once done something like $ gcc -c hello.c $ ar -r libhello.a hello.o and now still have that old libhello.a. Naturally, you also have an associated header file: /*--- hello.h ---*/ void print_hello_world(); Now, you've created some new code you need to link against that lib: /*--- hellomain.c ---*/ #include "hello.h" int main() { print_hello_world(); return 0; } But when you try to do so on a system with a new libc you get $ gcc -o hello hellomain.c libhello.a libhello.a(libhello.o): In function `print_hello_world': libhello.o(.text+0x34): undefined reference to `__ctype_tolower' collect2: ld returned 1 exit status However, when you link against the old libc-2.3.2 you fetched above, things should be fine $ gcc -o hello_static -nodefaultlibs hellomain.c libhello.a libc-2.3.2.a -lgcc (to document what you're doing, you can also add the switch -static, but in this particular case the result should be no different...) And you get, as expected $ ./hello_static hello world! Also, ldd should confirm that no dynamic libs are required: $ ldd ./hello-static not a dynamic executable OK, if you're feeling adventurous, or have many small programs to link against your old lib, you can of course also link them dynamically, which is somewhat more involved: You need libc-2.3.2.so, ld-2.3.2.so (i.e. the dynamic loader/linker) and libc_nonshared.a. The latter is from libc6-dev, the other two are in the package libc6. Decide on where you want to keep them - preferably in some seperate directory, e.g. /usr/local/lib/libc-old - then extract them there $ cd /usr/local/lib/libc-old $ dpkg-deb --fsys-tarfile /tmp/libc6-dev_2.3.2.ds1-22_i386.deb | tar x -O ./usr/lib/libc_nonshared.a >libc_nonshared $ dpkg-deb --fsys-tarfile /tmp/libc6_2.3.2.ds1-22_i386.deb | tar x -O ./lib/libc-2.3.2.so >libc-2.3.2.so $ dpkg-deb --fsys-tarfile /tmp/libc6_2.3.2.ds1-22_i386.deb | tar x -O ./lib/ld-2.3.2.so >ld-2.3.2.so (the libc_nonshared.a is required during linking only, the other two are needed both at compiletime and when you run the program) $ ln -s libc-2.3.2.so libc.so.6 $ chmod +x ld-2.3.2.so $ ls -l -rwxr-xr-x 1 ab ab 90248 12. Nov 11:30 ld-2.3.2.so -rw-r--r-- 1 ab ab 1244688 12. Nov 11:29 libc-2.3.2.so -rw-r--r-- 1 ab ab 10400 12. Nov 11:29 libc_nonshared.a lrwxrwxrwx 1 ab ab 13 12. Nov 11:31 libc.so.6 -> libc-2.3.2.so Now, you should be able to link the stuff: $ LIBPATH=/usr/local/lib/libc_old $ gcc -o hello \ -nodefaultlibs \ -Wl,-rpath $LIBPATH \ -Wl,--dynamic-linker $LIBPATH/ld-2.3.2.so \ hellomain.c libhello.a \ $LIBPATH/libc.so.6 \ $LIBPATH/libc_nonshared.a \ $LIBPATH/ld-2.3.2.so $ ./hello hello world! and ldd should show $ ldd ./hello libc.so.6 => /usr/local/lib/libc_old/libc.so.6 (0x40018000) /usr/local/lib/libc_old/ld-2.3.2.so => /usr/local/lib/libc_old/ld-2.3.2.so (0x40000000) You'll probably have to tweak things somewhat to integrate this in your specific build environment, but this should give you the basic idea... Also, if you're planning to use the old libc for more than just some occasional re-linking, you'll probably also want to install the correct include files somewhere, and make that location known via -I. Cheers, Almut -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

