#!/bin/bash
#
# Copyright (C) 2019 Kyle Schwarz
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
#
v_script="4.0.1"
v_mingww64="6git"
v_binutils="2.32git"
v_gcc="8svn"
v_gmp="6.1.2"
v_mpfr="4.0.2"
v_mpc="1.1.0"
v_isl="0.20"
show_help()
{
cat <.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
VERSION
}
error_exit()
{
local error_text="$1"
shift
if [[ -z "$error_text" ]]; then
error_text="See 'build.log' for further details."
fi
echo "mingw-w64-build: error: $error_text" >&3
exit 1
}
clean_build()
{
local build_dir="$1"
rm -fr "$build_dir"
mkdir -p "$build_dir"
cd "$build_dir" || error_exit
}
download_sources()
{
cd "$src" || error_exit
echo "downloading mingw-w64" >&3
git clone --depth 1 -b v6.x git://git.code.sf.net/p/mingw-w64/mingw-w64 mingw-w64-$v_mingww64 || error_exit
echo "downloading binutils" >&3
git clone --depth 1 -b binutils-2_32-branch --single-branch git://sourceware.org/git/binutils-gdb.git binutils-$v_binutils || error_exit
echo "downloading gcc" >&3
svn co svn://gcc.gnu.org/svn/gcc/branches/gcc-8-branch gcc-$v_gcc || error_exit
local urls=(
"https://ftp.gnu.org/gnu/gmp/gmp-$v_gmp.tar.xz"
"https://ftp.gnu.org/gnu/mpfr/mpfr-$v_mpfr.tar.xz"
"https://ftp.gnu.org/gnu/mpc/mpc-$v_mpc.tar.gz"
"http://isl.gforge.inria.fr/isl-$v_isl.tar.xz"
)
for url in "${urls[@]}"; do
local archive="${url##*/}"
echo "downloading $archive" >&3
curl -O "$url" || error_exit
echo "extracting $archive" >&3
tar -xf "$archive" || error_exit
done
cd "$src/gcc-$v_gcc" || error_exit
ln -s "../gmp-$v_gmp" "gmp"
ln -s "../mpfr-$v_mpfr" "mpfr"
ln -s "../mpc-$v_mpc" "mpc"
ln -s "../isl-$v_isl" "isl"
}
build_toolchain()
{
local host="$1-w64-mingw32"
local prefix="$wd/$host"
export PATH="$prefix/bin:$PATH"
rm -fr "$prefix"
clean_build "$bld/binutils"
echo "configuring binutils" >&3
"../../src/binutils-$v_binutils/configure" --prefix="$prefix" --disable-shared \
--enable-static --with-sysroot="$prefix" --target="$host" \
--disable-multilib --disable-nls --enable-lto --disable-werror || error_exit
echo "building binutils" >&3
make -j $cpus || error_exit
echo "installing binutils" >&3
make install || error_exit
clean_build "$bld/mingw-w64"
echo "configuring mingw-w64-headers" >&3
"../../src/mingw-w64-$v_mingww64/mingw-w64-headers/configure" --build="$build" \
--host="$host" --prefix="$prefix/$host" --enable-secure-api || error_exit
echo "installing mingw-w64-headers" >&3
make install || error_exit
cd "$prefix" || error_exit
ln -s "./$host" "./mingw" || error_exit
clean_build "$bld/gcc"
echo "configuring gcc" >&3
"../../src/gcc-$v_gcc/configure" --target="$host" --disable-shared \
--enable-static --disable-multilib --prefix="$prefix" \
--enable-languages=c,c++ --disable-nls || error_exit
echo "running 'make-gcc' for gcc" >&3
make -j $cpus all-gcc || error_exit
echo "running 'install-gcc' for gcc" >&3
make install-gcc || error_exit
clean_build "$bld/mingw-w64"
echo "configuring mingw-w64-crt" >&3
"../../src/mingw-w64-$v_mingww64/mingw-w64-crt/configure" --build="$build" --host="$host" \
--prefix="$prefix/$host" --with-sysroot="$prefix/$host"
echo "building mingw-w64-crt" >&3
make -j $cpus || error_exit
echo "installing mingw-w64-crt" >&3
make install || error_exit
cd "$bld/gcc" || error_exit
echo "building gcc" >&3
make -j $cpus || error_exit
echo "installing gcc" >&3
make install || error_exit
return 0
}
while :; do
case $1 in
-h|--help)
show_help
exit
;;
--version)
show_version
exit
;;
-?*)
echo "mingw-w64-build: error: unknown option: '$1'" >&2
exit
;;
*)
break
esac
shift
done
if [[ "$PWD" = *" "* ]]; then
echo "mingw-w64-build: error: working path contains spaces" >&2
exit 1
fi
if [[ -z "$@" ]]; then
echo "mingw-w64-build: error: missing ARCH option" >&2
echo "See 'mingw-w64-build --help' for build options." >&2
exit 1
fi
for arch in $@; do
if [[ "$arch" != "i686" ]] && [[ "$arch" != "x86_64" ]]; then
echo "mingw-w64-build: error: invalid ARCH: '$arch'" >&2
exit 1
fi
done
progs=(
"curl"
"gzip"
"bzip2"
"git"
"make"
"patch"
"g++"
"tr"
"tar"
"svn"
"flex"
"bison"
"makeinfo"
)
missing_progs=""
for prog in "${progs[@]}"; do
if ! command -v $prog >/dev/null; then
missing_progs="$prog $missing_progs"
fi
done
if [[ -n "$missing_progs" ]]; then
echo "mingw-w64-build: missing required program(s): $missing_progs" >&2
exit 1
fi
cpus=$(grep -c processor /proc/cpuinfo 2>/dev/null || sysctl -n hw.ncpu | tr -d "\n" 2>/dev/null)
build=$(curl -s "http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD" | sh)
wd="$PWD"
src="$wd/src"
bld="$wd/bld"
log="$wd/bld/build.log"
rm -fr "$log" "$src" "$bld"
mkdir "$bld" "$src"
download_sources 3>&1 1>>"$log" 2>&1
for arch in $@; do
build_toolchain "$arch" 3>&1 1>>"$log" 2>&1
done
rm -fr "$bld" "$src"
exit 0