[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