wiki:toolchain/x86_64/04_temp_tool_chain

Constructing the temporary /tools directory

Echo

Check one last time that your environment variable is set up properly:

echo $LINEXA

Binutils-2.31.1 Pass 1

cd $LINEXA/sources/binutils-2.31.1

The Binutils documentation recommends building Binutils outside of the source directory in a dedicated build directory:

/!\ make sure texinfo is installed on your host system!

mkdir -v ../binutils-build &&
cd ../binutils-build

Install:

../binutils-2.31.1/configure \
  --target=$LINEXA_TARGET \
  --prefix=/tools \
  --with-sysroot=$LINEXA \
  --with-lib-path=/tools/lib \
  --disable-nls \
  --disable-werror &&

make 
case $(uname -m) in
  x86_64) mkdir -v /tools/lib && ln -sv lib /tools/lib64 ;;
esac

make install

GCC 7.3.0 Pass 1

[^]

Extract the sources and cd into the directory...

Get the MPFR and GMP sources into the tree:

tar -xf ../mpfr-4.0.1.tar.xz
mv -v mpfr-4.0.1 mpfr
tar -xf ../gmp-6.1.2.tar.xz
mv -v gmp-6.1.2 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc

The following command will change the location of GCC's default dynamic linker to use the one installed in /tools. It also removes /usr/include from GCC's include search path.

for file in gcc/config/{linux,i386/linux{,64}}.h
do
  cp -uv $file{,.orig}
  sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
      -e 's@/usr@/tools@g' $file.orig > $file
  echo '
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
  touch $file.orig
done

Finally, on x86_64 hosts, set the default directory name for 64-bit libraries to “lib”:

case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
 ;;
esac

The GCC documentation recommends building GCC outside of the source directory in a dedicated build directory:

mkdir -v ../gcc-build &&
cd ../gcc-build

/!\ make sure there is a g++ compiler installed in the host system, e.g. apt-get install g++ !

../gcc-7.3.0/configure \
  --target=$LINEXA_TARGET \
  --prefix=/tools \
  --with-glibc-version=2.18 \
  --with-sysroot=$LINEXA \
  --with-newlib \
  --without-headers \
  --with-local-prefix=/tools \
  --with-native-system-header-dir=/tools/include \
  --disable-nls \
  --disable-shared \
  --disable-multilib \
  --disable-decimal-float \
  --disable-threads \
  --disable-libatomic \
  --disable-libmpx \
  --disable-libquadmath \
  --disable-libgomp \
  --disable-libvtv \
  --disable-libssp \
  --disable-libstdcxx \
  --enable-languages=c,c++ 

make && make install

Linux-Headers-4.18.9

[^]

Extract the kernel sources and cd into that directory.

cd /mnt/loop/sources/linux-4.18.9
make mrproper &&
make INSTALL_HDR_PATH=dest headers_install &&
cp -rv dest/include/* /tools/include

This installs the header files that are common to all architectures.

Glibc-2.26

[^]

Extract the sources and cd into that directory.

cd /mnt/loop/sources/glibc-2.26

The Glibc documentation recommends building Glibc outside of the source directory in a dedicated build directory:

mkdir -v ../glibc-build &&
cd ../glibc-build
echo "slibdir=/tools/lib" >> configparms
../glibc-2.26/configure --prefix=/tools \
  --host=$LINEXA_TARGET \
  --build=$(../glibc-2.26/scripts/config.guess) \
  --enable-obsolete-rpc \
  --enable-kernel=3.4.0 \
  --disable-profile \
  --with-headers=/tools/include \
    libc_cv_forced_unwind=yes \
    libc_cv_c_cleanup=yes &&
    make 
    make install

Configure Options:

--host=${LINEXA_TARGET}, --build=$(../glibc-2.28/scripts/config.guess)

The combined effect of these switches is that Glibc's build system configures itself to cross-compile, using the cross-linker and cross-compiler in /tools.

--disable-profile

This builds the libraries without profiling information. Omit this option if profiling on the temporary tools is necessary.

--enable-obsolete-rpc

This installs NIS and RPC related headers that are not installed by default. They are required to build GCC and by several BLFS packages.

--enable-kernel=2.6.32

This tells Glibc to compile the library with support for 2.6.32 Linux kernels.

--with-headers=/tools/include

This tells Glibc to compile itself against the headers recently installed to the tools directory, so that it knows exactly what features the kernel has and can optimize itself accordingly.

libc_cv_forced_unwind=yes

The build requires support for forced unwind, but because it is being cross compiled, it cannot auto detect it. Setting this variable on the command line explicitly tells the configure script that support is available.

libc_cv_c_cleanup=yes

The build also requires support for C cleanup handling, which it cannot auto detect when being cross compiled. Enable it explicitly

libc_cv_ctors_header=yes

Simlarly, we pass libc_cv_ctors_header=yes through to the configure script so that the test is skipped and gcc constructor support is configured.


[^]

Test the linker

echo 'int main(){}' > dummy.c &&
$LINEXA_TARGET-gcc dummy.c &&
readelf -l a.out | grep ': /tools'

The Output should be something like this:

   [Requesting program interpreter: /tools/lib/ld-linux.so.2]

Clean up

rm -v dummy.c a.out

NOTE for 64-bit machines, the interpreter name will be /tools/lib64/ld-linux-x86-64.so.2


[^]

Libstdc++-7.3.0

tar xf gcc-7.3.0.tar.xz &&
cd gcc-7.3.0 &&
mkdir ../gcc-build &&
cd ../gcc-build
../gcc-7.3.0/libstdc++-v3/configure \
 --host=$LINEXA_TARGET \
 --prefix=/tools \
 --disable-multilib \
 --disable-nls \
 --disable-libstdcxx-threads \
 --disable-libstdcxx-pch \
 --with-gxx-include-dir=/tools/$LINEXA_TARGET/include/c++/7.3.0

 make && make install

Binutils-2.31.1 Pass 2

Remove and re-extract the sources, cd into the directory. The Binutils documentation recommends building Binutils outside of the source directory in a dedicated build directory.

mkdir -v ../binutils-build &&
 cd ../binutils-build
CC=$LINEXA_TARGET-gcc \
RANLIB=$LINEXA_TARGET-ranlib \
AR=$LINEXA_TARGET-ar \
  ../binutils-2.31.1/configure \
  --host=$LINEXA_TARGET \
  --prefix=/tools \
  --disable-nls \
  --disable-werror \
  --with-lib-path=/tools/lib \
  --with-sysroot &&

  make && make install &&
  make -C ld clean && make -C ld LIB_PATH=/usr/lib:/lib &&
  cp -v ld/ld-new /tools/bin

GCC 7.3.0 Pass 2

Extract the sources and cd into the directory.

The following is mainly based on the LFS setup

cat gcc/limitx.h gcc/glimits.h gcc/limity.h > \
  `dirname $($LINEXA_TARGET-gcc -print-libgcc-file-name)`/include-fixed/limits.h

[^]

for file in gcc/config/{linux,i386/linux{,64}}.h
do
  cp -uv $file{,.orig}
  sed -e 's@/lib\(64\)\?\(32\)\?/ld@/tools&@g' \
  -e 's@/usr@/tools@g' $file.orig > $file
  echo '
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define STANDARD_STARTFILE_PREFIX_1 "/tools/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""' >> $file
  touch $file.orig
done

change the default directory name for 64-bit libraries to “lib”

case $(uname -m) in
  x86_64)
    sed -e '/m64=/s/lib64/lib/' \
        -i.orig gcc/config/i386/t-linux64
  ;;
esac

As in the first build of GCC it requires the GMP, MPFR and MPC packages. Unpack the tarballs and move them into the required directory names :

[^]

tar -xf ../mpfr-4.0.1.tar.xz
mv -v mpfr-4.0.1 mpfr
tar -xf ../gmp-6.1.2.tar.xz
mv -v gmp-6.1.2 gmp
tar -xf ../mpc-1.1.0.tar.gz
mv -v mpc-1.1.0 mpc
mkdir -v ../gcc-build &&
cd ../gcc-build
CC=$LINEXA_TARGET-gcc \
CXX=$LINEXA_TARGET-g++ \
AR=$LINEXA_TARGET-ar \
RANLIB=$LINEXA_TARGET-ranlib \
../gcc-7.3.0/configure \
  --prefix=/tools \
  --with-local-prefix=/tools \
  --with-native-system-header-dir=/tools/include \
  --enable-languages=c,c++ \
  --disable-libstdcxx-pch \
  --disable-multilib \
  --disable-libgomp \
  --disable-bootstrap &&

make && make install &&
ln -sv gcc /tools/bin/cc

It is mandatory to stop and ensure that the basic functions (compiling and linking) of the new toolchain are working as expected!

echo 'int main(){}' > dummy.c
cc dummy.c
readelf -l a.out | grep ': /tools'

NOTE The output must be [Requesting program interpreter: /tools/lib64/ld-linux-x86-64.so.2]

Clean up

rm -v dummy.c a.out

Tcl-8.6.8

[^]

Extract the sources and cd into the directory

 cd unix &&
  ./configure --prefix=/tools &&
  make && make install &&
  chmod -v u+w /tools/lib/libtcl8.6.so &&
  make install-private-headers &&
  ln -sv tclsh8.6 /tools/bin/tclsh

Expect-5.45.4

[^]

Extract the sources and cd into the directory.

Next, force Expect's configure script to use /bin/stty instead of a /usr/local/bin/stty it may find on the host system. This will ensure that our testsuite tools remain sane for the final builds of our toolchain:

cp -v configure{,.orig}
sed 's:/usr/local/bin:/bin:' configure.orig > configure
./configure --prefix=/tools --with-tcl=/tools/lib \
  --with-tclinclude=/tools/include &&
  make && make SCRIPTS="" install

DejaGNU-1.6.1

Extract the sources and cd into the directory

./configure --prefix=/tools && make && make install

M4-1.4.18

Extract the sources and cd into the directory.

First, make some fixes required by glibc-2.28

sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
./configure --prefix=/tools &&  make && make install

Check-0.12.0

[^]

Extract the sources and cd into the directory

PKG_CONFIG= ./configure --prefix=/tools && make && make install

Ncurses-6.1

Extract the sources and cd into the directory

First, ensure that gawk is found first during configuration

sed -i s/mawk// configure
./configure --prefix=/tools \
  --with-shared \
  --without-debug \
  --without-ada \
  --enable-widec \
  --enable-overwrite &&

make && make install 

Bash-4.4.18

[^]

Extract the sources and cd into the directory, apply the following patches:

NOTE install bison on the host!

./configure --prefix=/tools \
  --without-bash-malloc &&

make && make install &&
ln -sv bash /tools/bin/sh

Compile Options:

--without-bash-malloc
This option turns off the use of Bash's memory allocation (malloc) function which is known to cause segmentation faults. By turning this option off, Bash will use the malloc functions from Glibc which are more stable.

Bison-3.1

[^]

Extract the sources and cd into the directory:

./configure --prefix=/tools 
make && make install

Bzip2-1.0.6

Extract the sources and cd into the directory

  • The Bzip2 package does not contain a configure script. Compile it with:
make -f Makefile-libbz2_so
make bzip2 libbz2.a && make PREFIX=/tools install

NOTE The above comannd shouldn't be altered to what is said in LFS. Otherwise libarchive won#t compile!

Coreutils-8.30

Extract the sources and cd into the directory.

./configure \
  --prefix=/tools \
  --enable-install-program=hostname &&

make && 
make install

Diffutils-3.6

[^]

Extract the sources and cd into the directory

./configure --prefix=/tools && make && make install

File-5.34

Extract the sources and cd into the directory.

./configure --prefix=/tools && make && make install

Findutils-4.6.0

Extract the sources and cd into the directory.

Fiexes for glibc 2.28

sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' gl/lib/*.c
sed -i '/unistd/a #include <sys/sysmacros.h>' gl/lib/mountlist.c
echo "#define _IO_IN_BACKUP 0x100" >> gl/lib/stdio-impl.h
./configure --prefix=/tools && make && make install

Gawk-4.2.1

[^]

Extract the sources and cd into the directory.

./configure --prefix=/tools && make && make install

Gettext-0.19.8.1

Extract the sources and cd into the directory. Only the programs in the gettext-tools directory need to be installed for the temp-system:

cd gettext-tools
EMACS="no"  ./configure --prefix=/tools \
  --disable-shared 
make -C gnulib-lib &&
make -C intl pluralx.c &&
make -C src msgfmt &&
make -C src msgmerge &&
make -C src xgettext &&
cp -v src/{msgfmt,msgmerge,xgettext} /tools/bin

Grep-3.1

Extract the sources and cd into the directory

./configure --prefix=/tools && make && make install

Gzip-1.9

[^]

Extract the sources and cd into the directory.

Fixes for glibc-2.28

sed -i 's/IO_ftrylockfile/IO_EOF_SEEN/' lib/*.c
echo "#define _IO_IN_BACKUP 0x100" >> lib/stdio-impl.h
./configure --prefix=/tools &&  make && make install

Make-4.2.1

Extract the sources and cd into the directory.

Work around an error caused by glibc-2.27

sed -i '211,217 d; 219,229 d; 232 d' glob/glob.c
./configure --prefix=/tools --without-guile &&  make && make install

Patch-2.7.6

[^]

Extract the sources and cd into the directory.

./configure --prefix=/tools  &&  make && make install

Perl-5.28.0

Extract the sources and cd into the directory.

Prepare Perl for compilation.

sh Configure -des -Dprefix=/tools -Dlibs=-lm &&
make &&
cp -v perl cpan/podlators/scripts/pod2man /tools/bin &&
mkdir -pv /tools/lib/perl5/5.28.0 &&
cp -Rv lib/* /tools/lib/perl5/5.28.0

Sed-4.5

[^]

Extract the sources and cd into the directory.

./configure --prefix=/tools  && make && make install

Tar-1.30

Extract the sources and cd into the directory.

./configure --prefix=/tools &&  make && make install

Texinfo-6.5

Extract the sources and cd into the directory.

./configure --prefix=/tools && make && make install

Util-linux-2.32.1

Extract the sources and cd into the directory.

./configure \
  --prefix=/tools \
  --without-python \
  --disable-makeinstall-chown \
  --without-systemdsystemunitdir \
  --with-bashcompletiondir=/tools/share/bash-completion/completions &&

  PKG_CONFIG="" && make && make install

Xz-5.2.4

[^]

Extract the sources and cd into the directory.

./configure --prefix=/tools  &&  make && make install

Packeges needed for package mangement and further building within the qemu-image

E2fsprogs-1.44.4

[^]

/!\ make sure libblkid-dev and uuid-dev are installed in the host system! Extract the sources and cd into the directory

The E2fsprogs documentation recommends that the package be built in a subdirectory of the source tree:

mkdir -v build &&
cd build
  ../configure \
  --prefix=/tools \
  --mandir=/tools/man \
  --disable-fsck \
  --disable-libblkid \
  --disable-libuuid \
  --disable-uuidd 
make && make install &&
make install-libs &&
chmod -v u+w /tools/lib/{libcom_err,libe2p,libext2fs,libss}.a

Iana-Etc-2.30

Extract the sources and cd into the directory. Install:

make && make ETC_DIR=$LINEXA/tools/etc install

Inetutils-1.9.4

Extract the sources and cd into the directory.

./configure --prefix=/tools \
  --disable-logger \
  --disable-whois \
  --disable-rcp \
  --disable-rexec \
  --disable-rlogin \
  --disable-rsh \
  --disable-servers && make && make install

Net-tools-CVS_20101030

Extract the sources and cd into the directory.

patch -Np1 -i ../net-tools-CVS_20101030-remove_dups-1.patch &&
sed -i '/#include <netinet\/ip.h>/d'  iptunnel.c &&

yes "" | make config &&
make
make BASEDIR=/tools update

zlib-1.2.11

./configure --prefix=/tools &&  make && make install

openssl-1.0.2o

NOTE check, if make install is executed!

Extract the sources and cd into the directory.

./config --prefix=/tools \
  shared \
  zlib-dynamic && make && make install

libarchive-3.1.2

[^]

Extract the sources and cd into the directory. Pacman requires the shared and static libraries:

./configure --prefix=/tools \
  --with-gnu-ld \
  --without-xml2 && make && make install

wget-1.16

Extract the sources and cd into the directory.

./configure --prefix=/tools --sysconfdir=/tools/etc --with-ssl=openssl &&
make && make install

openssh-7.7p1

We will need ssh support when building the core packages within the qemu image!

./configure \
  --prefix=/tools \
  --includedir=/tools/include \
  --with-privsep-path=/tools/var/empty \
  --with-pid-dir=/tools/var/run && make && make install

Configure Options:

--with-privsep-path=

--with-pid-dir=

These options must be set because the default is set to /var/empty and /var/run .

Pacman-4.0.3

[^]

Extract the sources and cd into the directory. Pacman requires the shared and static libraries:

./configure --prefix=/tools \
  --with-sysroot=/tools \
  --with-gnu-ld \
  --without-gpgme \
  --disable-doc \
  --enable-static \
  --without-libcurl \
  --with-pkg-ext='.pkg.tar.xz' \
  --with-src-ext='.src.tar.xz' &&
make && make install &&
sed -i 's@/usr/bin/wget@/tools/bin/wget@' /tools/etc/makepkg.conf &&
sed -i "s|'ftp.*|'ftp::/tools/bin/wget -c --passive-ftp -t 3 --waitretry=3 -O %o %u'|" /tools/etc/makepkg.conf &&
sed -i "s|'https.*|'https::/tools/bin/wget -c -t 3 --waitretry=3 --no-check-certificate -O %o %u'|" /tools/etc/makepkg.conf &&
sed -i "s|'http::.*|'http::/tools/bin/wget -c -t 3 --waitretry=3 -O %o %u'|" /tools/etc/makepkg.conf &&
sed -i 's@/usr@/tools@g' /tools/bin/makepkg

rsync-3.1.3

Extract the sources and cd into the directory.

./configure --prefix=/tools && make && make install

joe-4.6

Extract the sources and cd into the directory.

./configure --prefix=/tools --sysconfdir=/tools/etc && make && make install

shadow-4.6

Extract the sources and cd into the directory.

./configure --prefix=/tools && make && make install

Creating Essential Dirs

mkdir -pv $LINEXA/{bin,boot,dev{,/shm,/pts},{etc/,}opt,home,lib/firmware,mnt} &&
mkdir -pv $LINEXA/{proc,media/{floppy,cdrom},sbin,srv,sys} &&
mkdir -pv $LINEXA/var/{opt,cache,lib/{color,misc,locate},local} &&
mkdir -pv $LINEXA/var/{log,mail,spool} &&
mkdir -pv $LINEXA/run/lock &&
install -dv -m 0750 $LINEXA/root &&
install -dv -m 1777 ${LINEXA}{/var,}/tmp &&
case $(uname -m) in
 x86_64) mkdir -v $LINEXA/lib64 ;;
esac
mkdir -v  $LINEXA/usr/libexec
mkdir -pv $LINEXA/usr/{,local/}{bin,include,lib,sbin,src} &&
mkdir -pv $LINEXA/usr/{,local/}share/{doc,info,locale,man} &&
mkdir -pv $LINEXA/usr/{,local/}share/{misc,terminfo,zoneinfo} &&
mkdir -pv $LINEXA/usr/{,local/}share/man/man{1..8} &&
for dir in $LINEXA/usr{,/local}; do
  ln -sv /usr/share/{man,doc,info} $dir
done
ln -sv /tools/bin/{bash,cat,echo,grep,pwd,rm,stty,login,mount,ln,mkdir,rsync,ssh-keygen,chmod,passwd,joe,sed,ifconfig} $LINEXA/bin &&
ln -sv /tools/sbin/route $LINEXA/sbin &&
ln -sv /tools/bin/{env,install,perl,file} $LINEXA/usr/bin &&
ln -sv /tools/lib/libgcc_s.so{,.1} $LINEXA/usr/lib &&
ln -sv /tools/lib/libstdc++.{a,so{,.6}} $LINEXA/usr/lib

install -vdm755 $LINEXA/usr/lib/pkgconfig

ln -sv bash $LINEXA/bin/sh
ln -sv /proc/self/mounts $LINEXA/etc/mtab

[^]

for lib in blkid lzma mount uuid do

ln -sv /tools/lib/lib$lib.so* $LINEXA/usr/lib

done ln -svf /tools/include/blkid $LINEXA/usr/include ln -svf /tools/include/libmount $LINEXA/usr/include ln -svf /tools/include/uuid $LINEXA/usr/include for pc in blkid mount uuid do

sed 's@tools@usr@g' /tools/lib/pkgconfig/${pc}.pc \

$LINEXA/usr/lib/pkgconfig/${pc}.pc

done

Creating Essential Files

cat > ${LINEXA}/etc/passwd << "EOF"
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/dev/null:/bin/false
nobody:x:99:99:Unprivileged User:/dev/null:/bin/false
sshd:x:50:50:OpenSSH daemon:/var/lib/sshd:/bin/false
rsyncd:x:48:48:rsyncd Daemon:/var/lib/rsyncd:/bin/false
EOF
cat > ${LINEXA}/etc/group << "EOF"
root:x:0:
bin:x:1:
sys:x:2:
kmem:x:3:
tty:x:4:
tape:x:5:
daemon:x:6:
floppy:x:7:
disk:x:8:
lp:x:9:
dialout:x:10:
audio:x:11:
video:x:12:
utmp:x:13:
usb:x:14:
cdrom:x:15:
mail:x:34:
nogroup:x:99:
sshd:x:50:
rsyncd:x:48:
EOF
touch ${LINEXA}/run/utmp ${LINEXA}/var/log/{btmp,lastlog,faillog,wtmp}
chgrp -v utmp ${LINEXA}/var/log/lastlog
chmod -v 664 ${LINEXA}/run/utmp ${LINEXA}/var/log/lastlog
chmod -v 600 ${LINEXA}/var/log/btmp

Stripping

strip --strip-debug /tools/lib/*
/usr/bin/strip --strip-unneeded /tools/{,s}bin/*

rm -rf /tools/{,share}/{info,man,doc}

find /tools/{lib,libexec} -name \*.la -delete

Clean up

cd /mnt/loop/sources
find . -type d -exec rm -rf {} +

Chown /mnt/loop

exit
chown -R root /mnt/loop/tools
umount /mnt/loop
losetup -d /dev/loop1

Copy the image and the kernel

scp -P <port> /virtual/toolchain.img <new_host>/directory
scp -P <port> /boot/vmlinuz <new_host>/directory
Last modified 19 months ago Last modified on Oct 1, 2018 5:04:59 PM