mirror of
https://github.com/richfelker/musl-cross-make.git
synced 2025-04-18 23:14:59 +02:00
362 lines
12 KiB
Bash
Executable File
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.
|
|
|