#!/bin/sh set -eu version_mes=0.22 version_mescc_tools=1.0.1 version_nyacc=0.99.3 version_linux=4.14 version_binutils=2.20.1 version_gcc=4.9.4 version_gmp=4.3.2 version_mpfr=2.4.2 version_mpc=1.0.3 version_musl=1.2.1 version_busybox=1.31.1 export MAKEFLAGS="-j${NPROC:-$(getconf _NPROCESSORS_ONLN)}" system=system dir_root="$PWD" dir_sources="$dir_root/sources" dir_install="$dir_root/$system" mkdir -p build && cd build rm -rf "mes-$version_mes" tar xf "$dir_sources/mes-$version_mes.tar.gz" ( cd "mes-$version_mes" tar xf "$dir_sources/mescc-tools-Release_$version_mescc_tools.tar.gz" tar xf "$dir_sources/nyacc-$version_nyacc.tar.gz" mv "mescc-tools-Release_$version_mescc_tools" mescc-tools mv "nyacc-$version_nyacc" nyacc cp -a mescc-tools mescc-tools-target make -C mescc-tools M1 hex2 blood-elf COMMIT= export PATH="$PWD/mescc-tools/bin:$PATH" # First, we build a native mes, "mes-gcc". # This allows us to cross-build everything on systems that mes doesn't support. gcc -O2 -std=gnu99 -w -lrt -o mes-gcc -DMES_VERSION='""' -DSYSTEM_LIBC=1 -Iinclude \ lib/mes/eputs.c \ lib/mes/fdgetc.c \ lib/mes/fdputc.c \ lib/mes/fdputs.c \ lib/mes/fdungetc.c \ lib/mes/itoa.c \ lib/mes/mes_open.c \ lib/mes/ntoab.c \ src/gc.c \ src/hash.c \ src/lib.c \ src/math.c \ src/mes.c \ src/module.c \ src/posix.c \ src/reader.c \ src/string.c \ src/struct.c \ src/vector.c # This version of mes messes doesn't have a proper getopt... # TODO: Fix this (somehow) and make the patch unnecessary. sed -i -e 's/ -nostdlib/ --nostdlib/' \ -e 's/ -lc/ -l c/' \ build-aux/bootstrap.sh.in # Use this to build mes and its libc for the target CC=true guile_site_dir="$PWD/nyacc/module" sh configure.sh --host=x86-linux-mes CC="$PWD/scripts/mescc" MES="$PWD/mes-gcc" sh bootstrap.sh # Install mes install -Dm755 bin/mes "$dir_install/mes/bin/mes" # Build tools with mes to obtain reproducible outputs make -C mescc-tools-target M1 hex2 blood-elf COMMIT= \ CC="$PWD/scripts/mescc" MES="$PWD/mes-gcc" MES_PREFIX="../" \ GUILE_LOAD_PATH="../module" CFLAGS='-L ../lib -L ../mescc-lib -l c+tcc' install -Dm755 mescc-tools-target/bin/M1 "$dir_install/mes/bin/M1" install -Dm755 mescc-tools-target/bin/hex2 "$dir_install/mes/bin/hex2" install -Dm755 mescc-tools-target/bin/blood-elf "$dir_install/mes/bin/blood-elf" ) rm -rf "linux-$version_linux" tar xf "$dir_sources/linux-$version_linux.tar.gz" ( cd "linux-$version_linux" make mrproper make ARCH=x86 INSTALL_HDR_PATH="$dir_install/sources/linux-headers" headers_install find "$dir_install/sources/linux-headers" -type f ! -name "*.h" -exec rm {} + ) # Build static busybox with musl rm -rf "busybox-$version_busybox" tar xf "$dir_sources/busybox-$version_busybox.tar.bz2" ( cd "busybox-$version_busybox" tar xf "$dir_sources/binutils-${version_binutils}a.tar.bz2" mv "binutils-$version_binutils" binutils tar xf "$dir_sources/gcc-$version_gcc.tar.bz2" mv "gcc-$version_gcc" gcc tar xf "$dir_sources/gmp-$version_gmp.tar.bz2" mv "gmp-$version_gmp" gcc/gmp tar xf "$dir_sources/mpfr-$version_mpfr.tar.bz2" mv "mpfr-$version_mpfr" gcc/mpfr tar xf "$dir_sources/mpc-$version_mpc.tar.gz" mv "mpc-$version_mpc" gcc/mpc tar xf "$dir_sources/musl-$version_musl.tar.gz" mv "musl-$version_musl" musl prefix="$PWD/prefix" export PATH="$prefix/bin:$PATH" # Fix requirement for mktemp, so it works with coreutils-5.0 if ! command -v mktemp 2> /dev/null; then sed -i -e 's@$(mktemp tmp.XXXXXXXXXX)@/tmp/tmp.trylink@' scripts/trylink fi # Building a specific version of binutils+GCC, to make the results reproducible... # GCC-4.6.4's results aren't reproducible across machines for some reason, # so this bootstrap uses GCC-4.9.4. This increases the build time a little. ( cd binutils CFLAGS='-O2 -w' ./configure \ --target=i686-bootstrap-linux-gnu \ --prefix="$prefix" \ --with-sysroot="$prefix" \ --disable-nls \ --disable-werror make make install ) ( cd gcc mkdir build && cd build # Build breaks without a build directory # Using --with-local-prefix=/ puts /include in the search path before # /lib/gcc/.../include-fixed, avoiding some issues. CFLAGS='-O2 -w' CXXFLAGS='-O2 -w' MAKEINFO=true ../configure \ --target=i686-bootstrap-linux-gnu \ --prefix="$prefix" \ --with-sysroot="$prefix" \ --with-local-prefix=/ \ --with-host-libstdcxx=-lsupc++ \ --with-newlib \ --without-headers \ --disable-shared \ --disable-threads \ --disable-nls \ --enable-languages=c make all-gcc all-target-libgcc make install-gcc install-target-libgcc ) # Musl provides a very small libc, that can be linked statically. # It might be worthwhile to switch to uClibc in the future, as that's # what's usually used for busybox. Might yield "cleaner" results. cp -a "$dir_install/sources/linux-headers" prefix ( cd musl ./configure \ --host=i686-bootstrap-linux-gnu \ --prefix="$PWD/../prefix" \ --disable-shared make make install ) cp "$dir_root/busybox-config" .config make CROSS_COMPILE=i686-bootstrap-linux-gnu- CONFIG_STATIC=y busybox install -Dm755 busybox "$dir_install/bin/busybox" install -Dm755 busybox_unstripped "$dir_install/bin/busybox_unstripped" ) cd "$dir_install" # Verify the built binaries sha1sum -c "$dir_root/binaries.sha1" # Pack it up find bin mes sources \( -type f -o -type l \) ! -path bin/busybox_unstripped | LC_ALL=C sort | xargs tar --mtime=@0 --numeric-owner --owner=0 --group=0 -cf binaries.tar gzip -nv binaries.tar # Clean up cd "$dir_root" rm -rf build