Hi everyone,
I'm kinda silent on the list so people may not know that Gentoo supports
uclibc-ng as a replacement for glibc. As a from source distro, we can
do that. I also support Gentoo+musl.
A few months back I switched from uclibc to uclibc-ng for obvious
reasons. Its important for our users that we provide a forward
migration path. The migration from uclibc -> uclibc-ng was a bit rocky
but doable. [See
https://wiki.gentoo.org/wiki/Project:Hardened_uClibc].
Since then, there have been two major changes to uclibc-ng which
necessitated some more extra steps: 1) the coalescing of the breakout
libraries like libdl.so, libm.so etc into libc.so. and 2) dropping
obstack support. I'm going to outline the steps for forward migration
here as an RFC. I'm also going to push out a news item to our users.
Please comment
1. First we address the breakout libraries. Make sure you are on either
uclibc-ng-1.0.18 or 1.0.19 and rebuild world with
emerge -evq @world
This should ensure that all executables bypass any symlinks from libm.so
(and friends) to libc.so and link directly against libc.so. You can
reassure yourself afterwards that a particular ${executable} does not
link against any of the breakout libraries by using
readelf -d ${executable} | grep
"NEEDED.*lib\(crypt\|dl\|m\|pthread\|rt\|resolv\|ubacktrace\|util\).so"
At this point it is safe to upgrade to 1.0.20. Make sure you do not set
the symlink-compat USE flag. This is the default behavior, but you can
be explicit about it:
USE="-symlink-compat" emerge =sys-libs/uclibc-ng-1.0.20
2. Now we will have to rebuild @world again and make sure that the
packages' build systems think that our libc does NOT provide obstack,
even though it does. A direct upgrade to 1.0.21 will break your system
because many critical executables will not be able to find obstack* symbols.
There's a few steps that will do the trick here:
a. Remove the obstack.h header:
mv /usr/include/obstack.h ~
b. Force any gnulib build to think it has to provide its own obstack:
cp /usr/include/gnu-versions.h ~
sed -i -e '/#define _GNU_OBSTACK/d' /usr/include/gnu-versions.h
c. Tell stdio.h to not expose some obstack function prototypes. This is
accomplished by defining __UCLIBC_HAS_OBSTACK__ 0 via the
uClibc_config.h file:
cp /usr/include/bits/uClibc_config.h ~
sed -i -e '/__UCLIBC_HAS_OBSTACK__/ s/1/0/'
/usr/include/bits/uClibc_config.h
3. Now we are ready to rebuild @world, but we must skip rebuilding
uclibc-ng itself since it will just undo the changes in step 2!
emerge -—keep-going -evq --exclude sys-libs/uclibc-ng @world
Some packages might fail. dev-libs/gmp will fail. It is a critical
part of the toolchain, and we must deal with it.
4. To rebuild dev-libs/gmp, we need to override its build system's
search for obstack_vprintf(). Use
ac_cv_func_obstack_vprintf=no emerge -1 gmp
5. At this point you may want to check that no ${executable} is looking
for an undefined symbol that looks like obstack*. If an executable does
have such an undefined symbol, it will break upon upgrade. That's okay
as long as it isn't critical to your system!
readelf -sW ${executable} | grep "UND.*obstack"
6. Now we can upgrade uclibc-ng:
emerge sys-libs/uclibc-ng-1.0.21
7. Finally, we rebuild world one more time to fix any non-critical
executables that still need obstack:
emerge —evq @world