mirror of
https://github.com/richfelker/musl-cross-make.git
synced 2025-04-19 07:24:59 +02:00
388 lines
13 KiB
Bash
Executable File
388 lines
13 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
#===============================================================
|
|
# Filename : scripts/winner
|
|
# Purpose : Builds Windows-to-Linux cross-compiler toolchains.
|
|
# Authors : Zach van Rijn <me@zv.io>
|
|
# License : MIT
|
|
# Revision : 20200303
|
|
#===============================================================
|
|
|
|
#---------------------------------------------------------------
|
|
# README
|
|
#
|
|
# overview
|
|
# --------
|
|
#
|
|
# This script builds "musl-cross-make" cross-compiler toolchains
|
|
# that are hosted on Windows and target Linux. For example, your
|
|
# Windows XP machine can use up-to-date versions of GCC to build
|
|
# code (C, C++, Fortran) for your MIPS router. 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:
|
|
#
|
|
# * https://gnutoolchains.com/download/
|
|
# * (um?)
|
|
#
|
|
# What does this look like? Modern GCC that does:
|
|
#
|
|
# * Win32 --> ARM, Motorola 68000, MIPS, OpenRISC, PowerPC,
|
|
# RISC-V, S/390, SuperH, x86-based, more?
|
|
#
|
|
# The goal, of course, is to achieve parity with musl.cc's Linux
|
|
# offerings. A link to pre-built Windows binaries is now public,
|
|
# and this is the script to reproduce them. https://win.musl.cc/
|
|
#
|
|
#
|
|
# build platforms
|
|
# ---------------
|
|
#
|
|
# In absolute theory, one can build this toolchain suite using a
|
|
# "native" toolchain from 'musl.cc' suitable for your platform,
|
|
# to build a MinGW-w64 cross-compiler (hosted on your platform,
|
|
# targeting i686- or x86_64- Windows), then use that toolchain
|
|
# to build the suite. Some may exist here: https://more.musl.cc/
|
|
#
|
|
# In practice, you just need 'i686-w64-mingw32-cross' for 32-bit
|
|
# or 'x86_64-w64-mingw32-cross' for 64-bit that runs on your own
|
|
# Linux (or Windows, with Cygwin or MSYS2) system.
|
|
#
|
|
#
|
|
# 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)
|
|
# * rsync
|
|
# * tar
|
|
# * xz
|
|
# * zip
|
|
#
|
|
# e.g., apk add cmake curl git make patch rsync tar xz zip
|
|
#
|
|
# You'll also need an internet connection (or manually do so) to
|
|
# obtain corresponding "donor" toolchains from musl.cc; what we
|
|
# are doing is pulling musl and the Linux kernel headers from an
|
|
# existing toolchain, rather than fuss with getting them to play
|
|
# nicely with the "Canadian" cross infrastructure.
|
|
#
|
|
#
|
|
# other notes
|
|
# -----------
|
|
#
|
|
# * Toolchains cannot be built with kernel headers; these are
|
|
# copied into the output directory after the initial build.
|
|
# Kernel version is that of donor toolchain.
|
|
#
|
|
# * Toolchains cannot be built with the musl library; this is
|
|
# copied into the output directory after the initial build.
|
|
# musl version is that of donor toolchain, but may be flaky.
|
|
#
|
|
# * If you do not uncomment the 'nano' line, you will build a
|
|
# large number of toolchains. This requires an exceptional
|
|
# amount of disk space and time. This is what I use it for.
|
|
#
|
|
#
|
|
# to-do
|
|
# -----
|
|
#
|
|
# * Fix underlying issue causing kernel headers and musl to be
|
|
# not built or installed correctly.
|
|
#
|
|
# * Generate Cygwin (and/or MSYS2) packages for distribution.
|
|
|
|
#---------------------------------------------------------------
|
|
# 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.3.0
|
|
BINUTILS_VER=2.34
|
|
MUSL_VER=git-0a005f499cf39822166dd4db3d2d31f0639f1b1b
|
|
GMP_VER=6.2.0
|
|
MPC_VER=1.1.0
|
|
MPFR_VER=4.1.0
|
|
LINUX_VER=5.4.50 # TODO: proper install, no rsync
|
|
|
|
## 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="/tmp/winner_src" # base source directory
|
|
huge="/tmp/winner_bld" # base build directory
|
|
logs="/tmp/winner_log" # suite build log directory
|
|
zips="/tmp/winner_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 Windows development environment. Note that unless the
|
|
# website says otherwise, only the 'i686-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=i686-linux-musl # platform that builds suite
|
|
host=i686-w64-mingw32 # platform that runs suite
|
|
|
|
## Build Environment
|
|
#
|
|
# This variable is extended during the toolchain download step.
|
|
#
|
|
kale="${base}/${host}${csuf}/bin:${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=master # branch name (no assumptions!)
|
|
|
|
## 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
|
|
|
|
ifneq ($(NATIVE),)
|
|
COMMON_CONFIG += CC="$(HOST)-gcc ${STAT}" CXX="$(HOST)-g++ ${STAT}" FC="$(HOST)-gfortran ${STAT}"
|
|
else
|
|
COMMON_CONFIG += CC="gcc ${STAT}" CXX="g++ ${STAT}" FC="gfortran ${STAT}"
|
|
endif
|
|
COMMON_CONFIG += CFLAGS="${FLAG}" CXXFLAGS="${FLAG}" FFLAGS="${FLAG}" LDFLAGS="-s ${STAT}"
|
|
COMMON_CONFIG += --disable-nls --disable-bootstrap --build=__USER__ --host=__HOST__ --target=__TARG__
|
|
|
|
GCC_VER = __GCC_VER__
|
|
BINUTILS_VER = __BINUTILS_VER__
|
|
MUSL_VER = __MUSL_VER__
|
|
GMP_VER = __GMP_VER__
|
|
MPC_VER = __MPC_VER__
|
|
MPFR_VER = __MPFR_VER__
|
|
LINUX_VER = __LINUX_VER__
|
|
EOF
|
|
);
|
|
|
|
#---------------------------------------------------------------
|
|
# Subroutines.
|
|
|
|
# Download preliminary toolchains.
|
|
#
|
|
get_tool ()
|
|
{
|
|
mkdir -p "${base}";
|
|
|
|
# host
|
|
if [ ! -d "${base}/${host}${csuf}" ]; then
|
|
curl ${musl}/${user}/${host}${csuf}.tgz \
|
|
| tar 2>/dev/null -C "${base}" -xzf -;
|
|
(
|
|
cd "${base}/${host}${csuf}/bin";
|
|
find . -maxdepth 1 -type f | while read k; do
|
|
ln -sf ${k} ${k#*-*-*-};
|
|
done;
|
|
)
|
|
fi
|
|
|
|
# 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}/${name}" ] || return;
|
|
git clone ${repo} "${base}/${name}";
|
|
}
|
|
|
|
# Overwrite any existing configuration (config.mak) template.
|
|
#
|
|
get_conf ()
|
|
{
|
|
[ -d "${base}/${name}" ] || exit 1;
|
|
printf > "${base}/${name}/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 without musl or kernel headers. Note:
|
|
# the '-ik' in the 'make' command is required to avoid issues in
|
|
# areas that have not yet been investigated but don't affect the
|
|
# correctness of the resulting toolchain.
|
|
#
|
|
run_make ()
|
|
{
|
|
mkdir -p "${huge}";
|
|
mkdir -p "${logs}";
|
|
|
|
cat "${base}/${filt}" | grep -v "#" | while read k; do
|
|
|
|
get_conf; sed -i "${base}/${name}/config.mak" \
|
|
-e "s@__USER__@${user}@" \
|
|
-e "s@__HOST__@${host}@" \
|
|
-e "s@__TARG__@${k}@" \
|
|
\
|
|
-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@__LINUX_VER__@@";
|
|
|
|
if [ ! -d "${huge}/${k}${csuf}" ]; then
|
|
PATH="${kale}:${base}/${k}${csuf}/bin:${PATH}" \
|
|
\
|
|
CC="${host}-gcc" \
|
|
CXX="${host}-g++" \
|
|
RANLIB="${host}-ranlib" \
|
|
\
|
|
CC_FOR_BUILD="${user}-gcc" \
|
|
CXX_FOR_BUILD="${user}-g++" \
|
|
RANLIB_FOR_BUILD="${user}-ranlib" \
|
|
\
|
|
CC_FOR_TARGET="${k}-gcc" \
|
|
CXX_FOR_TARGET="${k}-g++" \
|
|
RANLIB_FOR_TARGET="${k}-ranlib" \
|
|
\
|
|
make -ik -C "${base}/${name}" -O install \
|
|
TARGET=${k} OUTPUT="${huge}/${k}${csuf}" \
|
|
2>&1 | tee "${logs}/${k}${csuf}.log";
|
|
fi
|
|
|
|
done;
|
|
}
|
|
|
|
# Synchronize a donor toolchain's libraries and headers (for the
|
|
# sole purposes of musl and kernel headers) with the newly-built
|
|
# Windows-hosted toolchain.
|
|
#
|
|
run_sync ()
|
|
{
|
|
cat "${base}/${filt}" | grep -v "#" | while read k; do
|
|
sync=$(cat <<EOF
|
|
${k}${csuf}/${k}/include/
|
|
${k}${csuf}/${k}/lib/
|
|
EOF
|
|
);
|
|
for n in ${sync}; do rsync -raz --ignore-existing \
|
|
"${base}/${n}" "${huge}/${n}";
|
|
done;
|
|
done;
|
|
}
|
|
|
|
# Windows does not appreciate symbolic links. Delete them. Then
|
|
# pack the toolchains into zip files. They're ready for distro.
|
|
#
|
|
run_pack ()
|
|
{
|
|
mkdir -p "${zips}";
|
|
|
|
cat "${base}/${filt}" | grep -v "#" | while read k; do
|
|
if [ ! -e "${zips}/${k}${csuf}.zip" ]; then
|
|
(
|
|
cd "${huge}";
|
|
find ${k}${csuf} -type l -delete;
|
|
zip -rq "${zips}/${k}${csuf}.zip" ${k}${csuf};
|
|
)
|
|
fi
|
|
done
|
|
}
|
|
|
|
#---------------------------------------------------------------
|
|
# 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_sync; # Harvest/inject "donor" organs.
|
|
run_pack; # Pack output for distribution.
|
|
|