Notes on building uClibc/2.6 system

Gregory Fleischer (Lists) gfleischer.lists at gmail.com
Wed Sep 12 21:07:22 PDT 2007


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

The following are my notes are for building a uClibc / 2.6 kernel
system.  These were originally based on a build using HLFS
"SVN-20070708" but have been updated to apply to "SVN-20070901".

My build machine was an athlon-4 (x86_64), and the target machine was
a Pentium compatible (i586).  Some of these commands below are
specifically tailored to these requirements, but these should be
reasonably obvious.

This is the build setup I used:
- - host environment: VMware Server 1.0.3
- - build environment: installed version of LFS LiveCD x86-6.2-5  
(running under VMware)

The file-system resulting from the build was then transferred via rsync
to the target system.

Here is a list of major software differences from HLFS "SVN-20070901":
- - lfs-bootscripts-version:  6.2 (http://www.linuxfromscratch.org/lfs/ 
downloads/6.2/lfs-bootscripts-6.2.tar.bz2)
- - kernel: linux-2.6.22.6 + latest grsecurity
- - instead of Sysklogd using syslog-ng (http://www.balabit.com/ 
downloads/files/syslog-ng/sources/2.0/src/)

The following additional environment variables were set globally:
CFLAGS="-march=pentium -O2 -pipe -fomit-frame-pointer"
CXXFLAGS="-march=pentium -O2 -pipe -fomit-frame-pointer"

These CFLAGS and CXXFLAGS values were cleared for the Embroyo, Cocoon,
and Butterfly toolchain builds.

Chapter 5

5.2. Embryo Toolchain

- - in ./configure include:

    --host=i586-pc-linux --target=i586-pc-linux


5.4 uClibc-0.9.29

- - download and apply extra patches:
     001-fix-mmap.patch
     conditional-sched_affinity.patch
     fix-gethostent_r-failure-retval.patch
     fix-internal_function-definition.patch
   from
     http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/trunk/buildroot/ 
toolchain/uClibc/


5.5. Adjusting the Toolchain

- - instead of architecture from the build machine, use:

    host=i586-pc-linux-uclibc


5.10. Cocoon Toolchain

- - after the symlinks to the SSP headers are created with this
   command:

   ln -vs ssp/{ssp,stdio,string,unistd}.h \
     `dirname $(gcc -print-libgcc-file-name)`/include/

   the following additional commands are needed:

     sed -i -e 's@^#ifndef _SSP_STDIO_H.*$@#if defined(__need_FILE)  
|| defined(__need__FILE)\n#include_next <stdio.h>\n#else\n&@'  
`dirname $(gcc -print-libgcc-file-name)`/include/stdio.h

     echo '#endif /* __need_FILE */' >> `dirname $(gcc -print-libgcc- 
file-name)`/include/stdio.h

   This is required because stdio.h is included in files for different
   purposes depending on whether __need_FILE or __need__FILE are
   defined.  Because _SSP_STDIO_H was being unilaterally defined, it
   prevented future inclusions of the header from working properly.
   If the update to stdio.h is not performed, most of the rest of
   the build will fail in random ways during compilation.


5.15. Coreutils-6.9

- - Coreutils implements its own "pre-preprocessor" to calculate absolute
   include paths and then includes header files with that value.  So,
   instead of
     #include <stdio.h>
   it generates
     #include "/some/actual/path/to/stdio.h"

   But, the absolute paths breaks the #include_next directives in the
   SSP symlinked headers (see
   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17110)

   To compensate, apply a header file hack to do our own
   pre-pre-preprocessing and generated fixed up header files.  These
   header files are included in the configure command using the
   'gl_cv_absolute_???_h' overrides.  (The other option may be to change
   the #include_next values in the headers to be absolute paths as
   well.  Either way, it is a nasty hack.)

   Execute these commands:

     extra_config=""
     for f in stdio string unistd; do
	cp -v `dirname $(gcc -print-libgcc-file-name)`/include/$f.h $f.orig
	awk '{if (/#include_next/) { system("cat /tools/include/'$f'.h") }  
else { print $0 }}' $f.orig > $f.h
	extra_config="${extra_config} gl_cv_absolute_${f}_h=$(pwd)/$f.h"
     done

   Then run configure with the extra arguments:
     env "$extra_config" ./configure --prefix=/tools

5.17. Findutils-4.2.31

- - need to apply same header file hack as Coreutils


5.19. Gettext-0.16.1

- - there is a problem with an internal name clashing with library names.

   Download and apply:
      http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/trunk/buildroot/ 
package/gettext/gettext-error_print_progname.patch


5.21. Gzip-1.3.12

- - need to apply same header file hack as Coreutils


5.26. Perl-5.8.8

- - the perl-5.8.8-libc-2.patch is for the regular libc.  This won't
   work because the Perl config process miscalculates the appropriate
   libc when it is run.

   The patch needs to be modified so that all instances of "libc.so.6"
   are replaced with "libc.so.0".


Chapter 6

- - in the chroot environment, create a config.site as described in
   "5.5. Adjusting the Toolchain".


6.10. uClibc-0.9.29

6.10.1. Installation of uClibc

- - apply same extra uClibc patches from Chapter 5


6.10.2. Libintl: Gettext 0.16.1
- - the command

    ln -vsf ../../lib/libintl.so.3 /usr/lib/libintl.so

   should be:

    ln -vsf ../../lib/libintl.so.8 /usr/lib/libintl.so

   Note: the 8 instead of 3.


6.11. Re-adjusting the Toolchain

- - the libssp* files need to be present in the new /usr/lib once the
   tool chain is adjusted or linking will fail miserably.

   After, the "gcc -dumpspecs | perl ..." command, the following needs
   to be executed:

   for f in /tools/lib/libssp*;
      do ln -svf $f /usr/lib;
   done

   This create symbolic links to /usr/lib for each of the files.

- - the libtool library files for libssp and libssp_nonshared need to be
   patched so that they point to the /usr/lib location and old
   dependency_libs are removed:

   sed -i -e 's@/tools/@/usr/@g' /usr/lib/libssp{,_nonshared}.la
   sed -i -e 's@^dependency_libs=.*$@dependency_libs='\'\''@' /usr/ 
lib/libssp{,_nonshared}.la


6.12. Butterfly Toolchain

- - optionally, apply extra patch:
   http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/trunk/buildroot/ 
toolchain/gcc/4.1.2/300-libstdc%2B%2B-pic.patch

- - an incorrect 'ld' is being used, fix this with:
   sed -e 's@/lib/ld-linux.so.2@/lib/ld-uClibc.so.0@' \
          -i gcc/config/i386/linux.h

- - it seems that ld-uClibc treats files compiled with "-fpic"
   differently than the more usual "-fPIC".  As a result, shared
   libraries compiled with "-fpic" will exhibit errors like
   "Can't modify blah-blah.so's text section. Use GCC option -fPIC for
   shared objects, please."  Following this request when it appears
   will solve the problem.

   Execute:

     sed -i.orig -e 's/PICFLAG=-fpic/PICFLAG=-fPIC/' config/mh-x86pic

- - dependency tracking through the libtool library files is basically
   foobar.  It is especially bad with libstdc++-v3 because it totally
   miscalculates the appropriate values and duplicates the paths.

   Execute:

     echo 'postdeps="${postdeps//-lssp_nonshared}"' >> ltcf-cxx.sh
     echo 'postdeps="${postdeps//-lssp}"' >> ltcf-cxx.sh
     sed -i.orig -e 's@\$(LIBS)@& -lssp_nonshared -lssp@' \
         ./libstdc++-v3/src/Makefile.in

   (I've also seen a recommendation to simply copy ltcf.sh over
   ltcf-cxx.sh, but I didn't try this.)

- - in the ./configure, the wrong locale is used.  Instead of

     --enable-clocale=gnu

   in needs to just be

     --enable-clocale

   The build process will appropriately auto-detect uclibc.

- - stdio.h fix-up

     sed -i -e 's@^#ifndef _SSP_STDIO_H.*$@#if defined(__need_FILE)  
|| defined(__need__FILE)\n#include_next <stdio.h>\n#else\n&@'  
`dirname $(gcc -print-libgcc-file-name)`/include/stdio.h
     echo '#endif /* __need_FILE */' >> `dirname $(gcc -print-libgcc- 
file-name)`/include/stdio.h

- - since libssp_nonshared.a is automatically linked with every file, it
    must exist in /usr/lib and not /usr/lib/static.  The statement:

      mv -v /usr/lib/{libopcodes,libssp,libssp_nonshared}.a /usr/lib/ 
static

    should be

      mv -v /usr/lib/{libopcodes,libssp}.a /usr/lib/static

- - if the libstdc++-pic.patch wasn't applied, this statement will fail:

      mv -v /usr/lib/libstdc++_pic.a /usr/lib/static/


6.13. Zlib-1.2.3

- - zlib needs an explicit -fPIC in the CFLAGS.

   After the ./configure execute:

     sed -i.orig -e 's/^CFLAGS=.*$/& -fPIC/' Makefile


6.15. Sed-4.1.5

- - if uClibc wasn't configured with MALLOC_GLIBC_COMPAT, then malloc(0)
   will return NULL instead of allocating 1 byte.  This causes sed to
   fail when attempting a re_malloc of zero which is valid in some  
cases.

   If so, download and apply:
     http://www.linuxfromscratch.org/patches/downloads/sed/sed-4.1.4- 
uClibc-1.patch

   (If you forget to apply this, the build will fail later with strange
   errors during configure.  To fix this, you must re-build the sed
   package, but first you need to remove the broken sed so that the
   version in /tools/bin is used instead, otherwise the configure for
   sed will fail.)


6.17. Coreutils-6.9

- - need to apply header hack as discussed in Chapter 5, but using /usr
   instead of /tools.

   Execute these commands:

     extra_config=""
     for f in stdio string unistd; do
	cp -v `dirname $(gcc -print-libgcc-file-name)`/include/$f.h $f.orig
	awk '{if (/#include_next/) { system("cat /usr/include/'$f'.h") }  
else { print $0 }}' $f.orig > $f.h
	extra_config="${extra_config} gl_cv_absolute_${f}_h=$(pwd)/$f.h"
     done

   Then run configure with the extra arguments:
     env "$extra_config" ./configure --prefix=/usr

- - there are some files in /bin that are symlinked to /tools/bin.
   Since the normal 'install' command isn't being used to install the
   files, they aren't removed first and the files they point to are
   updated instead.  Remove them before any attempt to copy over them:

     /tools/bin/rm -vf /bin/{cat,echo,pwd,rm,stty}


6.20. Findutils-4.2.31

- - need to apply same header file hack as Coreutils

- - there is a buffer overflow in findutils that prevents the -ls action
   from working properly (see http://savannah.gnu.org/bugs/?20751)

   Before running ./configure execute:

     sed -e 's/modebuf\[11\]/modebuf[12]/' -i.orig lib/listfile.c
     sed -e 's/modebuf\[10\]/modebuf[11]/' -i.orig lib/listfile.c


6.28. Groff-1.18.1.4

- - the old versions of groff attempt to implement its own getopt which
conflicts with the definition of the system version.

   Before running ./configure execute:

     sed -i -e 's/groff-getopt/getopt/' src/include/lib.h


6.30. Gettext-0.16.1

- - download and apply http://buildroot.uclibc.org/cgi-bin/viewcvs.cgi/ 
trunk/buildroot/package/gettext/gettext-error_print_progname.patch

- - the version should be 8 not 3, so

      mv -v /usr/lib/libintl.so.3* /lib
      ln -vsf ../../lib/libintl.so.3 /usr/lib/libintl.so

   need to be changed to

      mv -v /usr/lib/libintl.so.8* /lib
      ln -vsf ../../lib/libintl.so.8 /usr/lib/libintl.so


6.31. Inetutils-1.5

- - if uClibc wasn't configured with UCLIBC_HAS_GNU_GLOB, not all of the
   GLOB types are defined.

   Before running ./configure execute:

   sed -i -e 's/^.*flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_TILDE.*$/\
      flags = GLOB_NOCHECK; \
#ifdef GLOB_BRACE \
      flags |= GLOB_BRACE; \
#endif \
#ifdef GLOB_TILDE \
      flags |= GLOB_TILDE;\
#endif/' ftp/cmds.c

   This updates the code to only include values that are defined.


6.32. IPRoute2-2.6.20-070313

- - if uClibc wasn't configured with UCLIBC_HAS_IPV6, then execute the
   following commands before running make:

      sed -i -e '/do_ip6tunnel/d' ip/iptunnel.c ip/ip_common.h
      sed -i -e 's/ip6tunnel\.o//' ip/Makefile

   These prevent any of the IPv6 components from being built.


6.33. Perl-5.8.8

- - Perl attempts to build with "-fpic" which won't work.

   After ./configure.gnu is run, execute:

      sed -i -e 's at -fpic@-fPIC@' config.sh
      ./Configure -der

   This updates the automatically generated config and then re-runs the
   configuration setup with the new values.


6.42. Kbd-1.12

- - compiling with "-ansi" doesn't work.

   After ./configure is run, execute:

      sed -i -e 's at -ansi@@' openvt/Makefile


6.45. Gzip-1.3.12

- - need to apply same header file hack as Coreutils


6.47. Make-3.81

- - if uClibc wasn't configured with UCLIBC_HAS_GNU_GLOB, not all of the
   GLOB types are defined in the system libraries.  Make can be compiled
   to use an internal version by passing an extra arguments to
   configure.

   Configure should be executed as:

   env make_cv_sys_gnu_glob="no" GLOBINC=-I`pwd`/glob \
       GLOBLIB=glob/libglob.a \
       ./configure --prefix=/usr

   When these values are defined, make compiles and links against its
   internal library.

6.50. Procps-3.2.7

- - there is a problem running programs linked against uClibc when
   compiled with "-ffast-math" (stack alignment issues, see
   http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00929.html, among
   others).  Also, need to use explicit "-fPIC".
   Execute before running make:

     sed -i -e 's at -ffast-math@-fno-fast-math@' Makefile
     sed -i -e 's at -fpic@-fPIC@' proc/module.mk


6.51. Psmisc-22.5

- - if uClibc wasn't configured with UCLIBC_HAS_IPV6, then
   "--disable-ipv6" needs to be passed to configure

- - if uClibc wasn't configured with MALLOC_GLIBC_COMPAT, then need to
   lie about the malloc capabilities (see
   http://uclibc.org/FAQ.html#gnu_malloc).

   So, use extra args to ./configure:

   env ac_cv_func_malloc_0_nonnull=yes  
ac_cv_func_realloc_0_nonnull=yes \
   ./configure --disable-ipv6 ...

   or if IPv6 was configured,

   env ac_cv_func_malloc_0_nonnull=yes  
ac_cv_func_realloc_0_nonnull=yes \
   ./configure ...


6.52. Shadow-4.0.18.1

- - uClibc doesn't support NIS

   After running ./configure execute:

     sed -i -e 's/#define RUSEROK 0//' config.h

   Download and apply:

     - http://www.geocities.com/robm351/uclibc/shadow-uclibc.diff.txt

   This removes the dependency on NIS.


6.53. Util-linux-2.12r

- - if uClibc wasn't compiled with UCLIBC_HAS_RPC, then NFS isn't
   available.

   Before running ./configure execute:

     sed -i.orig -e 's/^NFS_OBJS = .*$/NFS_OBJS = /' -e \
     's/-DHAVE_NFS//' mount/Makefile

- - there is a buffer overflow in sfdisk that prevents it from working
   properly (see https://bugzilla.redhat.com/show_bug.cgi?id=159418)

   After running ./configure execute:
     sed -i -e 's/line+2, linesize/line+2, linesize-2/' fdisk/sfdisk.c


At this point the HLFS book ends and you boot your system to much  
rejoicing.

As far as stability is concerned, I built a machine using these notes
to enter in the "0wn the box? Own the box!" contest at Defcon 15.  The
system ran for over 48 hours unattended without crashing even under
various DOS and hack attacks.  I was very happy with the results.

Hope this information is useful to somebody.

Thanks,
Greg

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (Darwin)

iD8DBQFG6Ld6WbVJrJm/lrsRAjXcAJ9RPl5v0KZRCOWSs9oVch5lapVLKwCfazXE
ME7yIEfm4LMEXKbYak33fdQ=
=17z0
-----END PGP SIGNATURE-----



More information about the hlfs-dev mailing list