0
0
mirror of https://github.com/termux/termux-packages.git synced 2025-05-10 06:55:47 +00:00
Files
termux-packages/packages/ghc/build.sh
Aditya Alok e21578f662 bump(main/ghc): 9.12.2
Patched `rts` heap reservation logic on Android:

  * Need for patch

  - There seems to be a bug on Android. Sometimes simple commands like `ghc --help` usage 90% - 100% cpu and hangs.

  - It doesn't happen every time, but ~25% of the times (at least in my
    testing).

  * Cause of the bug

  - The function `osReserveHeapMemory` tries to allocate virtual space starting
    from `0x4200000000`. The allocated space has to start at an address >= this address.

  - If the kernel doesn't allocate inside this space, it keeps on repeating the
    `mmap` call with increasing starting point.

  - Now, on Android the kernel sometimes return an address above (as in counting)
    this `hint` address. It repeatedly returns the same address for subsequent calls.

  - Thus, an infinite loop occurs.

  References:
    - 383be28ffd/rts/posix/OSMem.c (L461)
    - https://github.com/termux/termux-packages/pull/22991#issuecomment-2759137291

  * Solution (proposed by Robert Kirkman):

  - It introduces a new helper function `osTryReserveHeapMemoryRecursive`.
    This transforms the heap reservation logic into a recursive one.

  - `osTryReserveHeapMemory()` is run multiple times without unmapping the
    undesired addresses. Thus, forcing the kernel to map subsequent calls of
    `mmap` to a new, unique address until an address above the `0x4200000000`
    mark is obtained.

  - After which each recursive call unmaps its undesired address before returning
    the desired address (in order from last mapped to first mapped).

  References:
    - https://gitlab.haskell.org/ghc/ghc/-/merge_requests/14164
    - https://github.com/termux/termux-packages/pull/22991#issuecomment-2761325484

Co-authored-by: Robert Kirkman <rkirkman@termux.dev>
Signed-off-by: Aditya Alok <alok@termux.dev>
2025-04-08 18:17:01 +02:00

113 lines
3.6 KiB
Bash

TERMUX_PKG_HOMEPAGE=https://www.haskell.org/ghc/
TERMUX_PKG_DESCRIPTION="The Glasgow Haskell Compiler"
TERMUX_PKG_LICENSE="custom"
TERMUX_PKG_MAINTAINER="Aditya Alok <alok@termux.dev>"
TERMUX_PKG_VERSION=9.12.2
TERMUX_PKG_SRCURL="https://downloads.haskell.org/~ghc/$TERMUX_PKG_VERSION/ghc-$TERMUX_PKG_VERSION-src.tar.xz"
TERMUX_PKG_SHA256=0e49cd5dde43f348c5716e5de9a5d7a0f8d68d945dc41cf75dfdefe65084f933
TERMUX_PKG_DEPENDS="libiconv, libffi, libgmp, libandroid-posix-semaphore, ncurses"
TERMUX_PKG_BUILD_IN_SRC=true
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="
--host=$TERMUX_BUILD_TUPLE
--with-system-libffi
--disable-ld-override"
TERMUX_PKG_NO_STATICSPLIT=true
TERMUX_PKG_LICENSE_FILE="LICENSE"
TERMUX_PKG_REPLACES="ghc-libs-static, ghc-libs"
TERMUX_PKG_PROVIDES="ghc-libs, ghc-libs-static"
__setup_bootstrap_compiler() {
local version=9.10.1
local temp_folder="$TERMUX_PKG_CACHEDIR/ghc-bootstrap-$version"
local tarball="$temp_folder.tar.xz"
local runtime_folder="$temp_folder-runtime"
export PATH="$runtime_folder/bin:$PATH"
[[ -d "$runtime_folder" ]] && return
termux_download "https://downloads.haskell.org/~ghc/$version/ghc-$version-x86_64-ubuntu20_04-linux.tar.xz" \
"$tarball" \
ae3be406fdb73bd2b0c22baada77a8ff2f8cde6220dd591dc24541cfe9d895eb
mkdir -p "$temp_folder" "$runtime_folder"
tar xf "$tarball" --strip-components=1 -C "$temp_folder"
(
set -e
unset CC CXX CFLAGS CXXFLAGS CPPFLAGS LDFLAGS AR AS CPP LD RANLIB READELF STRIP
cd "$temp_folder"
./configure --prefix="$runtime_folder"
make install
) &>/dev/null
rm -Rf "$temp_folder" "$tarball"
}
termux_step_pre_configure() {
__setup_bootstrap_compiler && termux_setup_cabal
export CONF_CC_OPTS_STAGE2="$CFLAGS $CPPFLAGS"
export CONF_GCC_LINKER_OPTS_STAGE2="$LDFLAGS"
export CONF_CXX_OPTS_STAGE2="$CXXFLAGS"
export target="$TERMUX_HOST_PLATFORM"
export no_profiled_libs=""
if [[ "$TERMUX_ARCH" == "arm" ]]; then
target="armv7a-linux-androideabi"
# NOTE: We do not build profiled libs for arm. It exceeds the 6 hours usage
# limit of github CI.
no_profiled_libs="+no_profiled_libs"
fi
TERMUX_PKG_EXTRA_CONFIGURE_ARGS="$TERMUX_PKG_EXTRA_CONFIGURE_ARGS --target=$target"
./boot.source
}
termux_step_make() {
(
unset CFLAGS LDFLAGS CPPFLAGS # For hadrian compilation
./hadrian/build binary-dist-dir \
-j"$TERMUX_PKG_MAKE_PROCESSES" \
--flavour="release$no_profiled_libs" --docs=none \
"stage1.unix.ghc.link.opts += -optl-landroid-posix-semaphore"
)
}
termux_step_make_install() {
cd _build/bindist/ghc-"$TERMUX_PKG_VERSION"-"$target" || exit 1
# Remove unnecessary flags. They would get written to settings file otherwise:
unset CONF_CC_OPTS_STAGE2 CONF_GCC_LINKER_OPTS_STAGE2 CONF_CXX_OPTS_STAGE2
# We need to re-run configure:
# See: https://gitlab.haskell.org/ghc/ghc/-/issues/22058
./configure \
--prefix="$TERMUX_PREFIX" \
--host="$target"
HOST_GHC_PKG="$(realpath ../../stage0/bin/ghc-pkg)" make install
}
termux_step_post_massage() {
local ghclibs_dir="lib/ghc-$TERMUX_PKG_VERSION"
if ! [[ -d "$ghclibs_dir" ]]; then
echo "ERROR: GHC lib directory is not at expected place. Please verify before continuing."
exit 1
fi
# Remove version suffix from `llc` and `opt`:
sed -i -E 's|("LLVM llc command",) "llc.*"|\1 "llc"|' "$ghclibs_dir"/lib/settings
sed -i -E 's|("LLVM opt command",) "opt.*"|\1 "opt"|' "$ghclibs_dir"/lib/settings
# Remove cross-prefix from tools:
sed -i "s|$CC|${CC/${target}-/}|g" "$ghclibs_dir"/lib/settings
sed -i "s|$CXX|${CXX/${target}-/}|g" "$ghclibs_dir"/lib/settings
# Strip unneeded symbols:
find . -type f \( -name "*.so" -o -name "*.a" \) -exec "$STRIP" --strip-unneeded {} \;
find "$ghclibs_dir"/bin -type f -exec "$STRIP" {} \;
}