490 lines
13 KiB
Bash
Executable file
490 lines
13 KiB
Bash
Executable file
#!/bin/bash -e
|
|
|
|
|
|
#
|
|
# Kangaroo Punch Toolchains
|
|
# Copyright 2023-2024 Scott Duensing <scott@kangaroopunch.com>
|
|
#
|
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
# of this software and associated documentation files (the “Software”), to
|
|
# deal in the Software without restriction, including without limitation the
|
|
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
|
# sell copies of the Software, and to permit persons to whom the Software is
|
|
# furnished to do so, subject to the following conditions:
|
|
#
|
|
# The above copyright notice and this permission notice shall be included in
|
|
# all copies or substantial portions of the Software.
|
|
#
|
|
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
|
# IN THE SOFTWARE.
|
|
#
|
|
|
|
|
|
TC_G_SCRIPT_PATH="${BASH_SOURCE}"
|
|
while [ -L "${TC_G_SCRIPT_PATH}" ]; do
|
|
TC_G_SCRIPT_DIR="$(cd -P "$(dirname "${TC_G_SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"
|
|
TC_G_SCRIPT_PATH="$(readlink "${TC_G_SCRIPT_PATH}")"
|
|
[[ ${TC_G_SCRIPT_PATH} != /* ]] && TC_G_SCRIPT_PATH="${TC_G_SCRIPT_DIR}/${TC_G_SCRIPT_PATH}"
|
|
done
|
|
TC_G_SCRIPT_PATH="$(readlink -f "${TC_G_SCRIPT_PATH}")"
|
|
TC_G_SCRIPT_DIR="$(cd -P "$(dirname -- "${TC_G_SCRIPT_PATH}")" >/dev/null 2>&1 && pwd)"
|
|
TC_G_SCRIPT=$(basename ${TC_G_SCRIPT_PATH})
|
|
|
|
|
|
TC_G_PIURL=https://github.com/tttapa/docker-arm-cross-toolchain/releases/latest/download/x-tools-
|
|
TC_G_PI64=https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2023-12-11/2023-12-11-raspios-bookworm-arm64-lite.img.xz
|
|
TC_G_PI32=https://downloads.raspberrypi.com/raspios_lite_armhf/images/raspios_lite_armhf-2023-12-11/2023-12-11-raspios-bookworm-armhf-lite.img.xz
|
|
|
|
|
|
function buildMacOSXToolchain() {
|
|
local SDK=$1
|
|
local XCODE=$2
|
|
local PLATFORM=$3
|
|
local CLANG=
|
|
local RTPATH=
|
|
local CROSSTOOLS="${TC_G_SCRIPT_DIR}/x-tools/${PLATFORM}"
|
|
|
|
mkdir -p work
|
|
|
|
if [[ ! -d work/osxcross ]]; then
|
|
git clone https://github.com/tpoechtrager/osxcross.git work/osxcross
|
|
sudo work/osxcross/tools/get_dependencies.sh
|
|
fi
|
|
|
|
if [[ ! -f x-tools/${PLATFORM}/toolchain.cmake ]]; then
|
|
pushd work/osxcross
|
|
# Have we built Apple's clang?
|
|
if [[ ! -d "${TC_G_SCRIPT_DIR}/clang" ]]; then
|
|
UNATTENDED=1 INSTALLPREFIX=${TC_G_SCRIPT_DIR}/clang ./build_apple_clang.sh
|
|
pushd build/clang*/build_stage2
|
|
make install
|
|
popd
|
|
fi
|
|
# Use our fresh new clang.
|
|
source <("${CROSSTOOLS}/bin/osxcross-conf" 2>/dev/null)
|
|
export PATH="${TC_G_SCRIPT_DIR}/clang/bin:${CROSSTOOLS}/bin:${PATH}"
|
|
export CC="${TC_G_SCRIPT_DIR}/clang/bin/clang"
|
|
export CXX="${TC_G_SCRIPT_DIR}/clang/bin/clang++"
|
|
# Do we have an existing SDK tarball?
|
|
if [[ ! -f "${TC_G_SCRIPT_DIR}/${SDK}" ]]; then
|
|
# Nope. Build tarball and keep for later.
|
|
./tools/gen_sdk_package_pbzx.sh "${TC_G_SCRIPT_DIR}/${XCODE}"
|
|
mv -f MacOSX* "${TC_G_SCRIPT_DIR}/."
|
|
fi
|
|
# Put tarball in place.
|
|
cp -f "${TC_G_SCRIPT_DIR}/${SDK}" tarballs/.
|
|
# Build SDK.
|
|
UNATTENDED=1 TARGET_DIR="${CROSSTOOLS}" ./build.sh
|
|
# Fix fubar in osxcross.
|
|
[[ -d target ]] && rm -rf target
|
|
ln -sf "${CROSSTOOLS}" target
|
|
:<<NO_GCC
|
|
# Build GCC
|
|
# Fix another fubar in osxcross.
|
|
if [[ ! -f build_gcc-fixed.sh ]]; then
|
|
sed '/^pushd gcc.*/a \.\/contrib\/download_prerequisites' build_gcc.sh > build_gcc-fixed.sh
|
|
chmod +x build_gcc-fixed.sh
|
|
fi
|
|
TARGET_DIR="${CROSSTOOLS}" ./build_gcc-fixed.sh
|
|
NO_GCC
|
|
# Build compiler runtime.
|
|
#***TODO*** This fails to find <optional> for x86.
|
|
RTPATH="${TC_G_SCRIPT_DIR}/clang/lib/clang"
|
|
CLANG=$(ls -1 "${RTPATH}" | grep -F . | sort | tail -n1)
|
|
if [[ "${CLANG}" == "" ]]; then
|
|
CLANG=$(ls -1 "${RTPATH}" | sort | tail -n1)
|
|
fi
|
|
RTPATH="${RTPATH}/${CLANG}/lib/darwin"
|
|
if [[ -d "${RTPATH}" ]]; then
|
|
rm -rf "${RTPATH}"
|
|
fi
|
|
CXX_FLAGS="-std=c++17" ENABLE_COMPILER_RT_INSTALL=1 ./build_compiler_rt.sh
|
|
if [[ -d "${RTPATH}" ]]; then
|
|
mv -f "${RTPATH}" "${CROSSTOOLS}/."
|
|
echo "RTPATH=\"${RTPATH}\"" > ${CROSSTOOLS}/rtpath.inc
|
|
fi
|
|
# Tidy up for next build.
|
|
./cleanup.sh
|
|
popd
|
|
fi
|
|
}
|
|
|
|
|
|
function build_pi_sysroot() {
|
|
local BITS=$1
|
|
local OS=
|
|
local IMAGE=
|
|
local START=
|
|
local SYSROOT=../x-tools/sysroot-pi${BITS}
|
|
|
|
mkdir -p work
|
|
pushd work
|
|
if [[ ! -f sysroot-relativelinks.py ]]; then
|
|
wget https://raw.githubusercontent.com/riscv/riscv-poky/master/scripts/sysroot-relativelinks.py
|
|
fi
|
|
if [[ "${BITS}" == "64" ]]; then
|
|
OS=${TC_G_PI64}
|
|
else
|
|
OS=${TC_G_PI32}
|
|
fi
|
|
IMAGE=$(basename ${OS})
|
|
if [[ ! -f $(basename ${OS} .xz) ]]; then
|
|
wget ${OS}
|
|
unxz ${IMAGE}
|
|
fi
|
|
IMAGE=$(basename ${IMAGE} .xz)
|
|
START=$(fdisk -l ${IMAGE} | grep Linux | awk '{ print $2 }')
|
|
START=$(( 512 * START ))
|
|
mkdir -p ${SYSROOT}
|
|
mkdir -p mnt
|
|
sudo mount -t ext4 -o loop,offset=${START} ${IMAGE} mnt
|
|
rsync -avz mnt/* ${SYSROOT} || true
|
|
#rsync -avz mnt/lib ${SYSROOT}
|
|
#rsync -avz mnt/usr/include ${SYSROOT}/usr
|
|
#rsync -avz mnt/usr/lib ${SYSROOT}/usr
|
|
sudo umount mnt
|
|
python3 ./sysroot-relativelinks.py ${SYSROOT}
|
|
if [[ "${BITS}" == "64" ]]; then
|
|
cp -f $(which qemu-aarch64-static) ${SYSROOT}/usr/bin/.
|
|
else
|
|
cp -f $(which qemu-arm-static) ${SYSROOT}/usr/bin/.
|
|
fi
|
|
popd
|
|
}
|
|
|
|
|
|
function install_x86_64_linux() {
|
|
# Required tools for Linux x86_64. These should always be installed.
|
|
sudo apt-get install -y \
|
|
autoconf \
|
|
binutils \
|
|
bison \
|
|
build-essential \
|
|
clang \
|
|
cmake \
|
|
cmake-curses-gui \
|
|
curl \
|
|
flex \
|
|
git \
|
|
git-lfs \
|
|
liblzma-dev \
|
|
libtool \
|
|
nasm \
|
|
texinfo \
|
|
unzip \
|
|
zlib1g-dev
|
|
}
|
|
|
|
|
|
function install_x86_linux() {
|
|
# x86 Linux support.
|
|
sudo dpkg --add-architecture i386
|
|
sudo apt-get install -y \
|
|
gcc-i686-linux-gnu \
|
|
g++-i686-linux-gnu
|
|
}
|
|
|
|
|
|
function install_x86_64_windows() {
|
|
# x86 and x86_64 Windows.
|
|
sudo apt-get install -y mingw-w64
|
|
}
|
|
|
|
|
|
function install_x86_windows() {
|
|
# x86 Windows.
|
|
install_x86_64_windows
|
|
}
|
|
|
|
|
|
function install_aarch64_pi() {
|
|
# Raspberry Pi, aarch64.
|
|
# wget -O- ${TC_G_PIURL}aarch64-rpi3-linux-gnu.tar.xz | tar xJ
|
|
build_pi_sysroot 64
|
|
}
|
|
|
|
|
|
function install_armv6_pi() {
|
|
# Raspberry Pi, armv6.
|
|
wget -O- ${TC_G_PIURL}armv6-rpi-linux-gnueabihf.tar.xz | tar xJ
|
|
build_pi_sysroot 32
|
|
}
|
|
|
|
|
|
function install_armv8_pi() {
|
|
# Raspberry Pi, armv8.
|
|
wget -O- ${TC_G_PIURL}armv8-rpi3-linux-gnueabihf.tar.xz | tar xJ
|
|
build_pi_sysroot 32
|
|
}
|
|
|
|
|
|
|
|
function install_x86_64_macos() {
|
|
# MacOS x86_64.
|
|
#***TODO*** https://stackoverflow.com/questions/67712376/after-updating-gcc-clang-cant-find-libstdc-anymore
|
|
buildMacOSXToolchain MacOSX10.13.sdk.tar.xz Xcode_9.4.1.xip x86_64-macos-apple
|
|
}
|
|
|
|
|
|
function install_x86_macos() {
|
|
# MacOS x86.
|
|
install_x86_64_macos
|
|
}
|
|
|
|
|
|
function install_aarch64_macos() {
|
|
# MacOS aarch64.
|
|
#***TODO*** https://stackoverflow.com/questions/67712376/after-updating-gcc-clang-cant-find-libstdc-anymore
|
|
buildMacOSXToolchain MacOSX13.3.sdk.tar.xz Xcode_14.3.1.xip aarch64-macos-apple
|
|
}
|
|
|
|
|
|
function install_x86_dos() {
|
|
# DJGPP for DOS.
|
|
export DJGPP_PREFIX=$(pwd)/x-tools/djgpp
|
|
|
|
mkdir -p work
|
|
|
|
if [[ ! -d work/build-djgpp ]]; then
|
|
git clone https://github.com/andrewwutw/build-djgpp.git work/build-djgpp
|
|
fi
|
|
|
|
if [[ ! -f x-tools/djgpp/setenv ]]; then
|
|
pushd work/build-djgpp
|
|
./build-djgpp.sh 12.2.0
|
|
popd
|
|
fi
|
|
}
|
|
|
|
|
|
function use_toolchain() {
|
|
local ARCH=$1
|
|
local PLAT=$2
|
|
|
|
case "${PLAT}" in
|
|
|
|
dos)
|
|
case "${ARCH}" in
|
|
x86)
|
|
TRIPLE="i586-pc-msdosdjgpp"
|
|
;;
|
|
esac
|
|
echo "source ${TC_G_SCRIPT_DIR}/x-tools/djgpp/setenv"
|
|
#echo "export PATH=\"${TC_G_SCRIPT_DIR}/x-tools/djgpp/i586-pc-msdosdjgpp/bin:${TC_G_SCRIPT_DIR}/x-tools/djgpp/bin:${TC_G_SCRIPT_DIR}/x-tools/djgpp/libexec/gcc/i586-pc-msdosdjgpp/12.2.0:${PATH}\""
|
|
#echo "export GCC_EXE_PREFIX=\"${TC_G_SCRIPT_DIR}/x-tools/djgpp/lib/gcc\""
|
|
#echo "export DJDIR=\"${TC_G_SCRIPT_DIR}/x-tools/djgpp/i586-pc-msdosdjgpp\""
|
|
CROSS_OS="dos"
|
|
CC="gcc"
|
|
CXX="g++"
|
|
RANLIB="ranlib"
|
|
SUFFIX=".exe"
|
|
;;
|
|
|
|
linux)
|
|
case "${ARCH}" in
|
|
x86)
|
|
TRIPLE="i686-linux-gnu"
|
|
;;
|
|
x86_64)
|
|
TRIPLE="x86_64-linux-gnu"
|
|
;;
|
|
esac
|
|
CROSS_OS="linux"
|
|
CC="${TRIPLE}-gcc"
|
|
CXX="${TRIPLE}-g++"
|
|
RANLIB="${TRIPLE}-ranlib"
|
|
;;
|
|
|
|
macos)
|
|
case "${ARCH}" in
|
|
aarch64)
|
|
TRIPLE="aarch64-apple-darwin22.4"
|
|
OSXCROSS_LOCATION=${TC_G_SCRIPT_DIR}/x-tools/aarch64-macos-apple
|
|
;;
|
|
x86)
|
|
TRIPLE="i386-apple-darwin17"
|
|
OSXCROSS_LOCATION=${TC_G_SCRIPT_DIR}/x-tools/x86_64-macos-apple
|
|
;;
|
|
x86_64)
|
|
TRIPLE="x86_64-apple-darwin17"
|
|
OSXCROSS_LOCATION=${TC_G_SCRIPT_DIR}/x-tools/x86_64-macos-apple
|
|
;;
|
|
esac
|
|
CROSS_OS="darwin"
|
|
CC="${OSXCROSS_LOCATION}/bin/${TRIPLE}-clang"
|
|
CXX="${OSXCROSS_LOCATION}/bin/${TRIPLE}-clang++"
|
|
RANLIB="${OSXCROSS_LOCATION}/bin/${TRIPLE}-ranlib"
|
|
AR="${OSXCROSS_LOCATION}/bin/${TRIPLE}-ar"
|
|
"${OSXCROSS_LOCATION}/bin/osxcross-conf" 2>/dev/null
|
|
echo "export AR=\"${AR}\""
|
|
echo "export OSXCROSS_LOCATION=\"${OSXCROSS_LOCATION}\""
|
|
echo "export LDFLAGS=\"-fuse-ld=${OSXCROSS_LOCATION}/bin/${TRIPLE}-ld\""
|
|
echo "export PATH=\"${OSXCROSS_LOCATION}/bin:${PATH}\""
|
|
echo "export OSXCROSS_PKG_CONFIG_USE_NATIVE_VARIABLES=1"
|
|
;;
|
|
|
|
pi)
|
|
case "${ARCH}" in
|
|
aarch64)
|
|
TRIPLE="aarch64-rpi3-linux-gnu"
|
|
echo "export SYSROOT=${TC_G_SCRIPT_DIR}/x-tools/sysroot-pi64"
|
|
;;
|
|
armv6)
|
|
TRIPLE="armv6-rpi-linux-gnueabihf"
|
|
echo "export SYSROOT=${TC_G_SCRIPT_DIR}/x-tools/sysroot-pi64"
|
|
;;
|
|
armv8)
|
|
TRIPLE="armv8-rpi3-linux-gnueabihf"
|
|
echo "export SYSROOT=${TC_G_SCRIPT_DIR}/x-tools/sysroot-pi64"
|
|
;;
|
|
esac
|
|
CROSS_OS="linux"
|
|
CC="${TRIPLE}-gcc"
|
|
CXX="${TRIPLE}-g++"
|
|
RANLIB="${TRIPLE}-ranlib"
|
|
;;
|
|
|
|
windows)
|
|
case "${ARCH}" in
|
|
x86)
|
|
TRIPLE="i686-w64-mingw32"
|
|
;;
|
|
x86_64)
|
|
TRIPLE="x86_64-w64-mingw32"
|
|
;;
|
|
esac
|
|
CC="${TRIPLE}-gcc-posix"
|
|
CXX="${TRIPLE}-g++-posix"
|
|
RANLIB="${TRIPLE}-ranlib"
|
|
SUFFIX=".exe"
|
|
CROSS_OS="mingw32"
|
|
;;
|
|
|
|
esac
|
|
|
|
echo "export TOOLCHAIN_FILE=\"${TC_G_SCRIPT_DIR}/cmake/${TRIPLE}.cmake\""
|
|
echo "export CC=\"${CC}\""
|
|
echo "export CXX=\"${CXX}\""
|
|
echo "export RANLIB=\"${RANLIB}\""
|
|
echo "export SUFFIX=\"${SUFFIX}\""
|
|
echo "export CROSS_OS=\"${CROSS_OS}\""
|
|
echo "export TRIPLE=\"${TRIPLE}\""
|
|
}
|
|
|
|
|
|
MODE=$1
|
|
ARCH=$2
|
|
PLAT=$3
|
|
|
|
HELP=1
|
|
|
|
COLS=2
|
|
ROWS=11
|
|
row=0
|
|
declare -A PLATFORMS=()
|
|
# List of ARCHs List of PLATs
|
|
PLATFORMS[0]="x86_64"; PLATFORMS[1]="linux"
|
|
PLATFORMS[2]="x86"; PLATFORMS[3]="linux"
|
|
PLATFORMS[4]="x86_64"; PLATFORMS[5]="windows"
|
|
PLATFORMS[6]="x86"; PLATFORMS[7]="windows"
|
|
PLATFORMS[8]="aarch64"; PLATFORMS[9]="pi"
|
|
PLATFORMS[10]="armv6"; PLATFORMS[11]="pi"
|
|
PLATFORMS[12]="armv8"; PLATFORMS[13]="pi"
|
|
PLATFORMS[14]="x86_64"; PLATFORMS[15]="macos"
|
|
PLATFORMS[16]="x86"; PLATFORMS[17]="macos"
|
|
PLATFORMS[18]="aarch64"; PLATFORMS[19]="macos"
|
|
PLATFORMS[20]="x86"; PLATFORMS[21]="dos"
|
|
|
|
if [[ "${MODE}" == "install" ]]; then
|
|
# We need some more packages for Pi work.
|
|
if [[ "${PLAT}" == "pi" ]]; then
|
|
sudo apt-get -y install qemu-user-static
|
|
fi
|
|
|
|
# Install all toolchains.
|
|
if [[ "${ARCH}" == "all" && "${PLAT}" == "all" ]]; then
|
|
HELP=0
|
|
for (( row=0; row<ROWS; row++ )); do
|
|
set -x
|
|
install_${PLATFORMS[$((${COLS}*${row}))]}_${PLATFORMS[$((${COLS}*${row}+1))]}
|
|
set +x
|
|
done
|
|
fi
|
|
|
|
# Install all toolchains for a specific platform.
|
|
if [[ "${ARCH}" == "all" && "${PLAT}" != "all" ]]; then
|
|
HELP=0
|
|
for (( row=0; row<ROWS; row++ )); do
|
|
if [[ "${PLAT}" == "${PLATFORMS[$((${COLS}*${row}+1))]}" ]]; then
|
|
set -x
|
|
install_${PLATFORMS[$((${COLS}*${row}))]}_${PLAT}
|
|
set +x
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Install a single toolchain.
|
|
if [[ "${ARCH}" != "all" && "${PLAT}" != "all" ]]; then
|
|
for (( row=0; row<ROWS; row++ )); do
|
|
if [[ "${ARCH}" == "${PLATFORMS[$((${COLS}*${row}))]}" && "${PLAT}" == "${PLATFORMS[$((${COLS}*${row}+1))]}" ]]; then
|
|
HELP=0
|
|
set -x
|
|
install_${ARCH}_${PLAT}
|
|
set +x
|
|
fi
|
|
done
|
|
fi
|
|
fi
|
|
|
|
if [[ "${MODE}" == "use" ]]; then
|
|
for (( row=0; row<ROWS; row++ )); do
|
|
if [[ "${ARCH}" == "${PLATFORMS[$((${COLS}*${row}))]}" && "${PLAT}" == "${PLATFORMS[$((${COLS}*${row}+1))]}" ]]; then
|
|
HELP=0
|
|
use_toolchain ${ARCH} ${PLAT}
|
|
fi
|
|
done
|
|
fi
|
|
|
|
# Do they need help?
|
|
if [[ ${HELP} -eq 1 ]]; then
|
|
cat <<-HELP
|
|
|
|
Kangaroo Punch Toolchain Installer
|
|
http://skunkworks.kangaroopunch.com
|
|
|
|
Usage: ${TC_G_SCRIPT} [install|use] [architecture] [platform]
|
|
|
|
Where [architecture] and [platform] are one of:
|
|
|
|
HELP
|
|
for (( row=0; row<ROWS; row++ )); do
|
|
printf ' %-10s %s\n' "${PLATFORMS[$((${COLS}*${row}))]}" "${PLATFORMS[$((${COLS}*${row}+1))]}"
|
|
done
|
|
cat <<-HELP
|
|
|
|
For "install" mode:
|
|
|
|
If [architecture] and [platform] are both "all",
|
|
everything will be installed.
|
|
|
|
if [architecture] is "all", then all available
|
|
architectures for the specified [platform] will
|
|
be installed.
|
|
|
|
NOTE: You should always install x86_64 linux
|
|
before attempting to install other
|
|
toolchains.
|
|
|
|
For "use" mode:
|
|
|
|
Souce the output of this script to set the environment
|
|
to use the appropriate toolchain for [architecture] and
|
|
[platform].
|
|
|
|
HELP
|
|
fi
|