musl-cross-make/scripts/sinner
2024-01-10 03:39:51 +08:00

362 lines
12 KiB
Bash
Executable File

#!/bin/sh
#===============================================================
# Filename : scripts/sinner
# Purpose : Builds Linux-to-Windows cross-compiler toolchains.
# Authors : Zach van Rijn <me@zv.io>
# License : MIT
# Revision : 20190531
#===============================================================
#---------------------------------------------------------------
# README
#
# overview
# --------
#
# This script builds "musl-cross-make" cross-compiler toolchains
# that are hosted on Linux and target Windows. For example, your
# MIPS router can use up-to-date versions of GCC to build code
# (C, C++, Fortran) for your Windows XP machine. The libc used
# is called 'musl': https://www.musl-libc.org/faq.html
#
# Others have tried and failed to deliver what you're able to do
# with this tiny script. Additions to this list are welcome:
#
# What does this look like? Modern GCC that does:
#
# * Linux on ARM, Motorola 68000, MIPS, OpenRISC, PowerPC,
# RISC-V, S/390, SuperH, x86-based, more?
#
# --> Windows XP to 10, and possibly older.
#
# The goal, of course, is to achieve parity with musl.cc's Linux
# offerings. This is the script to build the binaries located at
# https://more.musl.cc/YOUR-HOST-ARCHITECTURE/*-w64-mingw32.zip
#
#
# build platforms
# ---------------
#
# You need Linux to build these, and an architecture that runs a
# toolchain from musl.cc.
#
#
# requirements
# ------------
#
# Consider running this script inside of an isolated environment
# such as a container or virtual machine. While not required, we
# do not recommend running any foreign scripts or binaries in an
# important environment. You'll need the following packages:
#
# * cmake
# * curl
# * git
# * make
# * patch (GNU)
# * tar
# * xz
# * zip
#
# e.g., apk add cmake curl git make patch rsync tar xz zip
#
#
# other notes
# -----------
#
# * A prior version of this script ('prepare') relies on Linux
# 'binfmt_misc' and QEMU to emulate certain build byproducts
# and requires root privileges to install (but not use) that
# setup. This version cross-compiles the toolchains purely.
#
# * This script uses the 'mingw-cross-make' flavor maintained
# at https://git.zv.io/toolchains/mingw-cross-make to build
# MinGW toolchains. Issues should be addressed there.
#
#
# usage
# -----
#
# $ ./scripts/sinner [TRIPLE ...]
#
# $ ./scripts/sinner i686-w64-mingw32 x86_64-w64-mingw32
#---------------------------------------------------------------
# Configuration.
## Component Versions
#
# These options are self explanatory, but *must* correspond to a
# supported version within the "musl-cross-make" repository. One
# other factor to consider is that kernel headers and musl libc
# will be harvested from a "donor" toolchain; these versions do
# not necessarily correspond to what is built here (yet, TODO).
#
GCC_VER=9.1.0
BINUTILS_VER=2.32
MUSL_VER=git-a60b9e06861e56c0810bae0249b421e1758d281a
GMP_VER=6.1.2
MPC_VER=1.1.0
MPFR_VER=4.0.2
MINGW_VER=git-3e6c10aeba81c589a7b2ed1e7daee4d4d75b646e
## Directories
#
# By default, all toolchains that can be built, are built. This
# requires a significant amount of disk space. Please ensure you
# have at least 50GB of free disk space in these directories:
#
base="${HOME}/sinner_src" # base source directory
huge="${HOME}/sinner_bld" # base build directory
logs="${HOME}/sinner_log" # suite build log directory
zips="${HOME}/sinner_bin" # completed toolchains go here
## Toolchain Mirror
#
# If you have access to an x86_64 Linux machine, or one that has
# an x86_64 QEMU user-mode emulator registered in 'binfmt_misc',
# you will always be using the latest available software.
#
musl=https://more.musl.cc # more.musl.cc or mirror
## Toolchain Naming Conventions
#
# The musl.cc toolchains follow a simple naming convention: all
# cross compilers are suffixed with '-cross', native '-native'.
# If you're using a different mirror or convention, set it here.
#
csuf=-cross # cross suffix
nsuf=-native # native suffix
## Toolchain Tuples
#
# Values can be found at 'https://more.musl.cc/' where the $user
# variable corresponds to your build platform, and $host to your
# intended Linux development environment. Note that unless the
# website says otherwise, only the 'x86_64-linux-musl' toolchain
# directory is up-to-date. If you can't find what you're looking
# for you must build a MinGW-w64 suitable toolchain from source.
#
user=x86_64-linux-musl # platform that builds suite
## Build Environment
#
# This variable is extended during the toolchain download step.
#
kale="${base}/${user}${csuf}/bin";
## Repositories
#
# The build infrastructure used is called "musl-cross-make" and
# is upstream https://github.com/richfelker/musl-cross-make, but
# this version is incompatible with the current script. It's out
# of date, too, so please leave the default unless you fork it.
#
name=musl-cross-make
repo=https://git.zv.io/toolchains/${name}
brch=musl-git # branch name (no assumptions!)
sinn=mingw-cross-make
sinr=https://git.zv.io/toolchains/${sinn}
sinb=mingw
## Suite Targets
#
# Now that RISC-V patches are (unofficially) merged into musl, a
# single text file with target tuples (which comprise the suite)
# may now be used. Modify this with e.g. a pastebin link if you
# wish to use a different list (this one is self-updating).
#
list=${repo}/raw/${brch}/scripts/triples.txt
filt=tuples.txt # filename of saved tuples list
## Suite Configuration
#
# To facilitate users' needs in customizing the toolchain suite,
# a configuration file is embedded below. These settings *must*
# be supported by the repository specified above.
#
# Note: items that are prefixed/suffixed with double underscores
# are automatically populated later. Do not modify them here!
#
conf=$(cat <<'EOF'
STAT = -static --static
FLAG = -g0 -O2 -fno-align-functions -fno-align-jumps -fno-align-loops -fno-align-labels
COMMON_CONFIG += CC="$(HOST)-gcc ${STAT}" CXX="$(HOST)-g++ ${STAT}" FC="$(HOST)-gfortran -${STAT}"
COMMON_CONFIG += CFLAGS="${FLAG}" CXXFLAGS="${FLAG}" FFLAGS="${FLAG}" LDFLAGS="-s ${STAT}"
COMMON_CONFIG += --disable-nls --disable-bootstrap --build=__USER__ --host=__HOST__ --target=__TARG__
GCC_CONFIG += --enable-threads=__THREADS__
OVERRIDE = --enable-libquadmath --enable-libquadmath-support
GCC_VER = __GCC_VER__
BINUTILS_VER = __BINUTILS_VER__
MUSL_VER = __MUSL_VER__
GMP_VER = __GMP_VER__
MPC_VER = __MPC_VER__
MPFR_VER = __MPFR_VER__
MINGW_VER = __MINGW_VER__
LINUX_VER =
EOF
);
## Thread Configuration
#
# By popular demand, both Win32 and POSIX thread models will are
# supported. Edit this variable if you don't wish to build both.
#
tmod="posix" # default: "win32 posix"
#---------------------------------------------------------------
# Subroutines.
# Download preliminary toolchains.
#
get_tool ()
{
mkdir -p "${base}";
# build
if [ ! -d "${base}/${user}${csuf}" ]; then
curl ${musl}/${user}/${user}${csuf}.tgz \
| tar 2>/dev/null -C "${base}" -xzf -;
fi
}
# Clone a suitable "musl-cross-make" repository.
#
get_repo ()
{
[ -d "${base}" ] || exit 1;
[ ! -d "${base}/${sinn}" ] || return;
git clone ${sinr} "${base}/${sinn}";
}
# Overwrite any existing configuration (config.mak) template.
#
get_conf ()
{
[ -d "${base}/${sinn}" ] || exit 1;
printf > "${base}/${sinn}/config.mak" "%s\n" \
"${conf}";
}
# Fetch an up-to-date list of possible target tuples. Allow the
# user to edit this list, if the line is uncommented, before DL.
#
get_list ()
{
[ ! -f "${base}/${filt}" ] || return;
curl -o "${base}/${filt}" ${list};
sed -i "${base}/${filt}" -e '/mingw/d';
nano "${base}/${filt}";
}
# Download all necessary target toolchains.
#
get_targ ()
{
# targets (if different from build)
cat "${base}/${filt}" | grep -v "#" | while read k; do
if [ ! -d "${base}/${k}${csuf}" ]; then
curl ${musl}/${user}/${k}${csuf}.tgz \
| tar 2>/dev/null -C "${base}" -xzf -;
fi
done;
}
# Build the compiler suite. Note: the '-ik' in 'make' is used to
# ignore an error:
#
# The directory that should contain system headers does not
# exist: //mingw/include
#
# We use 'make clean' to ensure that the updated configuration
# takes full effect (relevant to thread model settings).
#
run_make ()
{
cat "${base}/${filt}" | grep -v "#" | while read k; do
for tget in ${@}; do # command-line argument list
for t in ${tmod}; do # thread model list
mkdir -p "${huge}/${k}";
mkdir -p "${logs}/${k}";
get_conf; sed -i "${base}/${sinn}/config.mak" \
-e "s@__USER__@${user}@" \
-e "s@__HOST__@${k}@" \
-e "s@__TARG__@${tget}@" \
\
-e "s@__GCC_VER__@${GCC_VER}@" \
-e "s@__BINUTILS_VER__@${BINUTILS_VER}@" \
-e "s@__MUSL_VER__@${MUSL_VER}@" \
-e "s@__GMP_VER__@${GMP_VER}@" \
-e "s@__MPC_VER__@${MPC_VER}@" \
-e "s@__MPFR_VER__@${MPFR_VER}@" \
-e "s@__MINGW_VER__@${MINGW_VER}@" \
\
-e "s@__THREADS__@${t}@";
if [ ! -d "${huge}/${k}/${tget}${csuf}-${t}" ]; then
PATH="${kale}:${base}/${k}${csuf}/bin:${base}/${tget}${csuf}/bin:${PATH}" \
\
CC="${k}-gcc" \
CXX="${k}-g++" \
RANLIB="${k}-ranlib" \
\
CC_FOR_BUILD="${user}-gcc" \
CXX_FOR_BUILD="${user}-g++" \
RANLIB_FOR_BUILD="${user}-ranlib" \
\
make -ik -C "${base}/${sinn}" -O clean install \
HOST=${k} \
TARGET=${tget} \
OUTPUT="${huge}/${k}/${tget}${csuf}-${t}" \
2>&1 | tee \
"${logs}/${k}/${tget}${csuf}-${t}.log";
fi
done; # thread model list
done; # command-line argument list
done; # source list (hosts)
}
# Pack the toolchains into tgz files. They're ready for distro.
#
run_pack ()
{
cat "${base}/${filt}" | grep -v "#" | while read k; do
for tget in ${@}; do # command-line argument list
for t in ${tmod}; do # thread model list
mkdir -p "${zips}/${k}";
if [ ! -e "${zips}/${k}/${tget}${csuf}-${t}.tgz" ]; then
(
cd "${huge}/${k}";
tar -pczf "${zips}/${k}/${tget}${csuf}-${t}.tgz" \
${tget}${csuf}-${t};
)
fi
done; # thread model list
done; # command-line argument list
done; # source list (hosts)
}
#---------------------------------------------------------------
# Driver.
get_tool; # Download initial toolchains.
get_repo; # Clone "musl-cross-make" repo.
get_conf; # Write toolchain configuration.
get_list; # Generate list of targets.
get_targ; # Fetch "donor" toolchains.
run_make ${@}; # Build specified toolchains.
run_pack ${@}; # Pack output for distribution.