Subject: Re: bug#65340: further build failure on Android (Termux)

From: Bruno Haible <[email-masked]>
Date: Thu, 17 Aug 2023 00:46:06 +0200

Po Lu wrote:
> As with the bug you previously reported, this should also now be fixed.
> Please test and ack.

In my previous build, I had mistakenly forgotten to include the
configure '--host=armv7l-linux-androideabi' option. Thus my build skipped
a couple of of stumbling stones. Sorry about that.

Now, with this option included, I'm getting two other problems in the
first place:

1) Although I have installed ncurses-6.4 and put -I and -L options
so that libncurses should be found, the build fails while linking the
'temacs.tmp' executable:
----------------------------------------------------------------------
clang -ferror-limit=0 -o temacs.tmp \
  -Demacs  -I. -I. -I../lib -I../lib                          -MMD -MF deps/.d -MP                   -Wno-switch -Wno-pointer-sign -Wno-string-plus-int -Wno-unknown-attributes -Wno-unknown-pragmas -Wno-initializer-overrides -Wno-tautological-compare -Wno-tautological-constant-out-of-range-compare -O2 -DHAVE_CONFIG_H    -L/data/data/com.termux/files/home/local/lib -Wl,-rpath,/data/data/com.termux/files/home/local/include \
    dispnew.o frame.o scroll.o xdisp.o menu.o  window.o charset.o coding.o category.o ccl.o character.o chartab.o bidi.o cm.o term.o terminal.o xfaces.o    emacs.o keyboard.o macros.o keymap.o sysdep.o bignum.o buffer.o filelock.o insdel.o marker.o minibuf.o fileio.o dired.o cmds.o casetab.o casefiddle.o indent.o search.o regex-emacs.o undo.o alloc.o pdumper.o data.o doc.o editfns.o callint.o eval.o floatfns.o fns.o sort.o font.o print.o lread.o  syntax.o  bytecode.o comp.o  process.o gnutls.o callproc.o region-cache.o sound.o timefns.o atimer.o doprnt.o intervals.o textprop.o composite.o xml.o lcms.o   profiler.o decompress.o thread.o systhread.o sqlite.o  treesit.o itree.o                tparam.o lastfile.o      ../lib/libgnu.a                                -lutil              -lm     -lgmp        
ld.lld: error: undefined symbol: tputs
>>> referenced by cm.c
>>>               cm.o:(cmcostinit)
>>> referenced by cm.c
>>>               cm.o:(cmcostinit)
>>> referenced by cm.c
>>>               cm.o:(cmcostinit)
>>> referenced 114 more times
>>> did you mean: fputs
>>> defined in: /system/lib/libc.so

ld.lld: error: undefined symbol: tgetent
>>> referenced by term.c
>>>               term.o:(init_tty)

ld.lld: error: undefined symbol: tgetstr
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced 76 more times

ld.lld: error: undefined symbol: tgetflag
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced 9 more times

ld.lld: error: undefined symbol: tgetnum
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced by term.c
>>>               term.o:(init_tty)
>>> referenced 4 more times

ld.lld: error: undefined symbol: PC
>>> referenced by term.c
>>>               term.o:(init_tty)
clang-15: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [Makefile:743: temacs] Error 1
make[2]: Leaving directory '/data/data/com.termux/files/home/emacs/src'
make[1]: *** [Makefile:554: src] Error 2
make[1]: Leaving directory '/data/data/com.termux/files/home/emacs'
make[1]: Entering directory '/data/data/com.termux/files/home/emacs'
***
*** "make all" failed with exit status 2.
----------------------------------------------------------------------

The reason is that in src/config.h, the macro TERMINFO is no longer defined.

The cause are these two pieces of configure.ac:

AC_CACHE_CHECK([for library containing tputs], [emacs_cv_tputs_lib],
[if test "${opsys}" = "mingw32" || test "$opsys" = "android"; then
  emacs_cv_tputs_lib='none required'
else
  # curses precedes termcap because of AIX (Bug#9736#35) and OpenIndiana.
  tputs_libraries='tinfo ncurses terminfo curses termcap tinfow ncursesw'

  mingw32 | android)
    TERMINFO=no
    LIBS_TERMCAP=
    ;;

$opsys is apparently 'android' in the Termux build, derived from $host_os.

I got past this stumbling block by hand-editing the generated configure
file, taking out these two comparisons of $opsys with 'android'.

2) Then it fails later, while loading "version.el":
-------------------------------------------------------------------------------
./temacs --batch  -l loadup --temacs=pbootstrap \
        --bin-dest /data/data/com.termux/files/home/local/bin/ --eln-dest /data/data/com.termux/files/home/local/lib/emacs/30.0.50/
Loading loadup.el (source)...
Dump mode: pbootstrap
Using load-path (/data/data/com.termux/files/home/emacs/lisp /data/data/com.termux/files/home/emacs/lisp/emacs-lisp /data/data/com.termux/files/home/emacs/lisp/progmodes /data/data/com.termux/files/home/emacs/lisp/language /data/data/com.termux/files/home/emacs/lisp/international /data/data/com.termux/files/home/emacs/lisp/textmodes /data/data/com.termux/files/home/emacs/lisp/vc)
Loading emacs-lisp/debug-early (source)...
Loading emacs-lisp/byte-run (source)...
Loading emacs-lisp/backquote (source)...
Loading subr (source)...
Loading keymap (source)...
Loading version (source)...
Opening input file: No such file or directory, /assets/build_info

Error: file-missing ("Opening input file" "No such file or directory" "/assets/build_info")
  mapbacktrace((closure ((prin1 . prin1) t) (evald func args _flags) (let ((args args)) (if evald (progn (princ "  ") (funcall prin1 func) (princ "(")) (progn (princ "  (") (setq args (cons func args)))) (if args (while (progn (funcall prin1 (car args)) (setq args (cdr args))) (princ " "))) (princ ")\n"))))
  (let ((print-escape-newlines t) (print-escape-control-characters t) (print-escape-nonascii t) (prin1 (if (and (fboundp 'cl-prin1) (fboundp 'cl-defmethod) (condition-case nil (require 'cl-print) (error nil))) #'cl-prin1 #'prin1))) (mapbacktrace #'(lambda (evald func args _flags) (let ((args args)) (if evald (progn (princ "  ") (funcall prin1 func) (princ "(")) (progn (princ "  (") (setq args (cons func args)))) (if args (while (progn (funcall prin1 (car args)) (setq args (cdr args))) (princ " "))) (princ ")\n")))))
  debug-early-backtrace()
  debug-early(error (file-missing "Opening input file" "No such file or directory" "/assets/build_info"))
  insert-file-contents("/assets/build_info")
  (progn (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string)))
  (unwind-protect (progn (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))
  (save-current-buffer (set-buffer temp-buffer) (unwind-protect (progn (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (with-current-buffer temp-buffer (unwind-protect (progn (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer))))
  (let ((temp-buffer (generate-new-buffer " *temp*" t))) (with-current-buffer temp-buffer (unwind-protect (progn (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string))) (and (buffer-name temp-buffer) (kill-buffer temp-buffer)))))
  (with-temp-buffer (insert-file-contents "/assets/build_info") (let ((string (buffer-substring 1 (line-end-position)))) (and (not (equal string "Unknown")) string)))
  android-read-build-system()
  (and (eq system-type 'android) (android-read-build-system))
  (or (and (eq system-type 'android) (android-read-build-system)) (system-name))
  (defconst emacs-build-system (or (and (eq system-type 'android) (android-read-build-system)) (system-name)) "Name of the system on which Emacs was built, or nil if not available.")
  load("version")
  load("loadup.el")
make[2]: *** [Makefile:1012: bootstrap-emacs.pdmp] Error 255
make[2]: Leaving directory '/data/data/com.termux/files/home/emacs/src'
make[1]: *** [Makefile:554: src] Error 2
make[1]: Leaving directory '/data/data/com.termux/files/home/emacs'
make[1]: Entering directory '/data/data/com.termux/files/home/emacs'
***
*** "make all" failed with exit status 2.
-------------------------------------------------------------------------------

Looking at version.el, this looks like some
  (eq system-type 'android)
test that was meant for the Android GUI, now applying to the Android Termux
build.

3) I'll get to testing the "Error: permission-denied" from function
add-name-to-file only after I'm past the errors 1) and 2), since it comes
from a later point in loadup.el.

Bruno