Moving the dynamic linker
Or, interpreter witchcraft to achieve a relatively ert nomultilib filesystem hierarchy.
Introduction
When I first began LFS, the presence of a mysterious /lib64 containing two
files never sat right with me. It's not even supposed to exist at /usr/lib64!
For the instructions in LFS and BLFS to work correctly, it is imperative that this directory [/usr/lib64/] be non-existent. From time to time you should verify that it does not exist, because it is easy to create it inadvertently, and this will probably break your system.
After bricking my LFS once by naively deleting /lib64, and thereby breaking all
dynamically linked binaries, I decided I wanted to get rid of this annoying
directory in my root properly. Not only is it confusing, but it clutters /,
which of course is absolutely unacceptable.
Setting up the system
Thence began the journey of greping through glibc and gcc source code to
divine how I might change this directory. After some investigating, I
discovered I could patch libc_cv_rtlddir much like LFS already patches
libc_cv_slibdir in glibc. Again, through similar exploration, I set the
default linker directory to /usr/lib for gcc via a sed.
# The variable to pass to glibc's configure script, around the same time the
# libc_cv_slibdir variable is passed
libc_cv_rtlddir=/usr/lib
# The gcc sed in question, to be applied around the same time the default 64-bit
# library directory name is
But it's not over yet; we still need to patch ldd to look in the correct
place. While LFS also applies a patch, they only remove /usr from /usr/lib64,
leaving /lib64.
-RTLDLIST="/usr/lib64/ld-linux-x86-64.so.2 /usr/lib/ld-linux.so.2 /usr/libx32/ld-linux-x32.so.2"
+RTLDLIST="/usr/lib/ld-linux-x86-64.so.2"
It would be prudent to run some sanity checks at this point.
|
|
| |
|
|
Those checks differ slightly from the ones LFS runs in that, again, we're
looking for a program interpreter under /usr/lib instead of /lib64. The
tweaks to the toolchain must be applied each time glibc or gcc is rebuilt.
Once we've compiled stage 2 LFS, it's time to chroot in and build stage 3. But
there's a problem -- the utilities we cross-compiled from our host system have
their dynamic linker hardcoded to /lib64/ld-linux-x86-64.so.2. To fix this, we
call upon patchelf, my beloved.
| while ; do
if | ; then
interp="";
if | ; then
fi
fi
done
Finally we can chroot in and build out the stage 3 system. Once again, it's necessary to continue applying the build tweaks for gcc and glibc from before.
Assuming all has gone smoothly, the final system might look a little like this
(note i've also moved /root into /home).
Maintenance
For maintenance, patchelf and libtree are two indispensable utilities for
troubleshooting dynamic linking on such a system.
Dynamically linked binaries compiled elsewhere will not work here until their interpreter is patched.
For setting up a rust toolchain with rustup, I found it necessary to briefly
create /lib64 to satisfy some internal checks and to use the latest commit
version of patchelf to dodge an assertion that rustup trips in patchelf
0.18.0. Once the binaries had been installed, I then overwrote their
interpreters with patchelf.