Skip to content

Commit 5246d4e

Browse files
committed
unix: rework terminfo database handling
Before, ncurses on Linux was built to look for the terminfo database in a location that only existed in the build environment After, it looks for the database in `/etc/terminfo`, `/lib/terminfo`, and `/usr/share/terminfo`. These are the directory locations that work on a superset of Debian and RedHat. This hopefully means that terminfo database resolution "just works" in a lot of common Linux environments. As part of this, we add the terminfo database to the ncurses package artifacts. Then we copy the terminfo database into `install/share/terminfo` in the CPython distribution if a terminfo database is present. macOS doesn't distribute a terminfo database because the system terminfo database should be "good enough." Plus we don't build ncurses on macOS distributions. Closes #215.
1 parent ef75ffd commit 5246d4e

File tree

3 files changed

+73
-3
lines changed

3 files changed

+73
-3
lines changed

cpython-unix/build-cpython.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -884,6 +884,11 @@ if [ -d "${TOOLS_PATH}/deps/lib/tcl8" ]; then
884884
fi
885885
fi
886886

887+
# Copy the terminfo database if present.
888+
if [ -d "${TOOLS_PATH}/deps/usr/share/terminfo" ]; then
889+
cp -av ${TOOLS_PATH}/deps/usr/share/terminfo ${ROOT}/out/python/install/share/
890+
fi
891+
887892
# config.c defines _PyImport_Inittab and extern references to modules, which
888893
# downstream consumers may want to strip. We bundle config.c and config.c.in so
889894
# a custom one can be produced downstream.

cpython-unix/build-ncurses.sh

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@ if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then
2020
echo "building host ncurses to provide modern tic for cross-compile"
2121

2222
pushd ncurses-${NCURSES_VERSION}
23-
CC="${HOST_CC}" ./configure --prefix=${TOOLS_PATH}/host --without-cxx --without-tests --without-manpages --enable-widec
23+
24+
CC="${HOST_CC}" ./configure \
25+
--prefix=${TOOLS_PATH}/host \
26+
--without-cxx \
27+
--without-tests \
28+
--without-manpages \
29+
--enable-widec \
30+
--disable-db-install \
31+
--enable-symlinks
2432
make -j ${NUM_CPUS}
2533
make -j ${NUM_CPUS} install
2634

@@ -38,6 +46,10 @@ pushd ncurses-${NCURSES_VERSION}
3846
# recognize the target architecture. We could fix this by overriding strip.
3947
# But we don't care about the installed binaries, so we simply disable
4048
# stripping of the binaries.
49+
# --enable-symlinks is needed to force use of symbolic links in the terminfo
50+
# database. By default hardlinks are used, which are wonky to tar up. Be sure
51+
# this is set on the host native `tic` build above, as it is the entity writing
52+
# symlinks!
4153
CONFIGURE_FLAGS="
4254
--build=${BUILD_TRIPLE}
4355
--host=${TARGET_TRIPLE}
@@ -46,7 +58,9 @@ CONFIGURE_FLAGS="
4658
--without-tests
4759
--without-manpages
4860
--disable-stripping
49-
--enable-widec"
61+
--enable-widec
62+
--enable-symlinks
63+
"
5064

5165
# ncurses wants --with-build-cc when cross-compiling. But it insists on CC
5266
# and this value not being equal, even though using the same binary with
@@ -55,17 +69,48 @@ if [[ -n "${CROSS_COMPILING}" && "${PYBUILD_PLATFORM}" != "macos" ]]; then
5569
CONFIGURE_FLAGS="${CONFIGURE_FLAGS} --with-build-cc=$(which "${HOST_CC}")"
5670
fi
5771

72+
# The terminfo database exists as a set of standalone files. The absolute
73+
# paths to these files need to be hardcoded into the binary at build time.
74+
#
75+
# Since our final distributions are "relocatable," the absolute path of the
76+
# terminfo database can't be known at build time: there needs to be something
77+
# that sniffs for well-known directories and attempts to locate it. Ideally
78+
# that could find the terminfo database that we ship!
79+
#
80+
# All is not lost, however.
81+
#
82+
# On macOS, the system terminfo database location is well known: /usr/share/terminfo.
83+
#
84+
# On Linux, common distributions tend to place the terminfo database in only a
85+
# few well-known locations. We define default search paths that overlap with
86+
# Debian and RedHat distros. This often results in at least a partially working
87+
# terminfo lookup in most Linux environments.
88+
#
89+
# configure appears to use --with-default-terminfo-dir for both a) where to
90+
# install the terminfo database to b) default TERMINFO value compiled into the
91+
# binary. So we provide a suitable runtime value and then move files at install
92+
# time.
93+
5894
if [ "${PYBUILD_PLATFORM}" = "macos" ]; then
5995
CONFIGURE_FLAGS="${CONFIGURE_FLAGS}
6096
--datadir=/usr/share
6197
--sysconfdir=/etc
6298
--sharedstatedir=/usr/com
99+
--with-default-terminfo-dir=/usr/share/terminfo
63100
--with-terminfo-dirs=/usr/share/terminfo
101+
"
102+
else
103+
CONFIGURE_FLAGS="${CONFIGURE_FLAGS}
104+
--datadir=/tools/deps/usr/share
105+
--sysconfdir=/tools/deps/etc
106+
--sharedstatedir=/tools/deps/usr/com
64107
--with-default-terminfo-dir=/usr/share/terminfo
65-
--disable-db-install
108+
--with-terminfo-dirs=/etc/terminfo:/lib/terminfo:/usr/share/terminfo
66109
"
67110
fi
68111

69112
CFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" CPPFLAGS="${EXTRA_TARGET_CFLAGS} -fPIC" LDFLAGS="${EXTRA_TARGET_LDFLAGS}" ./configure ${CONFIGURE_FLAGS}
70113
make -j ${NUM_CPUS}
71114
make -j ${NUM_CPUS} install DESTDIR=${ROOT}/out
115+
116+
mv ${ROOT}/out/usr/share/terminfo ${ROOT}/out/tools/deps/usr/share/

docs/quirks.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ If you attempt to run ``python`` and the backspace key doesn't
1313
erase characters or the arrow keys don't work as expected, this
1414
is because the executable can't find the *terminfo database*.
1515

16+
A telltale sign of this is the Python REPL printing the following
17+
on startup::
18+
19+
Cannot read termcap database;
20+
using dumb terminal settings.
21+
1622
When you type a special key like the backspace key, this is
1723
registered as a key press. There is special software (typically
1824
``readline`` or ``libedit``) that most interactive programs use
@@ -60,6 +66,20 @@ The macOS distributions built with this project should automatically
6066
use the terminfo database in ``/usr/share/terminfo``. Please file
6167
a bug report if the macOS distributions do not behave as expected.
6268

69+
Starting in the first release after 20240107, the Linux distributions are
70+
configured to automatically use the terminfo database in ``/etc/terminfo``,
71+
``/lib/terminfo``, and ``/usr/share/terminfo``.
72+
73+
Also starting in the first release after 20240107, the terminfo database
74+
is distributed in the ``share/terminfo`` directory (``../../share/terminfo``
75+
relative to the ``bin/python3`` executable) in Linux distributions. Note
76+
that ncurses and derived libraries don't know how to find this directory
77+
since they are configured to use absolute paths to the terminfo database
78+
and the absolute path of the Python distribution is obviously not known
79+
at build time! So actually using this bundled terminfo database will
80+
require custom code setting ``TERMINFO_DIRS`` before
81+
ncurses/libedit/readline are loaded.
82+
6383
.. _quirk_tcl:
6484

6585
Tcl/tk Support Files

0 commit comments

Comments
 (0)