2025-10-02 17:55:20 +02:00

424 lines
10 KiB
Bash
Executable File

#!/usr/bin/env bash
set -e
NPROC=8
fetch_cmd=$( (type wget > /dev/null 2>&1 && echo "wget") || echo "curl -O" )
usage()
{
echo "USAGE: $0 <target>"
echo "where target is one of:"
echo " ios: build for iOS arm64"
echo " ios_simulator: build for iPhone Simulator for arm64/x86_64 (fat binary)"
echo " macos: build for macOS for arm64/x86_64 (fat binary)"
echo " macos_arm64: build for macOS arm64"
echo " macos_x86_64: build for macOS x86_64"
echo " android: build for Android arm64"
echo " android_x86_64: build for Android x86_64"
echo " host: build for this host"
echo " host_noasm: build for this host without asm optimizations (e.g. needed for macOS)"
echo " aarch64: build for Linux aarch64"
exit 1
}
get_gmp()
{
GMP_NAME=gmp-6.2.1
GMP_ARCHIVE=${GMP_NAME}.tar.xz
GMP_URL=https://ftp.gnu.org/gnu/gmp/${GMP_ARCHIVE}
if [ ! -f ${GMP_ARCHIVE} ]; then
$fetch_cmd ${GMP_URL}
fi
if [ ! -d gmp ]; then
tar -xvf ${GMP_ARCHIVE}
mv ${GMP_NAME} gmp
fi
}
build_aarch64()
{
PACKAGE_DIR="$GMP_DIR/package_aarch64"
BUILD_DIR=build_aarch64
if [ -d "$PACKAGE_DIR" ]; then
echo "aarch64 package is built already. See $PACKAGE_DIR"
return 1
fi
export TARGET=aarch64-linux-gnu
echo $TARGET
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
make -j${NPROC} &&
make install
cd ..
}
build_host()
{
PACKAGE_DIR="$GMP_DIR/package"
BUILD_DIR=build
if [ -d "$PACKAGE_DIR" ]; then
echo "Host package is built already. See $PACKAGE_DIR"
return 1
fi
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
# The following line is a workaround for the Windows build due to an existing incompatibility with current compiler
# when building GMP.
CFLAGS="-O2 -std=gnu17" CXXFLAGS="-O2 -std=gnu++17" \
../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
make -j${NPROC} &&
make install
cd ..
}
build_host_noasm()
{
PACKAGE_DIR="$GMP_DIR/package"
BUILD_DIR=build
if [ -d "$PACKAGE_DIR" ]; then
echo "Host package is built already. See $PACKAGE_DIR"
return 1
fi
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
make -j${NPROC} &&
make install
cd ..
}
build_android()
{
PACKAGE_DIR="$GMP_DIR/package_android_arm64"
BUILD_DIR=build_android_arm64
if [ -d "$PACKAGE_DIR" ]; then
echo "Android package is built already. See $PACKAGE_DIR"
return 1
fi
if [ -z "$ANDROID_NDK" ]; then
echo "ERROR: ANDROID_NDK environment variable is not set."
echo " It must be an absolute path to the root directory of Android NDK."
echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
return 1
fi
if [ "$(uname)" == "Darwin" ]; then
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
else
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
fi
export TARGET=aarch64-linux-android
export API=21
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
echo "$TOOLCHAIN"
echo "$TARGET"
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
make -j${NPROC} &&
make install
cd ..
}
build_android_x86_64()
{
PACKAGE_DIR="$GMP_DIR/package_android_x86_64"
BUILD_DIR=build_android_x86_64
if [ -d "$PACKAGE_DIR" ]; then
echo "Android package is built already. See $PACKAGE_DIR"
return 1
fi
if [ -z "$ANDROID_NDK" ]; then
echo "ERROR: ANDROID_NDK environment variable is not set."
echo " It must be an absolute path to the root directory of Android NDK."
echo " For instance /home/test/Android/Sdk/ndk/23.1.7779620"
return 1
fi
if [ "$(uname)" == "Darwin" ]; then
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/darwin-x86_64
else
export TOOLCHAIN=$ANDROID_NDK/toolchains/llvm/prebuilt/linux-x86_64
fi
export TARGET=x86_64-linux-android
export API=21
export AR=$TOOLCHAIN/bin/llvm-ar
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export AS=$CC
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
export LD=$TOOLCHAIN/bin/ld
export RANLIB=$TOOLCHAIN/bin/llvm-ranlib
export STRIP=$TOOLCHAIN/bin/llvm-strip
echo "$TOOLCHAIN"
echo $TARGET
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft &&
make -j${NPROC} &&
make install
cd ..
}
build_ios()
{
PACKAGE_DIR="$GMP_DIR/package_ios_arm64"
BUILD_DIR=build_ios_arm64
if [ -d "$PACKAGE_DIR" ]; then
echo "iOS package is built already. See $PACKAGE_DIR"
return 1
fi
export SDK="iphoneos"
export TARGET=arm64-apple-darwin
export MIN_IOS_VERSION=8.0
export ARCH_FLAGS="-arch arm64 -arch arm64e"
export OPT_FLAGS="-O3 -g3 -fembed-bitcode"
HOST_FLAGS="${ARCH_FLAGS} -miphoneos-version-min=${MIN_IOS_VERSION} -isysroot $(xcrun --sdk ${SDK} --show-sdk-path)"
CC=$(xcrun --find --sdk "${SDK}" clang)
export CC
CXX=$(xcrun --find --sdk "${SDK}" clang++)
export CXX
CPP=$(xcrun --find --sdk "${SDK}" cpp)
export CPP
export CFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
export CXXFLAGS="${HOST_FLAGS} ${OPT_FLAGS}"
export LDFLAGS="${HOST_FLAGS}"
echo $TARGET
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --host $TARGET --prefix="$PACKAGE_DIR" --with-pic --disable-fft --disable-assembly &&
make -j${NPROC} &&
make install
cd ..
}
build_ios_simulator()
{
libs=()
for ARCH in "arm64" "x86_64"; do
case "$ARCH" in
"arm64" )
echo "Building for iPhone Simulator arm64"
ARCH_FLAGS="-arch arm64 -arch arm64e"
;;
"x86_64" )
echo "Building for iPhone Simulator x86_64"
ARCH_FLAGS="-arch x86_64"
;;
* )
echo "Incorrect iPhone Simulator arch"
exit 1
esac
BUILD_DIR="build_iphone_simulator_${ARCH}"
PACKAGE_DIR="$GMP_DIR/package_iphone_simulator_${ARCH}"
libs+=("${PACKAGE_DIR}/lib/libgmp.a")
if [ -d "$PACKAGE_DIR" ]; then
echo "iPhone Simulator ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
continue
fi
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --prefix="${PACKAGE_DIR}" \
CC="$(xcrun --sdk iphonesimulator --find clang)" \
CFLAGS="-O3 -isysroot $(xcrun --sdk iphonesimulator --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mios-simulator-version-min=8.0" \
LDFLAGS="" \
--host ${ARCH}-apple-darwin --disable-assembly --enable-static --disable-shared --with-pic &&
make -j${NPROC} &&
make install
cd ..
done
mkdir -p "${GMP_DIR}/package_iphone_simulator/lib"
lipo "${libs[@]}" -create -output "${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
echo "Wrote universal fat library for iPhone Simulator arm64/x86_64 to ${GMP_DIR}/package_iphone_simulator/lib/libgmp.a"
}
build_macos_arch()
{
ARCH="$1"
case "$ARCH" in
"arm64" )
ARCH_FLAGS="-arch arm64 -arch arm64e"
;;
"x86_64" )
ARCH_FLAGS="-arch x86_64"
;;
* )
echo "Incorrect arch"
exit 1
esac
BUILD_DIR="build_macos_${ARCH}"
PACKAGE_DIR="$GMP_DIR/package_macos_${ARCH}"
if [ -d "$PACKAGE_DIR" ]; then
echo "macOS ${ARCH} package is built already. See $PACKAGE_DIR. Skip building this ARCH."
return
fi
rm -rf "$BUILD_DIR"
mkdir "$BUILD_DIR"
cd "$BUILD_DIR"
../configure --prefix="${PACKAGE_DIR}" \
CC="$(xcrun --sdk macosx --find clang)" \
CFLAGS="-O3 -isysroot $(xcrun --sdk macosx --show-sdk-path) ${ARCH_FLAGS} -fvisibility=hidden -mmacos-version-min=14.0" \
LDFLAGS="" \
--host "${ARCH}-apple-darwin" --disable-assembly --enable-static --disable-shared --with-pic &&
make -j${NPROC} &&
make install
cd ..
}
build_macos_fat()
{
echo "Building for macOS arm64"
build_macos_arch "arm64"
echo "Building for macOS x86_64"
build_macos_arch "x86_64"
gmp_lib_arm64="$GMP_DIR/package_macos_arm64/lib/libgmp.a"
gmp_lib_x86_64="$GMP_DIR/package_macos_x86_64/lib/libgmp.a"
gmp_lib_fat="$GMP_DIR/package_macos/lib/libgmp.a"
mkdir -p "${GMP_DIR}/package_macos/lib"
lipo "${gmp_lib_arm64}" "${gmp_lib_x86_64}" -create -output "${gmp_lib_fat}"
mkdir -p "${GMP_DIR}/package_macos/include"
cp "${GMP_DIR}/package_macos_arm64/include/gmp.h" "${GMP_DIR}/package_macos/include/"
echo "Wrote universal fat library for macOS arm64/x86_64 to ${GMP_DIR}/package_macos/lib/libgmp.a"
}
if [ $# -ne 1 ]; then
usage
fi
TARGET_PLATFORM=$(echo "$1" | tr "[:upper:]" "[:lower:]")
cd depends
get_gmp
cd gmp
GMP_DIR=$PWD
case "$TARGET_PLATFORM" in
"ios" )
echo "Building for ios"
build_ios
;;
"ios_simulator" )
echo "Building for iPhone Simulator"
build_ios_simulator
;;
"macos" )
echo "Building fat library for macOS"
build_macos_fat
;;
"macos_arm64" )
echo "Building library for macOS arm64"
build_macos_arch "arm64"
;;
"macos_x86_64" )
echo "Building library for macOS x86_64"
build_macos_arch "x86_64"
;;
"android" )
echo "Building for android"
build_android
;;
"android_x86_64" )
echo "Building for android x86_64"
build_android_x86_64
;;
"host" )
echo "Building for this host"
build_host
;;
"host_noasm" )
echo "Building for this host without asm optimizations (e.g. needed for macOS)"
build_host_noasm
;;
"aarch64" )
echo "Building for linux aarch64"
build_aarch64
;;
* )
usage
esac