#!/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 " 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