From b54fa7f61e3c9acdfdc13b9680b9ff023d69323d Mon Sep 17 00:00:00 2001 From: Robert Kirkman Date: Fri, 18 Apr 2025 12:36:32 -0500 Subject: [PATCH] addpkg(main/sbcl): 2.5.3 - Fixes https://github.com/termux/termux-packages/issues/948 - Partially fixes https://github.com/termux/termux-packages/issues/24176 - Partially fixes https://github.com/termux/termux-packages/issues/183 Previous attempts and progress: - https://github.com/termux/termux-packages/commit/880983e754c432d3432bac7d70c2507b2e1d7c8a (2016) - https://github.com/termux/termux-packages/pull/7625 (2021) - https://github.com/termux/termux-packages/pull/14435 (2023) This PR mainly implements the package in a termux-packages downstream-oriented way (heavy use of internal termux-packages repository code shared with other termux-packages). There is discussion regarding the upstream-oriented way of implementation from the SBCL side (trying to non-cross-compile while avoiding use of any internal termux-packages repository code) here: https://bugs.launchpad.net/sbcl/+bug/1956852 --- disabled-packages/sbcl/build.sh | 25 ---- disabled-packages/sbcl/make-config.sh.patch | 15 -- packages/sbcl/build.sh | 112 +++++++++++++++ .../sbcl/disable-close_range-syscall.patch | 14 ++ ...-tests-that-were-only-enabled-on-x86.patch | 30 ++++ ...disable-intermittently-failing-tests.patch | 25 ++++ ...tests-that-only-fail-in-termux-proot.patch | 105 ++++++++++++++ packages/sbcl/fix-build-on-device.patch | 129 ++++++++++++++++++ packages/sbcl/fix-stat-st_nlink-x86.patch | 48 +++++++ packages/sbcl/pass-testsuite-on-device.patch | 121 ++++++++++++++++ 10 files changed, 584 insertions(+), 40 deletions(-) delete mode 100644 disabled-packages/sbcl/build.sh delete mode 100644 disabled-packages/sbcl/make-config.sh.patch create mode 100644 packages/sbcl/build.sh create mode 100644 packages/sbcl/disable-close_range-syscall.patch create mode 100644 packages/sbcl/disable-failing-tests-that-were-only-enabled-on-x86.patch create mode 100644 packages/sbcl/disable-intermittently-failing-tests.patch create mode 100644 packages/sbcl/disable-tests-that-only-fail-in-termux-proot.patch create mode 100644 packages/sbcl/fix-build-on-device.patch create mode 100644 packages/sbcl/fix-stat-st_nlink-x86.patch create mode 100644 packages/sbcl/pass-testsuite-on-device.patch diff --git a/disabled-packages/sbcl/build.sh b/disabled-packages/sbcl/build.sh deleted file mode 100644 index f87b818aa2d3c64..000000000000000 --- a/disabled-packages/sbcl/build.sh +++ /dev/null @@ -1,25 +0,0 @@ -TERMUX_PKG_HOMEPAGE=https://www.sbcl.org/ -TERMUX_PKG_DESCRIPTION="Steel Bank Common Lisp" -TERMUX_PKG_LICENSE="custom" -TERMUX_PKG_MAINTAINER="@termux" -TERMUX_PKG_VERSION=1.3.9 -TERMUX_PKG_SRCURL=https://prdownloads.sourceforge.net/sbcl/sbcl-${TERMUX_PKG_VERSION}-source.tar.bz2 -TERMUX_PKG_SHA256=af0f09d4379113dfd5aa255279cb3df9cb9cac0bcd65369cc43dd857ca51de6e - -termux_step_pre_configure() { - local SBCL_HOST_TARFILE=$TERMUX_PKG_CACHEDIR/sbcl-host-${TERMUX_PKG_VERSION}.tar.bz2 - if [ ! -f $SBCL_HOST_TARFILE ]; then - curl -o $SBCL_HOST_TARFILE -L http://downloads.sourceforge.net/project/sbcl/sbcl/${TERMUX_PKG_VERSION}/sbcl-${TERMUX_PKG_VERSION}-x86-64-linux-binary.tar.bz2 - cd $TERMUX_PKG_TMPDIR - tar xf $SBCL_HOST_TARFILE - cd sbcl-${TERMUX_PKG_VERSION}-x86-64-linux - INSTALL_ROOT=$TERMUX_PKG_CACHEDIR/sbcl-host sh install.sh - fi - export PATH=$PATH:$TERMUX_PKG_CACHEDIR/sbcl-host/bin - export SBCL_HOME=$TERMUX_PKG_CACHEDIR/sbcl-host/lib/sbcl -} - -termux_step_make_install() { - cd $TERMUX_PKG_SRCDIR - sh make.sh --prefix=$TERMUX_PREFIX -} diff --git a/disabled-packages/sbcl/make-config.sh.patch b/disabled-packages/sbcl/make-config.sh.patch deleted file mode 100644 index b125bd944eb36e5..000000000000000 --- a/disabled-packages/sbcl/make-config.sh.patch +++ /dev/null @@ -1,15 +0,0 @@ -diff -u -r ../sbcl-1.3.4/make-config.sh ./make-config.sh ---- ../sbcl-1.3.4/make-config.sh 2016-03-31 03:28:36.000000000 -0400 -+++ ./make-config.sh 2016-04-10 16:43:40.651905145 -0400 -@@ -754,8 +754,9 @@ - # cross-compilers! - # - # FIXME: integrate to grovel-features, mayhaps --$GNUMAKE -C tools-for-build determine-endianness -I ../src/runtime --tools-for-build/determine-endianness >> $ltf -+# $GNUMAKE -C tools-for-build determine-endianness -I ../src/runtime -+# tools-for-build/determine-endianness >> $ltf -+echo " :little-endian" >> $ltf # Termux patch. - - export sbcl_os sbcl_arch - sh tools-for-build/grovel-features.sh >> $ltf diff --git a/packages/sbcl/build.sh b/packages/sbcl/build.sh new file mode 100644 index 000000000000000..c8f9174b7130806 --- /dev/null +++ b/packages/sbcl/build.sh @@ -0,0 +1,112 @@ +TERMUX_PKG_HOMEPAGE="http://www.sbcl.org/" +TERMUX_PKG_DESCRIPTION="A high performance Common Lisp compiler" +TERMUX_PKG_LICENSE="custom" +TERMUX_PKG_LICENSE_FILE="COPYING" +TERMUX_PKG_MAINTAINER="@termux" +TERMUX_PKG_VERSION="2.5.3" +TERMUX_PKG_SRCURL="https://github.com/sbcl/sbcl/archive/refs/tags/sbcl-${TERMUX_PKG_VERSION}.tar.gz" +TERMUX_PKG_SHA256=f3b923778f7d1f151f2bdc08a0e92ec4f5a3db5efca5f46ea2ac439dda06cc35 +TERMUX_PKG_DEPENDS="zstd" +# TERMUX_ON_DEVICE_BUILD=true build dependencies: ecl, strace +# TERMUX_ON_DEVICE_BUILD=false build dependencies: aosp-libs, bash, coreutils, strace +# NOTE: if you are bootstrapping on-device, if either is desired, it is possible to manually +# implement both an on-device build and an x86 build of ecl, but those are currently +# unimplemented in termux-packages at time of writing. +# the build dependency is disabled to avoid dependency errors when cross-compiling in CI for x86. +TERMUX_PKG_BUILD_DEPENDS="aosp-libs, bash, coreutils, strace" +# it is extremely difficult to port SBCL to 32-bit Android because of multiple severe +# incompatibilties, like the lack of support for a fully position-independent runtime executable. +TERMUX_PKG_EXCLUDED_ARCHES="arm, i686" +TERMUX_PKG_AUTO_UPDATE=true +TERMUX_PKG_BUILD_IN_SRC=true +TERMUX_PKG_HOSTBUILD=true + +termux_step_host_build() { + if [[ "$TERMUX_ON_DEVICE_BUILD" == "true" ]]; then + return + fi + + # precompiled SBCL release for GNU/Linux to use as host Lisp for bootstrapping + SBCL_BINURL="https://sourceforge.net/projects/sbcl/files/sbcl/${TERMUX_PKG_VERSION}/sbcl-${TERMUX_PKG_VERSION}-x86-64-linux-binary.tar.bz2" + SBCL_BINARCHIVE="${TERMUX_PKG_CACHEDIR}/sbcl-${TERMUX_PKG_VERSION}-x86-64-linux-binary.tar.bz2" + SBCL_BINSHA256=e207fa6e851631dee0a467cea4f15276d31d4192c949a2b1d3d0daadbf70d443 + SBCL_WORKDIR="${TERMUX_PKG_TMPDIR}/sbcl" + mkdir -p "$SBCL_WORKDIR" + termux_download "$SBCL_BINURL" "$SBCL_BINARCHIVE" "$SBCL_BINSHA256" + tar -xf "$SBCL_BINARCHIVE" --strip-components=1 -C "$SBCL_WORKDIR" + export INSTALL_ROOT="$TERMUX_PKG_HOSTBUILD_DIR" + cd "$SBCL_WORKDIR" + sh install.sh +} + +termux_step_configure() { + if [[ "$TERMUX_ON_DEVICE_BUILD" == "false" ]]; then + termux_setup_proot + fi + + # See doc/PACKAGING-SBCL.txt + echo "\"${TERMUX_PKG_FULLVERSION}.termux\"" > version.lisp-expr +} + +termux_step_make() { + if [[ "$TERMUX_ON_DEVICE_BUILD" == "true" ]]; then + export LINKFLAGS="$LDFLAGS" + sh make.sh \ + --xc-host="${TERMUX_PREFIX}/bin/ecl --norc" \ + --prefix="$TERMUX_PREFIX" \ + --with-android \ + --fancy \ + --without-gcc-tls + + pushd tests + sh run-tests.sh + popd + else + # if not appended to make.sh, the build fails with no error message + # only after cross-compilation, not non-cross-compilation + echo "exit 0" >> make.sh + + # build SBCL inside a proot that runs bionic-libc $TERMUX_PREFIX/bin/uname, + # some other bionic-libc commands, and bionic-libc build artifacts, + # but runs the host cross-compiler and the host sbcl binary to compile + # bootstrapping lisp code and compile the C-based runtime code. + termux-proot-run env LD_PRELOAD= LD_LIBRARY_PATH= \ + CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" LINKFLAGS="$LDFLAGS" \ + sh make.sh \ + --xc-host="${TERMUX_PKG_HOSTBUILD_DIR}/bin/sbcl --norc" \ + --prefix="$TERMUX_PREFIX" \ + --with-android \ + --fancy \ + --without-gcc-tls + + pushd tests + # for passing some tests + mkdir -p "$TERMUX_ANDROID_HOME" + + # run test suite inside proot + termux-proot-run env LD_PRELOAD= LD_LIBRARY_PATH= \ + CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" LINKFLAGS="$LDFLAGS" \ + TMPDIR="$TERMUX_PREFIX/tmp" \ + sh run-tests.sh + popd + fi + + # docs fail to build even after trying to configure texinfo and texlive, + # both on-device and after cross-compilation. + # error: + # texi2dvi -q -I "docstrings/" -I "../../contrib/" sbcl.texinfo + # start-stop.texinfo:113: I can't find file `fun-sb-ext-exit.texinfo'. + # texi2dvi: etex exited with bad status, quitting + #if [[ "$TERMUX_ON_DEVICE_BUILD" == "true" ]]; then + # make -C doc/manual + #else + # # build docs inside proot because this step needs the newly compiled bionic-libc sbcl + # termux-proot-run env LD_PRELOAD= LD_LIBRARY_PATH= \ + # make -C doc/manual + #fi + # however, at least the command "man sbcl" does work after installation despite this. +} + +termux_step_make_install() { + INSTALL_ROOT="$TERMUX_PREFIX" sh install.sh +} diff --git a/packages/sbcl/disable-close_range-syscall.patch b/packages/sbcl/disable-close_range-syscall.patch new file mode 100644 index 000000000000000..316269220095fed --- /dev/null +++ b/packages/sbcl/disable-close_range-syscall.patch @@ -0,0 +1,14 @@ +Disables use of close_range() on Android, which does not have +that function until API level 34 (Android 14) + +--- a/src/runtime/run-program.c ++++ b/src/runtime/run-program.c +@@ -134,7 +134,7 @@ void closefds_range(unsigned int first, unsigned int last) + #if defined(LISP_FEATURE_OS_PROVIDES_CLOSE_RANGE_WRAPPER) + // Prefer the libc wrapper, if it exists at build time. + fds_closed = !close_range(first, last, 0); +-#elif defined(LISP_FEATURE_LINUX) && defined(__NR_close_range) ++#elif defined(LISP_FEATURE_LINUX) && defined(__NR_close_range) && !defined(LISP_FEATURE_ANDROID) + // Use syscall(2) if we could detect the syscall number at build time. + fds_closed = !syscall(__NR_close_range, first, last, 0); + #endif diff --git a/packages/sbcl/disable-failing-tests-that-were-only-enabled-on-x86.patch b/packages/sbcl/disable-failing-tests-that-were-only-enabled-on-x86.patch new file mode 100644 index 000000000000000..47014629f276abe --- /dev/null +++ b/packages/sbcl/disable-failing-tests-that-were-only-enabled-on-x86.patch @@ -0,0 +1,30 @@ +elfcore.test.sh/elf-sans-immobile.test.sh is not passing on Android-x86, +so it is disabled by this. These tests also fail on ARM, but are +not enabled by upstream on any targets except 64-bit x86. +The exact reason why the test fails, or what steps might be necessary +to fix it, are not known, but one way of describing the probable +effects that this test failing implies would be: +"the 'elfination' feature is most likely not working on Android" + +--- a/tests/elf-sans-immobile.test.sh ++++ b/tests/elf-sans-immobile.test.sh +@@ -16,7 +16,7 @@ + . ./subr.sh + + run_sbcl <arena)))) + +--- a/tests/stream.impure.lisp ++++ b/tests/stream.impure.lisp +@@ -697,7 +697,7 @@ + ;; We used to not return from read on a named pipe unless the external-format + ;; routine had filled an input buffer. Now we'll return as soon as a request + ;; is satisfied, or on EOF. (https://bugs.launchpad.net/sbcl/+bug/643686) +-#-win32 ++#-(or win32 android) + (with-test (:name :overeager-character-buffering :skipped-on :win32) + (let ((use-threads #+sb-thread t) + (proc nil) diff --git a/packages/sbcl/disable-tests-that-only-fail-in-termux-proot.patch b/packages/sbcl/disable-tests-that-only-fail-in-termux-proot.patch new file mode 100644 index 000000000000000..ee9bd6b072feee6 --- /dev/null +++ b/packages/sbcl/disable-tests-that-only-fail-in-termux-proot.patch @@ -0,0 +1,105 @@ +These two tests only fail in termux-proot-run, not in an actual Termux App, +because of different behavior of the proot environment, and it doesn't +seem easy or straightforward to somehow fix them specifically for termux-proot-run. + +Builds of SBCL produced by 'termux-proot-run sh make.sh' still pass these tests when +the build directory is copied to a real Termux App and the test suite is run there. + +run-program-test.sh all envrionment variables comparison test: +termux-proot-run for TERMUX_ON_DEVICE_BUILD=false mode currently does something +that seems to make the environment variables scrambled into a different order +when this test tries to print and compare them as two large strings, and also makes the SBCL_PWD +environment variable not match between the two strings. + +Example: + The assertion (STRING= STRING EXPECTED) failed with STRING = "LD_LIBRARY_PATH= +LD_PRELOAD= +SBCL_PWD=/home/builder/.termux-build/sbcl/src/tests +SBCL_RUNTIME=/home/builder/.termux-build/sbcl/src/tests/../src/runtime/sbcl +HOME=/data/data/com.termux/files/home +LINKFLAGS=-L/data/data/com.termux/files/usr/lib -Wl,-rpath=/data/data/com.termux/files/usr/lib -Wl,--enable-new-dtags -Wl,--as-needed -Wl,-z,relro,-z,now +EXIT_LISP_WIN=52 +TERM=xterm +SOMETHING_IN_THE_ENVIRONMENT=yes there is +ANDROID_DATA=/data +TEST_FILESTEM=run-program-test +PATH=/some/path/that/does/not/exist:/data/data/com.termux/files/usr/bin:/home/builder/.termux-build/_cache/proot-bin-aarch64:/home/builder/.termux-build/_cache/android-r27c-api-24-v1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +EXIT_TEST_WIN=104 +CFLAGS= -fstack-protector-strong -Oz +ANDROID_ROOT=/system +SBCL_HOME=/home/builder/.termux-build/sbcl/src/tests/../obj/sbcl-home +SBCL_CORE=/home/builder/.termux-build/sbcl/src/tests/../output/sbcl.core +LANG=C +CPPFLAGS= -isystem/data/data/com.termux/files/usr/include/c++/v1 -isystem/data/data/com.termux/files/usr/include +PREFIX=/data/data/com.termux/files/usr +EXIT_LOSE=1 +SBCL_ARGS=--disable-ldb --noinform --no-sysinit --no-userinit --noprint --disable-debugger +script_basename=run-program.test.sh +PWD=/home/builder/.termux-build/sbcl/src/tests +LC_ALL=C +TEST_DIRECTORY=/home/builder/.termux-build/sbcl/src/tests/run-program-test-28269 +TZ=UTC +", + EXPECTED = "LD_LIBRARY_PATH= +LD_PRELOAD= +TZ=UTC +TEST_DIRECTORY=/home/builder/.termux-build/sbcl/src/tests/run-program-test-28269 +LC_ALL=C +PWD=/home/builder/.termux-build/sbcl/src/tests +script_basename=run-program.test.sh +SBCL_ARGS=--disable-ldb --noinform --no-sysinit --no-userinit --noprint --disable-debugger +EXIT_LOSE=1 +PREFIX=/data/data/com.termux/files/usr +CPPFLAGS= -isystem/data/data/com.termux/files/usr/include/c++/v1 -isystem/data/data/com.termux/files/usr/include +LANG=C +SBCL_CORE=/home/builder/.termux-build/sbcl/src/tests/../output/sbcl.core +SBCL_HOME=/home/builder/.termux-build/sbcl/src/tests/../obj/sbcl-home +ANDROID_ROOT=/system +CFLAGS= -fstack-protector-strong -Oz +EXIT_TEST_WIN=104 +PATH=/some/path/that/does/not/exist:/data/data/com.termux/files/usr/bin:/home/builder/.termux-build/_cache/proot-bin-aarch64:/home/builder/.termux-build/_cache/android-r27c-api-24-v1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +TEST_FILESTEM=run-program-test +ANDROID_DATA=/data +SOMETHING_IN_THE_ENVIRONMENT=yes there is +TERM=xterm +EXIT_LISP_WIN=52 +LINKFLAGS=-L/data/data/com.termux/files/usr/lib -Wl,-rpath=/data/data/com.termux/files/usr/lib -Wl,--enable-new-dtags -Wl,--as-needed -Wl,-z,relro,-z,now +HOME=/data/data/com.termux/files/home +SBCL_RUNTIME=/home/builder/.termux-build/sbcl/src/tests/../src/runtime/sbcl +SBCL_PWD=/home/builder/.termux-build/sbcl/src/tests +". + +malloc-failure: +This test essentially behaves similarly to a fork bomb or zip bomb +in some environments, like termux-proot-run. +It is an intentional, aggressive memory leak, sometimes. +It repeatedly calls malloc() in a loop until the system memory is +full, and it registers as a failure on systems that have an OOM killer daemon +running because the OOM killer will kill the lisp process before the test can +complete. +This is noted in the comment by upstream, and it is explained that this test +is expected to fail and have to be disabled in some situations. +https://github.com/sbcl/sbcl/blob/b46a61a4fd23f4e3954771eb9c9914dd26a21048/tests/alien.impure.lisp#L373-L381 + +--- a/tests/run-program.test.sh ++++ b/tests/run-program.test.sh +@@ -101,7 +101,7 @@ run_sbcl --eval "(defvar *exit-ok* $EXIT_LISP_WIN)" <<'EOF' + ;; The default Unix environment for the subprocess is the same as + ;; for the parent process. (I.e., we behave like perl and lots of + ;; other programs, but not like CMU CL.) +- #+unix ++ #+(and unix (not android)) + (let* ((sb-impl::*default-external-format* :latin-1) + (sb-alien::*default-c-string-external-format* :latin-1) + (string (with-output-to-string (stream) +--- a/tests/alien.impure.lisp ++++ b/tests/alien.impure.lisp +@@ -382,7 +382,7 @@ + #+64-bit (unless (>= (integer-length array-total-size-limit) 45) + (push :skip-malloc-test *features*)) + (with-test (:name :malloc-failure ; for lp#891268 +- :skipped-on (or :ubsan :msan :skip-malloc-test)) ++ :skipped-on (or :ubsan :msan :skip-malloc-test :android)) + (assert (eq :enomem + (handler-case + (loop repeat 128 diff --git a/packages/sbcl/fix-build-on-device.patch b/packages/sbcl/fix-build-on-device.patch new file mode 100644 index 000000000000000..23ca2893d6117b9 --- /dev/null +++ b/packages/sbcl/fix-build-on-device.patch @@ -0,0 +1,129 @@ +Fixes multiple errors in the on-device build of SBCL in Termux + +when this command is used on-device: + +sh make.sh --xc-host="$PREFIX/bin/ecl --norc" --prefix="$PREFIX" --with-android --fancy --without-gcc-tls + +contains some code from https://bugs.launchpad.net/sbcl/+bug/1956852 + +- make-contrib.lisp: remove block related to cross-compilation imeplementation created by upstream +- make-config.sh: disable blocks related to upstream's cross-compilation implementation and also + disable upstream's Android-specific headers and Android-specific software-version function +- run-program.lisp: enable the implementation of the software-version function intended for + GNU/Linux, but disable the use of /proc/sys/kernel/osrelease and prepend @TERMUX_PREFIX@ + to /bin/uname absolute path +- build-order.lisp-expr: treat Android as "Linux" in this file, disabling upstream's + Android-specific software-version function +- android_run.sh: rewrite functions related to upstream's cross-compilation implementation +- grovel-features.sh: adjust function call related to upstream's cross-compilation implementation + +--- a/contrib/make-contrib.lisp ++++ b/contrib/make-contrib.lisp +@@ -12,11 +12,6 @@ + + (defun run-defs-to-lisp (inputs output) + (flet ((invoke (string &rest args) +- #+android +- (when (string= string "RUN-C-COMPILER") +- (format t "~a ~{~a~^ ~}~%" string args) +- (sleep 5) ;; FIXME: should check if the file was compiled +- (return-from invoke 0)) + (apply (find-symbol string "SB-GROVEL") args))) + (let ((c-file (merge-pathnames "runme.c" output)) + (all-headers) +--- a/make-config.sh ++++ b/make-config.sh +@@ -384,7 +384,7 @@ echo //ensuring the existence of output/ directory + if [ ! -d output ] ; then mkdir output; fi + + echo //guessing default target CPU architecture from host architecture +-if $android ++if false + then + uname_arch=`adb shell uname -m` + else +@@ -472,7 +477,7 @@ then + esac + HOST_TAG=$sbcl_os-x86_64 + TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG +- export CC=$TOOLCHAIN/bin/$TARGET_TAG$ANDROID_API-clang ++ export CC=$TARGET_TAG-clang + echo "CC=$CC; export CC" >> output/build-config + echo "NDK=$NDK" > output/ndk-config + echo "HOST_TAG=$HOST_TAG" >> output/ndk-config +@@ -580,7 +585,7 @@ case "$sbcl_os" in + printf ' :largefile' >> $ltf + ;; + esac +- if $android ++ if false + then + link_or_copy Config.$sbcl_arch-android Config + link_or_copy $sbcl_arch-android-os.h target-arch-os.h +--- a/src/code/run-program.lisp ++++ b/src/code/run-program.lisp +@@ -1363,19 +1363,16 @@ Users Manual for details about the PROCESS structure. + (t + (fail "invalid option: ~S" object)))))) + +-#+(or (and linux (not android)) sunos haiku) ++#+(or linux sunos haiku) + (defun software-version () + "Return a string describing version of the supporting software, or NIL + if not available." + (or sb-sys::*software-version* + (setf sb-sys::*software-version* + (possibly-base-stringize +- #+linux +- (with-open-file (f "/proc/sys/kernel/osrelease") (read-line f)) +- #-linux + (string-trim '(#\newline) + (%with-output-to-string (stream) +- (run-program "/bin/uname" ++ (run-program "@TERMUX_PREFIX@/bin/uname" + ;; "-r" on haiku just prints "1" + ;; but "-v" prints some detail. + #+haiku '("-v") +--- a/src/cold/build-order.lisp-expr ++++ b/src/cold/build-order.lisp-expr +@@ -486,10 +486,9 @@ + ("src/code/funutils" :not-host) + + #+win32 ("src/code/win32" :not-host) +- #+android ("src/code/android-os" :not-host) + #+sunos ("src/code/sunos-os" :not-host) + #+bsd ("src/code/bsd-os" :not-host) +- #+(and linux (not android)) ("src/code/linux-os" :not-host) ++ #+linux ("src/code/linux-os" :not-host) + #+haiku ("src/code/haiku-os" :not-host) + #+win32 ("src/code/win32-os" :not-host) + +--- a/tools-for-build/android_run.sh ++++ b/tools-for-build/android_run.sh +@@ -1,13 +1,7 @@ + android_run() { +- adb push $1 /data/local/tmp/temp.out > /dev/null +- adb shell chmod +x /data/local/tmp/temp.out > /dev/null +- adb shell ./data/local/tmp/temp.out +- adb shell rm /data/local/tmp/temp.out > /dev/null ++ $@ + } + + android_run_for_exit_code() { +- adb push $1 /data/local/tmp/$1 > /dev/null +- adb shell chmod +x /data/local/tmp/$1 > /dev/null 2>&1 +- adb shell "echo input | ./data/local/tmp/$1 > /dev/null 2>&1 ; echo \"\$?\"" 2>/dev/null +- adb shell rm /data/local/tmp/$1 > /dev/null 2>&1 ++ echo input | $@ > /dev/null 2>&1 ; echo "$?" + } +--- a/tools-for-build/grovel-features.sh ++++ b/tools-for-build/grovel-features.sh +@@ -16,7 +16,7 @@ featurep() { + if $android + then + $CC -I../src/runtime -ldl -o $bin $bin.c > /dev/null 2>&1 +- exit_code=`android_run_for_exit_code $bin` ++ exit_code=`android_run_for_exit_code ./$bin` + else + $GNUMAKE $bin -I ../src/runtime > /dev/null 2>&1 && echo "input" | ./$bin> /dev/null 2>&1 + exit_code="$?" diff --git a/packages/sbcl/fix-stat-st_nlink-x86.patch b/packages/sbcl/fix-stat-st_nlink-x86.patch new file mode 100644 index 000000000000000..145539a8ff21d2b --- /dev/null +++ b/packages/sbcl/fix-stat-st_nlink-x86.patch @@ -0,0 +1,48 @@ +on 64-bit Android-x86, unlike Android ARM, st_nlink is 64 bits wide, not 32 bits. +https://cs.android.com/android/platform/superproject/+/android15-qpr2-release:bionic/libc/include/sys/stat.h;l=68 + +This probably happened because upstream's Android-stat-related commit +https://github.com/sbcl/sbcl/commit/30d48e68d8d554e60a89bc8fab87bb9eeea65b80 +was never tested on 64-bit Android-x86. +That is completely forgivable because, in 2014, it might not yet have been +obvious or expected in any way that 64-bit Android-x86 would ever +be meaningfully usable or testable in any real-world situation, and additionally, +it's uncertain whether the headers the author of that commit would have been +looking at at the time would have even been from a version of Android that +supported 64-bit x86 at all, since Android-x86 was originally +an entirely downstream project, and the official headers for Android 4, for example, +don't contain this information. It was added in Android 5, which released several +months AFTER this commit was made to SBCL. +https://cs.android.com/android/platform/superproject/+/android-4.2.2_r1.1:bionic/libc/include/sys/stat.h + +This change makes the stat.1, stat-mode.2, stat-mode.7 and stat-mode.8 tests +of contrib/sb-posix/posix-tests.lisp pass successfully on 64-bit Android-x86. + + +--- a/contrib/sb-posix/constants.lisp ++++ b/contrib/sb-posix/constants.lisp +@@ -325,7 +325,10 @@ + ((unsigned 32) dev "dev_t" "st_dev") + #+android + ((unsigned 64) dev "unsigned long long" "st_dev") ++ #-(and android x86-64) + (nlink-t nlink "nlink_t" "st_nlink") ++ #+(and android x86-64) ++ ((unsigned 64) nlink "unsigned long" "st_nlink") + (uid-t uid "uid_t" "st_uid") + ;; Linux/MIPS uses unsigned long instead of dev_t here. + #-(or mips android) +--- a/src/runtime/wrap.h ++++ b/src/runtime/wrap.h +@@ -68,7 +68,11 @@ typedef short wst_nlink_t; + typedef short wst_uid_t; + typedef short wst_gid_t; + #else ++#if defined(LISP_FEATURE_ANDROID) && defined(LISP_FEATURE_X86_64) ++typedef unsigned long wst_nlink_t; ++#else + typedef nlink_t wst_nlink_t; ++#endif + typedef uid_t wst_uid_t; + typedef gid_t wst_gid_t; + #endif diff --git a/packages/sbcl/pass-testsuite-on-device.patch b/packages/sbcl/pass-testsuite-on-device.patch new file mode 100644 index 000000000000000..9c86eb5b11264af --- /dev/null +++ b/packages/sbcl/pass-testsuite-on-device.patch @@ -0,0 +1,121 @@ +Makes Termux App on-device pass all tests (most of the time), +after building SBCL when the run-tests.sh script in the tests +folder is run on bare metal 64-bit ARM Android. + +Fixes https://github.com/termux/termux-packages/issues/24176 + +contains some code from https://bugs.launchpad.net/sbcl/+bug/1956852 + +- posix-tests.lisp: prepend @TERMUX_PREFIX@ to absolute paths + and slightly rewrite mkstemp.null-terminate to work with + absolute paths that contain periods in folder names (com.termux) +- fd-stream.lisp: call termux_tmpfile() instead of tmpfile() directly, + which avoids calling the implementation of tmpfile() that would be + loaded via dlopen() of libc.so, which does not respect $TMPDIR + on Android 13 and older. +- linux-os.c: implement termux_tmpfile() wrapper of prefix-prepended + custom implementation of tmpfile() which is inlined in the custom + stdio.h header of the Termux custom NDK +- run-program.test.sh: prepend @TERMUX_PREFIX@ to absolute paths + +--- a/contrib/sb-posix/posix-tests.lisp ++++ b/contrib/sb-posix/posix-tests.lisp +@@ -247,7 +247,7 @@ + (deftest stat.5 + (let* ((stat-1 (sb-posix:stat "/")) + (inode-1 (sb-posix:stat-ino stat-1)) +- (stat-2 (sb-posix:stat "/bin/sh" ++ (stat-2 (sb-posix:stat "@TERMUX_PREFIX@/bin/sh" + stat-1)) + (inode-2 (sb-posix:stat-ino stat-2))) + (values +@@ -506,7 +506,7 @@ + 3 #\f #\o #\o) + + (deftest opendir.1 +- (let ((dir (sb-posix:opendir "/"))) ++ (let ((dir (sb-posix:opendir "@TERMUX_PREFIX@"))) + (unwind-protect (sb-alien:null-alien dir) + (unless (sb-alien:null-alien dir) + (sb-posix:closedir dir)))) +@@ -514,7 +514,7 @@ + + #-(or (and darwin x86) haiku) + (deftest readdir.1 +- (let ((dir (sb-posix:opendir "/"))) ++ (let ((dir (sb-posix:opendir "@TERMUX_PREFIX@"))) + (unwind-protect + (block dir-loop + (loop for dirent = (sb-posix:readdir dir) +@@ -921,7 +921,7 @@ + + #-win32 + (deftest mkstemp.null-terminate +- (let* ((default (make-pathname :directory '(:absolute "tmp"))) ++ (let* ((default (make-pathname :directory '(:absolute "@TERMUX_PREFIX@/tmp"))) + (filename (namestring (make-pathname :name "mkstemp-1" + :type "XXXXXX" + :defaults default))) +@@ -936,9 +936,9 @@ + (make-string n :initial-element #\x)) + :defaults default)) + (unwind-protect +- (values (integerp fd) (subseq temp 0 (position #\. temp))) ++ (values (integerp fd) (subseq temp 0 (position #\. temp :from-end t))) + (delete-file temp)))) +- t "/tmp/mkstemp-1") ++ t "/@TERMUX_PREFIX@/tmp/mkstemp-1") + + (deftest envstuff + (let ((name1 "ASLIFJLSDKFJKAHGSDKLJH") +--- a/src/code/fd-stream.lisp ++++ b/src/code/fd-stream.lisp +@@ -2876,7 +2876,7 @@ + ;;; race conditions and (at least on Linux) does not make use of any shell environment variables + ;;; to determine a directory - in fact it doesn't make a directory entry at all. + (defun sb-unix:unix-tmpfile () +- (make-stdio-file (alien-funcall (extern-alien "tmpfile" (function system-area-pointer))))) ++ (make-stdio-file (alien-funcall (extern-alien "termux_tmpfile" (function system-area-pointer))))) + + (defun sb-unix:unix-fclose (file) + (alien-funcall (extern-alien "fclose" (function int system-area-pointer)) +--- a/src/runtime/linux-os.c ++++ b/src/runtime/linux-os.c +@@ -416,3 +416,8 @@ char *os_get_runtime_executable_path() + + return copied_string(path); + } ++ ++FILE *termux_tmpfile(void) ++{ ++ return tmpfile(); ++} +--- a/tests/run-program.test.sh ++++ b/tests/run-program.test.sh +@@ -50,7 +50,7 @@ run_sbcl --eval "(defvar *exit-ok* $EXIT_LISP_WIN)" <<'EOF' + #+haiku + "/bin/env" + #-haiku +- "/usr/bin/env") ++ "@TERMUX_PREFIX@/bin/env") + + ;; Unix environment strings are ordinarily passed with SBCL convention + ;; (instead of CMU CL alist-of-keywords convention). +@@ -84,7 +84,7 @@ run_sbcl --eval "(defvar *exit-ok* $EXIT_LISP_WIN)" <<'EOF' + #+unix + (flet ((try (sb-impl::*default-external-format* x y) + (let* ((process (run-program +- "/bin/sh" (list "-c" (format nil "echo ~c, $SB_TEST_FOO." x)) ++ "@TERMUX_PREFIX@/bin/sh" (list "-c" (format nil "echo ~c, $SB_TEST_FOO." x)) + :environment (list (format nil "SB_TEST_FOO=~c" y)) + :output :stream + :wait t)) +@@ -132,7 +132,7 @@ run_sbcl --eval "(defvar *exit-ok* $EXIT_LISP_WIN)" <<'EOF' + ;; note: this test will be inconclusive if the child's stderr is + ;; fully buffered.) + (let ((str (with-output-to-string (s) +- (our-run-program "/bin/sh" ++ (our-run-program "@TERMUX_PREFIX@/bin/sh" + '("-c" "(echo Foo; sleep 2; echo Bar)>&2") + :output s :search t :error :output :wait t)))) + (assert (string= str (format nil "Foo~%Bar~%"))))