[ale] Static linking of readline
Charles Shapiro
hooterpincher at gmail.com
Sat Jul 28 09:09:11 EDT 2012
The "diary.c" program compiles, links, and runs flawlessly to a shared
library executable 18K in size. It uses readline(3) to get some stuff
the user types in.
So you'd _think_ that, given "/usr/lib/libreadline.a", the command:
gcc -static -I. -lreadline -o diary diary.c
Would create the statically linked "diary" executable. But in fact,
on my ubuntu 10.10 system you get:
/tmp/ccU5znZ0.o: In function `get_timecode':
diary.c:(.text+0x65e): undefined reference to `readline'
diary.c:(.text+0x6ef): undefined reference to `readline'
/tmp/ccU5znZ0.o: In function `get_inputstring':
diary.c:(.text+0x76b): undefined reference to `readline'
collect2: ld returned 1 exit status
After much manful struggle, I determined that I could only get the
static-linked "diary" program to include readline if I disassembled
the /usr/lib/libreadline.a library with ar(1), then explicitly named
the .o files in the gcc command:
cc -static -I. -lgpm -o diary-static diary.c readline-6.1/bind.o
readline-6.1/callback.o readline-6.1/compat.o readline-6.1/complete.o
readline-6.1/display.o readline-6.1/funmap.o readline-6.1/histexpand.o
readline-6.1/histfile.o readline-6.1/history.o
readline-6.1/histsearch.o . . .
Alas, the same mechanism ( or lack of mechanism) also holds with the
ncurses library and the gpm library, which libreadline requires. So
after an immensely long gcc command line, I have a statically linked
program which runs, and is only 1.3 MB in size.
Has anyone else tried this with a less cumbersome method? I have
verified that I can statically link the "hello world" example ( the
shared object one is about 7K, and the static one is about 600), so I
am pretty sure that libgcc.a is being properly referenced. All of the
googling I have done seems to indicate that at the very least:
gcc -static -lreadline -lgpm -lncurses -I. -o diary-test diary.c
Should produce a statically linked diary-test file, given
/usr/lib/libreadline.a, /usr/lib/libncurses.a, and /usr/lib/libgpm.a.
But of course it never picks the readline object out of
/usr/lib/libreadline.a, giving the same error message as above.
If I tear everything into .o files with ar(1) and explicitly link
those in, the linker works fine. Once I am over the linker troubles,
the static-linked program seems to run. I am quite sure that gcc is
seeing libreadline.a, since I get no kvetching about not being able to
find a file, and I tried moving libreadline.a around and pointing to
it in different places with no change in behavior.
I am using:
gcc -v
Using built-in specs.
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro
4.4.4-14ubuntu5.1'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-4.4 --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib
--without-included-gettext --enable-threads=posix
--with-gxx-include-dir=/usr/include/c++/4.4 --libdir=/usr/lib
--enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-objc-gc --enable-targets=all
--disable-werror --with-arch-32=i686 --with-tune=generic
--enable-checking=release --build=i686-linux-gnu --host=i686-linux-gnu
--target=i686-linux-gnu
Thread model: posix
gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5.1)
ld --version
GNU ld (GNU Binutils for Ubuntu) 2.20.51-system.20100908
-- CHS
More information about the Ale
mailing list