Since glibc-2.1.95, glibc is reliable enough and binary compatible with glibc-2.1, so that I recommend to install it in /lib:/usr/lib. See glibc22install-HOWTO.html.
If you were to install a glibc snapshot in /lib:/usr/lib, chances are high that your system would be damaged in some way: maybe most C++ apps would dump core, maybe emacs won't work any more, maybe you will be unable to recompile a new gcc. If you have bad luck, your system will not even boot any more.
For this reason, I recommend to build in a completely separate tree, let's say /glibc22 instead of /usr. (You can choose any other pathname instead, or make /glibc22 a symbolic link. 150 MB space should be available here.)
Other people recommend to copy all of /etc, /lib, /bin, /sbin, /usr, /dev, /tmp, /var and the glibc sources to a new partition, say /testing, then do "chroot /testing", and build and install the new glibc in this chroot environment. But I don't like this, because I don't like chroot, and because with this approach you are likely to need to start from scratch if anything goes wrong.
Note that all binaries you create in /glibc22 will contain a hardwired pathname /glibc22/lib/ld-linux.so.2. You shouldn't distribute them: They will not run on any Linux system except yours.
Work as a non-root user, because that's the least likely to damage anything.
$ useradd buildguy
$ su - buildguy
Create the directory.
$ mkdir /glibc22
Unset the LD_PRELOAD and LD_LIBRARY_PATH environment variables. They would only cause trouble later.
$ unset LD_PRELOAD
$ unset LD_LIBRARY_PATH
Prepare the kernel sources. You must have them unpacked and configured. /usr/src/linux-2.x.y/include/linux/autoconf.h must exist. Building the kernel is not needed.
Unpack a fresh copy of the glibc snapshot sources. (Building glibc needs write access to the sources.) Also, remove the CVS traces therein.
$ tar xvfz /somewhere/glibc-2000-07-xx.tar.gz
$ find glibc-2000-07-xx -name CVS -type d -exec rm -r '{}' ';'
Note that if you got the snapshot from the ftp site, you need to download
and unpack two files: the main sources and the linuxthreads add-on.
Create a build directory and build there:
$ mkdir glibc-build
$ cd glibc-build
$ ../glibc-2000-07-xx/configure --prefix=/glibc22 --with-headers=/usr/src/linux-2.x.y/include --enable-add-ons
The --prefix=/glibc22 line here is very important; this is what avoids that your existing libc gets overwritten.
$ make
$ make check [This may fail.]
Make the documentation:
$ make info
$ make dvi [This creates manual/libc.dvi.]
$ make pdf [This creates manual/libc.pdf.]
Then install it:
$ make install
$ make localedata/install-locales
$ mkdir -p /glibc22/doc/libc
$ cp ../glibc-2000-07-xx/manual/libc.{dvi,pdf} /glibc22/doc/libc
Make symlinks for /glibc22/include/linux and /glibc22/include/asm
$ ln -s /usr/src/linux/include/asm /glibc22/include/asm
$ ln -s /usr/src/linux/include/linux /glibc22/include/linux
Add additional directories (/glibc22/lib is already implicit) to /glibc22/etc/ld.so.conf and run /glibc22/sbin/ldconfig. (For example, if you intend to recompile XFree86 for glibc 2.2, add /glibc22/X11R6/lib. Don't put here any directories which are listed in /etc/ld.so.conf.)
Now binaries linked against the new glibc should run. As a first test, try to create an UTF-8 locale for your work.
$ mkdir -p /glibc22/lib/locale
$ /glibc22/bin/localedef -c -f UTF-8 -i de_DE de_DE.UTF-8
Also set your timezone:
$ cd /glibc22/etc
$ ln -sf ../share/zoneinfo/Europe/Berlin localtime
At this point, you still cannot create C programs which link against the new glibc, because the linker will search for libc.so in /lib and /usr/lib. (Well, you can, but it's painful: First, you have to give -I/glibc22/include, and when it comes to linking, you have to link statically and modify by hand the linker command line that gcc passes to collect2.)
Unpack and configure binutils. (Note that you cannot compile binutils in its source directory if your $PATH contains "." in front of "/usr/bin".)
$ tar xvfz /somewhere/binutils-2.9.1.0.x.tar.gz
$ cd binutils-2.9.1.0.x
$ mkdir build
$ cd build
$ ../configure --prefix=/glibc22
Modify ld/Makefile as follows:
LIB_PATH = /glibc22/lib:/usr/local/lib
GENSCRIPTS = LIB_PATH=$(LIB_PATH) $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} i586-pc-linux-gnu i586-pc-linux-gnu i586-pc-linux-gnu ${EMUL} ""
Then you can build.
$ make
The only program you need to install is ld.
$ cd ld
$ mkdir -p /glibc22/i586-pc-linux-gnu/lib/ldscripts
$ make install
At this point, you still cannot create C programs which link against the new glibc, because gcc does not know the location of the newly created linker, and because it passes the option "--dynamic-linker /lib/ld-linux.so.2" to the linker. So you have to build a new gcc.
It is important that the ld created by the last step gets installed in /glibc22/i586-pc-linux-gnu/bin/ because this is the directory gcc will look at. If is was installed in a different directory, make a symlink.
Unpack gcc.
$ tar xvfI /somewhere/gcc-2.95.2.tar.bz2
$ cd gcc-2.95.2
Apply a patch needed for C++ support.
$ patch -p0 < gcc-glibc-2.2-compat.diff
Modify gcc/config/i386/linux.h as follows: Change /lib/ld-linux.so.2 to /glibc22/lib/ld-linux.so.2
Configure gcc.
$ cd ..
$ mkdir gcc-build
$ cd gcc-build
$ ../gcc-2.95.2/configure --prefix=/glibc22 --enable-shared --enable-version-specific-runtime-libs
Modify gcc/Makefile as follows: To the cccp.o rule add the line
-DSTANDARD_INCLUDE_DIR=\"/glibc22/include\" \
Then build as usual:
$ make bootstrap
$ make install
Now finally you have a compiler, /glibc22/bin/gcc, which can create binaries linked against the new glibc.
This step is optional. The ld which is used by /glibc22/bin/gcc still uses the old libc. To make things really self-hosting, you should rebuild the binutils.
Throw away the old build directory:
$ rm -r binutils-2.9.1.0.x
Unpack and configure:
$ tar xvfz /somewhere/binutils-2.9.1.0.x.tar.gz
$ cd binutils-2.9.1.0.x
$ mkdir build
$ cd build
$ CC=/glibc22/bin/gcc ../configure --prefix=/glibc22 --enable-shared
Modify ld/Makefile exactly the same way as before:
LIB_PATH = /glibc22/lib:/usr/local/lib
GENSCRIPTS = LIB_PATH=$(LIB_PATH) $(SHELL) $(srcdir)/genscripts.sh ${srcdir} ${libdir} i586-pc-linux-gnu i586-pc-linux-gnu i586-pc-linux-gnu ${EMUL} ""
Then you can build.
$ make
Before installing, edit the main Makefile to comment out the three lines (or seven lines, in newer binutils versions) defining REALLY_SET_LIB_PATH. Without this, LD_LIBRARY_PATH would be set, and you would get an obscure error during the installation of libiberty.a:
sh: /lib/ld-linux.so.2: version `GLIBC_2.2' not found (required by libc.so.6)
Now
$ make install
Any user can now use the new environment. All that is needed is
$ unset LD_PRELOAD
$ unset LD_LIBRARY_PATH
$ export PATH=/glibc22/bin:$PATH
You can now install any number of additional packages in /glibc22. Typically you would configure them with
$ .../configure --prefix=/glibc22 --enable-shared
And to put yourself into an UTF-8 locale:
$ unset LC_ALL
$ unset LC_CTYPE
$ export LANG=de_DE.UTF-8 [the name of the locale you created earlier]
And for gettext:
$ export LANGUAGE=de:en
(With earlier gettext versions, you would have to set
$ export LANGUAGE=de.UTF-8:en.UTF-8
and convert the message catalogs to UTF-8, but now gettext does the character
encoding conversion itself.)