How to build a C program using a custom version of glibc and static linking?
c, glibc, ld, static-linking
Solution
Following a couple of suggestions from the glibc help mailing list (libc-help@sourceware.org), I have a solution. It turns out that this task is a bit tricky because you have to tell the linker to omit everything it would normally include automatically (and silently), and then include back everything that it needs, including a bunch of start and end files. Some of the start and end files come from libc and some come from gcc, so the make rule is a bit complicated. Below is a general sample makefile to illustrate the approach. I will assume that you are building a program called prog from a source file called prog.c and that you have installed your custom glibc in directory /home/my_acct/glibc_install.
TARGET = prog
OBJ = $(TARGET).o
SRC = $(TARGET).c
CC = gcc
CFLAGS = -g
LDFLAGS = -nostdlib -nostartfiles -static
GLIBCDIR = /home/my_acct/glibc_install/lib
STARTFILES = $(GLIBCDIR)/crt1.o $(GLIBCDIR)/crti.o `gcc --print-file-name=crtbegin.o`
ENDFILES = `gcc --print-file-name=crtend.o` $(GLIBCDIR)/crtn.o
LIBGROUP = -Wl,--start-group $(GLIBCDIR)/libc.a -lgcc -lgcc_eh -Wl,--end-group
$(TARGET): $(OBJ)
$(CC) $(LDFLAGS) -o $@ $(STARTFILES) $^ $(LIBGROUP) $(ENDFILES)
$(OBJ): $(SRC)
$(CC) $(CFLAGS) -c $^
clean:
rm -f *.o *.~ $(TARGET)
Problem
I have built glibc 2.14 and installed it in directory `~/GLIBC/glibc_install`. Now I want to build and run programs using this C library instead of my system's default C library. To be sure that I was using my custom glibc, I added a call to puts into `glibc/stdio-common/printf.c:__printf` to print a message. Then I rebuilt and reinstalled glibc. Then I wrote a "Hello, World" program and tried to compile and link it as follows: ``` gcc -nodefaultlibs -static -lgcc -L~/GLIBC/glibc_install/lib -o myprog myprog.c ``` But I get the following linker error report: ``` /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start': (.text+0x19): undefined reference to `__libc_csu_init' /usr/lib/gcc/x86_64-linux-gnu/4.4.3/../../../../lib/crt1.o: In function `_start': (.text+0x25): undefined reference to `__libc_start_main' /tmp/ccACTQEp.o: In function `main': c1.c:(.text+0xa): undefined reference to `puts' collect2: ld returned 1 exit status ``` What am I doing wrong?