mirror of
https://github.com/termux/termux-packages.git
synced 2025-05-10 06:55:47 +00:00
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>
113 lines
3.6 KiB
Bash
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" {} \;
|
|
}
|