Scripts for bootstrapping various programming languages
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

431 lines
14 KiB

#!/bin/sh
set -e
# Example cross compile for x86_64, multilib-enabled
# This can be adapted for different architectures, but do note that some
# architectures will need more recent versions of gcc/glibc/tools.
# The version of gcc in /bootstrap should be able to build any such newer
# versions, at least as of right now (GCC 10.2).
# To homogenize build instructions across both multilib and non-multilib
# installs, and because some applications require heavy patches to install
# in alternate libdirs (cough cough python), the lib directory will contain
# native libraries, while lib32 whill contain 32-bit libraries.
# GCC will be patched slightly, and configured to achieve this, as by default
# it uses lib64 and lib.
# To initialize/enter chroot:
# mkdir dev tmp
# mknod dev/null c 1 3
# ./bootstrap/bin/chroot . /bootstrap/bin/env -i NPROC="$(nproc)" /bootstrap/bin/sh /sources/build_cross.sh
# Amount of make threads, configure this to your liking.
# This can be obtained using `getconf _NPROCESSORS_ONLN`, but requires /proc
# to be mounted, which we avoid.
export MAKEFLAGS="-j${NPROC:-4}"
cd /sources
#### Make a cross-compiler
export PATH=/cross/bin:/bootstrap/bin
rm -rf /cross /system
# kernel headers
rm -rf linux-4.14
tar zxf linux-4.14.tar.gz
( cd linux-4.14
make mrproper
make ARCH=x86_64 INSTALL_HDR_PATH="$PWD/install" headers_install
find install -type f ! -name "*.h" -exec rm {} +
mkdir -p /system/bootstrap/
cp -a install/include /system/bootstrap/
)
rm -rf linux-4.14
# Install cross binutils
rm -rf binutils-2.20.1
tar jxf binutils-2.20.1a.tar.bz2
( cd binutils-2.20.1
./configure \
--build=i686-pc-linux-gnu \
--target=x86_64-pc-linux-gnu \
--prefix=/cross \
--with-sysroot=/system \
--disable-shared \
--disable-nls \
--disable-werror
make
make install
)
rm -rf binutils-2.20.1
# Configure the gcc source
rm -rf gcc-4.9.4
tar jxf gcc-4.9.4.tar.bz2
( cd gcc-4.9.4
tar jxf ../gmp-4.3.2.tar.bz2
mv gmp-4.3.2 gmp
tar jxf ../mpfr-2.4.2.tar.bz2
mv mpfr-2.4.2 mpfr
tar zxf ../mpc-1.0.3.tar.gz
mv mpc-1.0.3 mpc
# Set up the location of target glibc
cat >> gcc/config/i386/t-linux64 << 'EOF'
MULTILIB_OSDIRNAMES = m64=../lib
MULTILIB_OSDIRNAMES+= m32=../lib32
EOF
cat >> gcc/config/i386/linux64.h << 'EOF'
#undef GLIBC_DYNAMIC_LINKER32
#undef GLIBC_DYNAMIC_LINKER64
#undef STANDARD_STARTFILE_PREFIX_1
#undef STANDARD_STARTFILE_PREFIX_2
#define GLIBC_DYNAMIC_LINKER32 "/bootstrap/lib32/ld-linux.so.2"
#define GLIBC_DYNAMIC_LINKER64 "/bootstrap/lib/ld-linux-x86-64.so.2"
#define STANDARD_STARTFILE_PREFIX_1 "/bootstrap/lib/"
#define STANDARD_STARTFILE_PREFIX_2 ""
EOF
mkdir build && cd build # Build breaks without a build directory
../configure \
--build=i686-pc-linux-gnu \
--target=x86_64-pc-linux-gnu \
--prefix=/cross \
--with-sysroot=/system \
--with-native-system-header-dir=/bootstrap/include \
--with-local-prefix=/bootstrap \
--with-host-libstdcxx=-lsupc++ \
--enable-multilib \
--enable-languages=c,c++ \
--disable-nls
)
# Install the compiler
make -C gcc-4.9.4/build all-gcc
make -C gcc-4.9.4/build install-gcc
# Configure the glibc source
rm -rf glibc-2.16.0
tar jxf glibc-2.16.0.tar.bz2
( cd glibc-2.16.0
# Fix hardcode of /bin/pwd
sed -i -e 's@/bin/pwd@pwd@g' configure
# Fix building cross-rpcgen without host rpc headers
sed -i -e 's/$(ALL_BUILD_CFLAGS)/-I. &/' sunrpc/Makefile
mkdir build && cd build
../configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--prefix=/bootstrap \
libc_cv_ssp=no \
libc_cv_forced_unwind=yes
cd ..
mkdir build32 && cd build32
../configure \
CC='x86_64-pc-linux-gnu-gcc -m32' \
CXX='x86_64-pc-linux-gnu-g++ -m32' \
--build=i686-bootstrap-linux-gnu \
--host=i686-pc-linux-gnu \
--prefix=/bootstrap \
--libdir=/bootstrap/lib32 \
libc_cv_slibdir=/bootstrap/lib32 \
libc_cv_ssp=no \
libc_cv_forced_unwind=yes
)
# Installing libgcc by using --without-headers --with-newlib in the gcc config
# would avoid having to install csu+headers before building libgcc,
# thereby simplifying the instructions slightly.
# I don't think that simplification is particularly worth it, however.
# Do the whole gcc/glibc song and dance...
# DESTDIR set to a different dir since glibc makefile breaks otherwise...
make -C glibc-2.16.0/build DESTDIR=/system csu/subdir_install
make -C glibc-2.16.0/build32 DESTDIR=/system csu/subdir_install
make -C glibc-2.16.0/build DESTDIR=/system install-bootstrap-headers=yes install-headers
touch /system/bootstrap/include/gnu/stubs.h
x86_64-pc-linux-gnu-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o /system/bootstrap/lib/libc.so
x86_64-pc-linux-gnu-gcc -m32 -nostdlib -nostartfiles -shared -x c /dev/null -o /system/bootstrap/lib32/libc.so
make -C gcc-4.9.4/build all-target-libgcc
make -C gcc-4.9.4/build install-target-libgcc
make -C glibc-2.16.0/build all
make -C glibc-2.16.0/build32 all
make -C glibc-2.16.0/build32 DESTDIR="$PWD/glibc_install" install
make -C glibc-2.16.0/build DESTDIR="$PWD/glibc_install" install
# TODO: Would running force-install instead work?
cp -a glibc_install/bootstrap /system/
rm -rf glibc_install
make -C gcc-4.9.4/build all-target-libstdc++-v3
make -C gcc-4.9.4/build install-target-libstdc++-v3
rm -rf glibc-2.16.0
rm -rf gcc-4.9.4/build
#### Cross-compile the compiler for the target
# Binutils
rm -rf binutils-2.20.1
tar jxf binutils-2.20.1a.tar.bz2
( cd binutils-2.20.1
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--prefix=/bootstrap \
--with-lib-path=/bootstrap/lib \
--with-sysroot \
--disable-shared \
--disable-nls \
--disable-werror
make
make DESTDIR=/system install
)
rm -rf binutils-2.20.1
# GCC (using the unpacked+patched archive from before)
rm -rf gcc-4.9.4/build
( cd gcc-4.9.4
mkdir build && cd build
../configure \
CC_FOR_TARGET=x86_64-pc-linux-gnu-gcc \
CXX_FOR_TARGET=x86_64-pc-linux-gnu-g++ \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--prefix=/bootstrap \
--with-native-system-header-dir=/bootstrap/include \
--with-local-prefix=/bootstrap \
--enable-multilib \
--enable-languages=c,c++ \
--disable-nls
make all-gcc all-target-libgcc all-target-libstdc++-v3
make DESTDIR=/system install-gcc install-target-libgcc install-target-libstdc++-v3
)
rm -rf gcc-4.9.4
#### Install a bunch of tools for the target
rm -rf coreutils-5.0
tar jxf coreutils-5.0.tar.bz2
( cd coreutils-5.0
# Fix conflicting type errors
sed -i -e '/^char \*malloc/d' lib/putenv.c
sed -i -e 's/tee /tee_files /g' src/tee.c
sed -i -e 's/eaccess/_&/g' src/test.c
./configure \
--prefix=/bootstrap \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls \
ac_cv_func_malloc_0_nonnull=yes \
am_cv_func_working_getline=yes \
utils_cv_sys_open_max=1019
make -C lib
make -C src
make -C src DESTDIR=/system install-exec
# Link chroot statically (optional if you can use the host's chroot)
x86_64-pc-linux-gnu-gcc -static -O2 -o /system/bootstrap/bin/chroot src/chroot.o lib/libfetish.a
)
rm -rf coreutils-5.0
rm -rf bash-4.4
tar zxf bash-4.4.tar.gz
( cd bash-4.4
# The configure script can't run a lot of tests when cross-compiling,
# so a lot of the tests are specified manually to match a native build.
# This fixes some otherwise-broken scripts when building Gentoo for example.
# It uses the following test: [[ $(< <(echo foo) ) == foo ]]
# to check for a sane bash.
# Xz also has issues building with a cross-compiled bash.
# I encourage you to compare the config.h with a native build!
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls \
ac_cv_func_chown_works=yes \
ac_cv_func_mmap_fixed_mapped=yes \
ac_cv_func_strcoll_works=yes \
bash_cv_func_sigsetjmp=present \
bash_cv_getcwd_malloc=yes \
bash_cv_job_control_missing=no \
bash_cv_printf_a_format=yes \
bash_cv_sys_named_pipes=yes \
bash_cv_sys_siglist=yes \
bash_cv_ulimit_maxfds=yes \
bash_cv_under_sys_siglist=yes \
bash_cv_unusable_rtsigs=no \
bash_cv_wcwidth_broken=yes \
bash_cv_wexitstatus_offset=8
make bash
install -Dm755 bash /system/bootstrap/bin/bash
ln -sf bash /system/bootstrap/bin/sh
)
rm -rf bash-4.4
rm -rf gzip-1.2.4
tar zxf gzip-1.2.4.tar.gz
( cd gzip-1.2.4
# -DSTDC_HEADERS=1 -DHAVE_UNISTD_H=1 -DDIRENT=1
# Such an old configure script doesn't support cross-compiling...
set -x
x86_64-pc-linux-gnu-gcc -DSTDC_HEADERS=1 -w -O2 -o gzip gzip.c zip.c deflate.c trees.c bits.c unzip.c inflate.c util.c crypt.c lzw.c unlzw.c unpack.c unlzh.c getopt.c
CC=x86_64-pc-linux-gnu-gcc ./configure
make gzip
install -Dm755 gzip /system/bootstrap/bin/gzip
ln -sf gzip /system/bootstrap/bin/gunzip
ln -sf gzip /system/bootstrap/bin/zcat
)
rm -rf gzip-1.2.4
rm -rf bzip2-1.0.8
tar zxf bzip2-1.0.8.tar.gz
( cd bzip2-1.0.8
make \
CC=x86_64-pc-linux-gnu-gcc \
AR=x86_64-pc-linux-gnu-ar \
bzip2
install -Dm755 bzip2 /system/bootstrap/bin/bzip2
ln -sf bzip2 /system/bootstrap/bin/bunzip2
ln -sf bzip2 /system/bootstrap/bin/bzcat
)
rm -rf bzip2-1.0.8
rm -rf tar-1.22
tar jxf tar-1.22.tar.bz2
( cd tar-1.22
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls
make -C lib
make -C src
install -Dm755 src/tar /system/bootstrap/bin/tar
)
rm -rf tar-1.22
rm -rf grep-2.0
tar zxf grep-2.0.tar.gz
( cd grep-2.0
# -DGREP -DSTDC_HEADERS=1 -DHAVE_STRING_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_UNISTD_H=1 -DHAVE_ALLOCA_H=1 -DHAVE_GETPAGESIZE=1 -DHAVE_MEMCHR=1 -DHAVE_STRERROR=1 -DHAVE_VALLOC=1 -DHAVE_WORKING_MMAP=1
# Such an old configure script doesn't support cross-compiling...
set -x
x86_64-pc-linux-gnu-gcc -DSTDC_HEADERS=1 -DHAVE_MEMCHR=1 -DHAVE_STRERROR=1 -w -O2 -o grep grep.c getopt.c regex.c dfa.c kwset.c obstack.c search.c
install -Dm755 grep /system/bootstrap/bin/grep
ln -sf grep /system/bootstrap/bin/egrep
ln -sf grep /system/bootstrap/bin/fgrep
)
rm -rf grep-2.0
# Optional, rationale for inclusion same as in build_bootstrap.sh
rm -rf findutils-4.6.0
tar zxf findutils-4.6.0.tar.gz
( cd findutils-4.6.0
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls
make -C gl
make -C lib
make -C find
make -C xargs
install -Dm755 find/find /system/bootstrap/bin/find
install -Dm755 xargs/xargs /system/bootstrap/bin/xargs
)
rm -rf findutils-4.6.0
rm -rf diffutils-2.7
tar zxf diffutils-2.7.tar.gz
( cd diffutils-2.7
CC=x86_64-pc-linux-gnu-gcc \
ac_cv_func_closedir_void=no \
ac_cv_header_stdc=yes \
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu
make cmp diff
install -Dm755 cmp /system/bootstrap/bin/cmp
install -Dm755 diff /system/bootstrap/bin/diff
)
rm -rf diffutils-2.7
rm -rf sed-4.0.6
tar zxf sed-4.0.6.tar.gz
( cd sed-4.0.6
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls \
am_cv_func_working_getline=yes
make -C lib
make -C sed
install -Dm755 sed/sed /system/bootstrap/bin/sed
)
rm -rf sed-4.0.6
rm -rf patch-2.5.9
tar zxf patch-2.5.9.tar.gz
( cd patch-2.5.9
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu
make patch
install -Dm755 patch /system/bootstrap/bin/patch
)
rm -rf patch-2.5.9
rm -rf gawk-3.1.8
tar jxf gawk-3.1.8.tar.bz2
( cd gawk-3.1.8
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls
make gawk
install -Dm755 gawk /system/bootstrap/bin/gawk
ln -sf gawk /system/bootstrap/bin/awk
)
rm -rf gawk-3.1.8
rm -rf make-3.82
tar jxf make-3.82.tar.bz2
( cd make-3.82
./configure \
--build=i686-pc-linux-gnu \
--host=x86_64-pc-linux-gnu \
--disable-nls
make make
install -Dm755 make /system/bootstrap/bin/make
)
rm -rf make-3.82
# Add /bin/sh symlink
mkdir -p /system/bin
ln -sf ../bootstrap/bin/bash /system/bin/bash
ln -sf bash /system/bin/sh
# Strip everything (saves hundreds of MB)
find /system/bootstrap/lib /system/bootstrap/lib32 -type f -name '*.a' | xargs x86_64-pc-linux-gnu-strip --strip-debug || true
find /system/bootstrap/lib /system/bootstrap/lib32 -type f -name '*.so*' | xargs x86_64-pc-linux-gnu-strip --strip-unneeded || true
find /system/bootstrap/bin /system/bootstrap/sbin /system/bootstrap/libexec -type f | xargs x86_64-pc-linux-gnu-strip --strip-all || true
# Clean up
#rm -rf /cross
rm -rf /system/bootstrap/share /system/bootstrap/var /system/bootstrap/etc
rm -f /system/bootstrap/lib/*.la /system/bootstrap/lib32/*.la /system/bootstrap/lib/libstdc++.so.*-gdb.py /system/bootstrap/lib32/libstdc++.so.*-gdb.py
# Back it up
cd /system
# Too many files to fit on single xargs command...
rm -f cross.tar
find bootstrap bin/sh bin/bash -type f -o -type l | LC_ALL=C sort | xargs tar --mtime=@0 --numeric-owner --owner=0 --group=0 -rf cross.tar
gzip -nv cross.tar
# Now you should reboot into a system with a kernel supporting the target architecture.
# Building a kernel+utilities for such a system is outside the scope of this script.
# Enter cross-chroot:
# ./bootstrap/bin/chroot . /bootstrap/bin/env -i PATH=/bootstrap/bin /bootstrap/bin/sh -l