gh-90005: Port readline and curses to PY_STDLIB_MOD (GH-94452)

Co-authored-by: Erlend Egeberg Aasland <erlend.aasland@protonmail.com>
This commit is contained in:
Christian Heimes 2022-07-06 11:56:25 +02:00 committed by GitHub
parent 50b9a7762f
commit e925241d95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 1943 additions and 458 deletions

View File

@ -0,0 +1,5 @@
Dependencies of :mod:`readline` and :mod:`curses` module are now detected in
``configure`` script with ``pkg-config``. Only ``ncurses`` / ``ncursesw``
are detected automatically. The old ``curses`` library is not configured
automatically. Workaround for missing ``termcap`` or ``tinfo`` library
has been removed.

View File

@ -72,8 +72,8 @@
# gdbm module needs -lgdbm
@MODULE__GDBM_TRUE@_gdbm _gdbmmodule.c
# needs -lreadline or -leditline, sometimes termcap, termlib, or tinfo
#@MODULE_READLINE_TRUE@readline readline.c
# needs -lreadline or -ledit, sometimes termcap, termlib, or tinfo
@MODULE_READLINE_TRUE@readline readline.c
# hashing builtins, can be disabled with --without-builtin-hashlib-hashes
@MODULE__MD5_TRUE@_md5 md5module.c
@ -138,10 +138,10 @@
# needs -lffi and -ldl
@MODULE__CTYPES_TRUE@_ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c @MODULE__CTYPES_MALLOC_CLOSURE@
# needs -lncurses, -lncursesw or -lcurses, sometimes -ltermcap
#@MODULE__CURSES_TRUE@_curses _cursesmodule.c
# needs -lncurses and -lpanel
#@MODULE__CURSES_PANEL_TRUE@_curses_panel _curses_panel.c
# needs -lncurses[w], sometimes -ltermcap/tinfo
@MODULE__CURSES_TRUE@_curses _cursesmodule.c
# needs -lncurses[w] and -lpanel[w]
@MODULE__CURSES_PANEL_TRUE@_curses_panel _curses_panel.c
@MODULE__SQLITE3_TRUE@_sqlite3 _sqlite/blob.c _sqlite/connection.c _sqlite/cursor.c _sqlite/microprotocols.c _sqlite/module.c _sqlite/prepare_protocol.c _sqlite/row.c _sqlite/statement.c _sqlite/util.c

1835
configure generated vendored

File diff suppressed because it is too large Load Diff

View File

@ -5780,127 +5780,169 @@ then
[Define this if you have flockfile(), getc_unlocked(), and funlockfile()])
fi
AC_ARG_WITH([readline],
[AS_HELP_STRING([--with(out)-readline@<:@=editline@:>@],
[use Editline for backend or disable readline module])],
[],
[with_readline=yes])
dnl Check for libreadline and libedit
dnl - libreadline provides "readline/readline.h" header and "libreadline"
dnl shared library. pkg-config file is readline.pc
dnl - libedit provides "editline/readline.h" header and "libedit" shared
dnl library. pkg-config file ins libedit.pc
dnl - editline is not supported ("readline.h" and "libeditline" shared library)
dnl
dnl NOTE: In the past we checked if readline needs an additional termcap
dnl library (tinfo ncursesw ncurses termcap). We now assume that libreadline
dnl or readline.pc provide correct linker information.
# check where readline lives
py_cv_lib_readline=no
# save the value of LIBS so we don't actually link Python with readline
LIBS_no_readline=$LIBS
AH_TEMPLATE([WITH_EDITLINE], [Define to build the readline module against libedit.])
if test "$with_readline" != no; then
case "$with_readline" in
editline|edit)
LIBREADLINE=edit
AC_DEFINE(WITH_EDITLINE, 1,
[Define to build the readline module against Editline.])
;;
yes|readline)
AC_ARG_WITH(
[readline],
[AS_HELP_STRING([--with(out)-readline@<:@=editline|readline|no@:>@],
[use libedit for backend or disable readline module])],
[
AS_CASE([$with_readline],
[editline|edit], [with_readline=edit],
[yes|readline], [with_readline=readline],
[no], [],
[AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline|readline|no@:>@])]
)
],
[with_readline=readline]
)
AS_VAR_IF([with_readline], [readline], [
PKG_CHECK_MODULES([LIBREADLINE], [readline], [
LIBREADLINE=readline
;;
*)
AC_MSG_ERROR([proper usage is --with(out)-readline@<:@=editline@:>@])
;;
esac
READLINE_CFLAGS=$LIBREADLINE_CFLAGS
READLINE_LIBS=$LIBREADLINE_LIBS
], [
AC_CHECK_HEADERS([readline/readline.h], [
WITH_SAVE_ENV([
AC_CHECK_LIB([readline], [readline], [
LIBREADLINE=readline
READLINE_CFLAGS=${LIBREADLINE_CFLAGS-""}
READLINE_LIBS=${LIBREADLINE_LIBS-"-lreadline"}
], [
with_readline=no
])
])
], [with_readline=no])
])
])
# On some systems we need to link readline to a termcap compatible
# library. NOTE: Keep the precedence of listed libraries synchronised
# with setup.py.
AC_MSG_CHECKING([how to link readline libs])
for py_libtermcap in "" tinfo ncursesw ncurses curses termcap; do
if test -z "$py_libtermcap"; then
READLINE_LIBS="-l$LIBREADLINE"
else
READLINE_LIBS="-l$LIBREADLINE -l$py_libtermcap"
fi
LIBS="$READLINE_LIBS $LIBS_no_readline"
AC_LINK_IFELSE(
[AC_LANG_CALL([],[readline])],
[py_cv_lib_readline=yes])
if test $py_cv_lib_readline = yes; then
break
fi
done
AS_VAR_IF([with_readline], [edit], [
PKG_CHECK_MODULES([LIBEDIT], [libedit], [
AC_DEFINE([WITH_EDITLINE], [1])
LIBREADLINE=edit
READLINE_CFLAGS=$LIBEDIT_CFLAGS
READLINE_LIBS=$LIBEDIT_LIBS
], [
AC_CHECK_HEADERS([editline/readline.h], [
WITH_SAVE_ENV([
AC_CHECK_LIB([edit], [readline], [
LIBREADLINE=edit
AC_DEFINE([WITH_EDITLINE], [1])
READLINE_CFLAGS=${LIBEDIT_CFLAGS-""}
READLINE_LIBS=${LIBEDIT_LIBS-"-ledit"}
], [
with_readline=no
])
])
], [with_readline=no])
])
])
# Uncomment this line if you want to use READLINE_LIBS in Makefile or scripts
#AC_SUBST([READLINE_LIBS])
if test $py_cv_lib_readline = no; then
AC_MSG_RESULT([none])
else
AC_MSG_RESULT([$READLINE_LIBS])
AC_DEFINE(HAVE_LIBREADLINE, 1,
[Define to build the readline module.])
fi
fi
if test "$py_cv_lib_readline" = yes; then
# check for readline 2.2
AC_CHECK_DECL(rl_completion_append_character,
AC_DEFINE(HAVE_RL_COMPLETION_APPEND_CHARACTER, 1,
[Define if you have readline 2.2]),,
[
#include <stdio.h> /* Must be first for Gnu Readline */
#ifdef WITH_EDITLINE
# include <editline/readline.h>
#else
# include <readline/readline.h>
#endif
])
AC_CHECK_DECL(rl_completion_suppress_append,
AC_DEFINE(HAVE_RL_COMPLETION_SUPPRESS_APPEND, 1,
[Define if you have rl_completion_suppress_append]),,
[
#include <stdio.h> /* Must be first for Gnu Readline */
#ifdef WITH_EDITLINE
# include <editline/readline.h>
#else
# include <readline/readline.h>
#endif
AC_MSG_CHECKING([how to link readline])
AS_VAR_IF([with_readline], [no], [
AC_MSG_RESULT([no])
], [
AC_MSG_RESULT([$with_readline (CFLAGS: $READLINE_CFLAGS, LIBS: $READLINE_LIBS)])
WITH_SAVE_ENV([
CPPFLAGS="$READLINE_CFLAGS $CFLAGS"
LIBS="$READLINE_LIBS $LIBS"
LIBS_SAVE=$LIBS
m4_define([readline_includes], [
#include <stdio.h> /* Must be first for Gnu Readline */
#ifdef WITH_EDITLINE
# include <editline/readline.h>
#else
# include <readline/readline.h>
# include <readline/history.h>
#endif
])
# check for readline 4.0
AC_CHECK_LIB($LIBREADLINE, rl_pre_input_hook,
AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK, 1,
[Define if you have readline 4.0]),,$READLINE_LIBS)
# check for readline 2.2
AC_CHECK_DECL([rl_completion_append_character], [
AC_DEFINE([HAVE_RL_COMPLETION_APPEND_CHARACTER], [1], [Define if you have readline 2.2])
], [], [readline_includes])
# also in 4.0
AC_CHECK_LIB($LIBREADLINE, rl_completion_display_matches_hook,
AC_DEFINE(HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK, 1,
[Define if you have readline 4.0]),,$READLINE_LIBS)
AC_CHECK_DECL([rl_completion_suppress_append], [
AC_DEFINE([HAVE_RL_COMPLETION_SUPPRESS_APPEND], [1], [Define if you have rl_completion_suppress_append])
], [], [readline_includes])
# also in 4.0, but not in editline
AC_CHECK_LIB($LIBREADLINE, rl_resize_terminal,
AC_DEFINE(HAVE_RL_RESIZE_TERMINAL, 1,
[Define if you have readline 4.0]),,$READLINE_LIBS)
# check for readline 4.2
AC_CHECK_LIB($LIBREADLINE, rl_completion_matches,
AC_DEFINE(HAVE_RL_COMPLETION_MATCHES, 1,
[Define if you have readline 4.2]),,$READLINE_LIBS)
# also in readline 4.2
AC_CHECK_DECL(rl_catch_signals,
AC_DEFINE(HAVE_RL_CATCH_SIGNAL, 1,
[Define if you can turn off readline's signal handling.]),,
[
#include <stdio.h> /* Must be first for Gnu Readline */
#ifdef WITH_EDITLINE
# include <editline/readline.h>
#else
# include <readline/readline.h>
#endif
# check for readline 4.0
AC_CACHE_CHECK([for rl_pre_input_hook in -l$LIBREADLINE], [ac_cv_readline_rl_pre_input_hook], [
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([readline_includes], [void *x = rl_pre_input_hook])],
[ac_cv_readline_rl_pre_input_hook=yes], [ac_cv_readline_rl_pre_input_hook=no]
)
])
AS_VAR_IF([ac_cv_readline_rl_pre_input_hook], [yes], [
AC_DEFINE([HAVE_RL_PRE_INPUT_HOOK], [1], [Define if you have readline 4.0])
])
AC_CHECK_LIB($LIBREADLINE, append_history,
AC_DEFINE(HAVE_RL_APPEND_HISTORY, 1,
[Define if readline supports append_history]),,$READLINE_LIBS)
fi
# also in 4.0
AC_CACHE_CHECK([for rl_completion_display_matches_hook in -l$LIBREADLINE], [ac_cv_readline_rl_completion_display_matches_hook], [
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_display_matches_hook])],
[ac_cv_readline_rl_completion_display_matches_hook=yes], [ac_cv_readline_rl_completion_display_matches_hook=no]
)
])
AS_VAR_IF([ac_cv_readline_rl_completion_display_matches_hook], [yes], [
AC_DEFINE([HAVE_RL_COMPLETION_DISPLAY_MATCHES_HOOK], [1], [Define if you have readline 4.0])
])
# End of readline checks: restore LIBS
LIBS=$LIBS_no_readline
# also in 4.0, but not in editline
AC_CACHE_CHECK([for rl_resize_terminal in -l$LIBREADLINE], [ac_cv_readline_rl_resize_terminal], [
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([readline_includes], [void *x = rl_resize_terminal])],
[ac_cv_readline_rl_resize_terminal=yes], [ac_cv_readline_rl_resize_terminal=no]
)
])
AS_VAR_IF([ac_cv_readline_rl_resize_terminal], [yes], [
AC_DEFINE([HAVE_RL_RESIZE_TERMINAL], [1], [Define if you have readline 4.0])
])
# check for readline 4.2
AC_CACHE_CHECK([for rl_completion_matches in -l$LIBREADLINE], [ac_cv_readline_rl_completion_matches], [
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([readline_includes], [void *x = rl_completion_matches])],
[ac_cv_readline_rl_completion_matches=yes], [ac_cv_readline_rl_completion_matches=no]
)
])
AS_VAR_IF([ac_cv_readline_rl_completion_matches], [yes], [
AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1], [Define if you have readline 4.2])
])
# also in readline 4.2
AC_CHECK_DECL([rl_catch_signals], [
AC_DEFINE([HAVE_RL_CATCH_SIGNAL], [1], [Define if you can turn off readline's signal handling.])
], [], [readline_includes])
AC_CACHE_CHECK([for append_history in -l$LIBREADLINE], [ac_cv_readline_append_history], [
AC_LINK_IFELSE(
[AC_LANG_PROGRAM([readline_includes], [void *x = append_history])],
[ac_cv_readline_append_history=yes], [ac_cv_readline_append_history=no]
)
])
AS_VAR_IF([ac_cv_readline_append_history], [yes], [
AC_DEFINE([HAVE_RL_APPEND_HISTORY], [1], [Define if readline supports append_history])
])
m4_undefine([readline_includes])
])dnl WITH_SAVE_ENV()
])
AC_CACHE_CHECK([for broken nice()], [ac_cv_broken_nice], [
AC_RUN_IFELSE([AC_LANG_SOURCE([[
@ -6056,14 +6098,124 @@ then
[Define if you have struct stat.st_mtimensec])
fi
dnl check for ncurses/ncursesw and panel/panelw
dnl NOTE: old curses is not detected.
dnl have_curses=[no, ncursesw, ncurses]
dnl have_panel=[no, panelw, panel]
have_curses=no
have_panel=no
AH_TEMPLATE([HAVE_NCURSESW], [Define to 1 if you have the `ncursesw' library.])
AC_CHECK_HEADERS([curses.h ncurses.h])
AS_VAR_IF([ac_cv_header_ncurses_h], [yes], [
if test "$ac_sys_system" != "Darwin"; then
dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
PKG_CHECK_MODULES([CURSES], [ncursesw], [
have_curses=ncursesw
], [
WITH_SAVE_ENV([
AC_CHECK_LIB([ncursesw], [initscr], [
AC_DEFINE([HAVE_NCURSESW], [1])
have_curses=ncursesw
CURSES_CFLAGS=${CURSES_CFLAGS-""}
CURSES_LIBS=${CURSES_LIBS-"-lncursesw"}
])
])
])
fi
AS_VAR_IF([have_curses], [no], [
PKG_CHECK_MODULES([CURSES], [ncurses], [
have_curses=ncurses
], [
WITH_SAVE_ENV([
AC_CHECK_LIB([ncurses], [initscr], [
have_curses=ncurses
CURSES_CFLAGS=${CURSES_CFLAGS-""}
CURSES_LIBS=${CURSES_LIBS-"-lncurses"}
])
])
])
])
])dnl ac_cv_header_ncurses_h = yes
dnl remove _XOPEN_SOURCE macro from curses cflags. pyconfig.h sets
dnl the macro to 700.
CURSES_CFLAGS=$(echo $CURSES_CFLAGS | sed 's/-D_XOPEN_SOURCE=600//')
if test "$have_curses" = no -a "$ac_sys_system" = "Darwin"; then
dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
dnl If we are here, we found a locally-supplied version of libncursesw.
dnl There should also be a libpanelw.
dnl _XOPEN_SOURCE defines are usually excluded for macOS, but we need
dnl _XOPEN_SOURCE_EXTENDED here for ncurses wide char support.
AS_VAR_APPEND([CURSES_CFLAGS], [" -D_XOPEN_SOURCE_EXTENDED=1"])
AC_DEFINE([HAVE_NCURSESW], [1])
fi
dnl TODO: detect "curses" and special cases tinfo, terminfo, or termcap
AC_MSG_CHECKING([curses module flags])
AS_VAR_IF([have_curses], [no], [
AC_MSG_RESULT([no])
], [
AC_MSG_RESULT([$have_curses (CFLAGS: $CURSES_CFLAGS, LIBS: $CURSES_LIBS)])
])
dnl check for ncurses' panel/panelw library
AC_CHECK_HEADERS([panel.h])
AS_VAR_IF([ac_cv_header_panel_h], [yes], [
if test "$ac_sys_system" != "Darwin"; then
dnl On macOS, there is no separate /usr/lib/libncursesw nor libpanelw.
AS_VAR_IF([have_curses], [ncursesw], [
PKG_CHECK_MODULES([PANEL], [panelw], [
have_panel=panelw
], [
WITH_SAVE_ENV([
AC_CHECK_LIB([panelw], [update_panels], [
have_panel=panelw
PANEL_CFLAGS=${PANEL_CFLAGS-""}
PANEL_LIBS=${PANEL_LIBS-"-lpanelw"}
])
])
])
])
fi
AS_VAR_IF([have_curses], [ncurses], [
PKG_CHECK_MODULES([PANEL], [panel], [
have_panel=panel
], [
WITH_SAVE_ENV([
AC_CHECK_LIB([panel], [update_panels], [
have_panel=panel
PANEL_CFLAGS=${PANEL_CFLAGS-""}
PANEL_LIBS=${PANEL_LIBS-"-lpanel"}
])
])
])
])
])dnl ac_cv_header_panel_h = yes
AC_MSG_CHECKING([panel flags])
AS_VAR_IF([have_panel], [no], [
AC_MSG_RESULT([no])
], [
AC_MSG_RESULT([$have_panel (CFLAGS: $PANEL_CFLAGS, LIBS: $PANEL_LIBS)])
])
# first curses header check
ac_save_cppflags="$CPPFLAGS"
if test "$cross_compiling" = no; then
CPPFLAGS="$CPPFLAGS -I/usr/include/ncursesw"
fi
AC_CHECK_HEADERS(curses.h ncurses.h)
# On Solaris, term.h requires curses.h
AC_CHECK_HEADERS(term.h,,,[
#ifdef HAVE_CURSES_H
@ -6985,8 +7137,14 @@ PY_STDLIB_MOD([_crypt],
PY_STDLIB_MOD([_ctypes],
[], [test "$have_libffi" = yes],
[$LIBFFI_CFLAGS], [$LIBFFI_LIBS])
dnl PY_STDLIB_MOD([_curses], [], [], [], [])
dnl PY_STDLIB_MOD([_curses_panel], [], [], [], [])
PY_STDLIB_MOD([_curses],
[], [test "$have_curses" != "no"],
[$CURSES_CFLAGS], [$CURSES_LIBS]
)
PY_STDLIB_MOD([_curses_panel],
[], [test "$have_panel" != "no"],
[$PANEL_CFLAGS $CURSES_CFLAGS], [$PANEL_LIBS $CURSES_LIBS]
)
PY_STDLIB_MOD([_decimal], [], [], [$LIBMPDEC_CFLAGS], [$LIBMPDEC_LDFLAGS])
PY_STDLIB_MOD([_dbm],
[test -n "$with_dbmliborder"], [test "$have_dbm" != "no"],
@ -6997,7 +7155,9 @@ PY_STDLIB_MOD([_gdbm],
PY_STDLIB_MOD([nis],
[], [test "$have_nis" = yes -a "$ac_cv_header_rpc_rpc_h" = yes],
[$LIBNSL_CFLAGS], [$LIBNSL_LIBS])
dnl PY_STDLIB_MOD([readline], [], [], [], [])
PY_STDLIB_MOD([readline],
[], [test "$with_readline" != "no"],
[$READLINE_CFLAGS], [$READLINE_LIBS])
PY_STDLIB_MOD([_sqlite3],
[test "$have_sqlite3" = "yes"],
[test "$have_supported_sqlite3" = "yes"],

View File

@ -290,6 +290,9 @@
/* Defined when any dynamic module loading is enabled. */
#undef HAVE_DYNAMIC_LOADING
/* Define to 1 if you have the <editline/readline.h> header file. */
#undef HAVE_EDITLINE_READLINE_H
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
@ -646,9 +649,6 @@
/* Define to 1 if you have the <libintl.h> header file. */
#undef HAVE_LIBINTL_H
/* Define to build the readline module. */
#undef HAVE_LIBREADLINE
/* Define to 1 if you have the `resolv' library (-lresolv). */
#undef HAVE_LIBRESOLV
@ -784,6 +784,9 @@
/* Define to 1 if you have the `nanosleep' function. */
#undef HAVE_NANOSLEEP
/* Define to 1 if you have the `ncursesw' library. */
#undef HAVE_NCURSESW
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
@ -821,6 +824,9 @@
/* Define to 1 if you have the `openpty' function. */
#undef HAVE_OPENPTY
/* Define to 1 if you have the <panel.h> header file. */
#undef HAVE_PANEL_H
/* Define to 1 if you have the `pathconf' function. */
#undef HAVE_PATHCONF
@ -905,6 +911,9 @@
/* Define to 1 if you have the `pwritev2' function. */
#undef HAVE_PWRITEV2
/* Define to 1 if you have the <readline/readline.h> header file. */
#undef HAVE_READLINE_READLINE_H
/* Define to 1 if you have the `readlink' function. */
#undef HAVE_READLINK
@ -1662,7 +1671,7 @@
Dyld is necessary to support frameworks. */
#undef WITH_DYLD
/* Define to build the readline module against Editline. */
/* Define to build the readline module against libedit. */
#undef WITH_EDITLINE
/* Define if you want to compile in object freelists optimization */

146
setup.py
View File

@ -1015,149 +1015,9 @@ class PyBuildExt(build_ext):
))
def detect_readline_curses(self):
# readline
readline_termcap_library = ""
curses_library = ""
# Cannot use os.popen here in py3k.
tmpfile = os.path.join(self.build_temp, 'readline_termcap_lib')
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
# Determine if readline is already linked against curses or tinfo.
if sysconfig.get_config_var('HAVE_LIBREADLINE'):
if sysconfig.get_config_var('WITH_EDITLINE'):
readline_lib = 'edit'
else:
readline_lib = 'readline'
do_readline = self.compiler.find_library_file(self.lib_dirs,
readline_lib)
if CROSS_COMPILING:
ret = run_command("%s -d %s | grep '(NEEDED)' > %s"
% (sysconfig.get_config_var('READELF'),
do_readline, tmpfile))
elif find_executable('ldd'):
ret = run_command("ldd %s > %s" % (do_readline, tmpfile))
else:
ret = 1
if ret == 0:
with open(tmpfile) as fp:
for ln in fp:
if 'curses' in ln:
readline_termcap_library = re.sub(
r'.*lib(n?cursesw?)\.so.*', r'\1', ln
).rstrip()
break
# termcap interface split out from ncurses
if 'tinfo' in ln:
readline_termcap_library = 'tinfo'
break
if os.path.exists(tmpfile):
os.unlink(tmpfile)
else:
do_readline = False
# Issue 7384: If readline is already linked against curses,
# use the same library for the readline and curses modules.
if 'curses' in readline_termcap_library:
curses_library = readline_termcap_library
elif self.compiler.find_library_file(self.lib_dirs, 'ncursesw'):
curses_library = 'ncursesw'
# Issue 36210: OSS provided ncurses does not link on AIX
# Use IBM supplied 'curses' for successful build of _curses
elif AIX and self.compiler.find_library_file(self.lib_dirs, 'curses'):
curses_library = 'curses'
elif self.compiler.find_library_file(self.lib_dirs, 'ncurses'):
curses_library = 'ncurses'
elif self.compiler.find_library_file(self.lib_dirs, 'curses'):
curses_library = 'curses'
if MACOS:
os_release = int(os.uname()[2].split('.')[0])
dep_target = sysconfig.get_config_var('MACOSX_DEPLOYMENT_TARGET')
if (dep_target and
(tuple(int(n) for n in dep_target.split('.')[0:2])
< (10, 5) ) ):
os_release = 8
if os_release < 9:
# MacOSX 10.4 has a broken readline. Don't try to build
# the readline module unless the user has installed a fixed
# readline package
if find_file('readline/rlconf.h', self.inc_dirs, []) is None:
do_readline = False
if do_readline:
readline_libs = [readline_lib]
if readline_termcap_library:
pass # Issue 7384: Already linked against curses or tinfo.
elif curses_library:
readline_libs.append(curses_library)
elif self.compiler.find_library_file(self.lib_dirs +
['/usr/lib/termcap'],
'termcap'):
readline_libs.append('termcap')
self.add(Extension('readline', ['readline.c'],
library_dirs=['/usr/lib/termcap'],
libraries=readline_libs))
else:
self.missing.append('readline')
# Curses support, requiring the System V version of curses, often
# provided by the ncurses library.
curses_defines = []
curses_includes = []
panel_library = 'panel'
if curses_library == 'ncursesw':
curses_defines.append(('HAVE_NCURSESW', '1'))
if not CROSS_COMPILING:
curses_includes.append('/usr/include/ncursesw')
# Bug 1464056: If _curses.so links with ncursesw,
# _curses_panel.so must link with panelw.
panel_library = 'panelw'
if MACOS:
# On OS X, there is no separate /usr/lib/libncursesw nor
# libpanelw. If we are here, we found a locally-supplied
# version of libncursesw. There should also be a
# libpanelw. _XOPEN_SOURCE defines are usually excluded
# for OS X but we need _XOPEN_SOURCE_EXTENDED here for
# ncurses wide char support
curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1'))
elif MACOS and curses_library == 'ncurses':
# Building with the system-suppied combined libncurses/libpanel
curses_defines.append(('HAVE_NCURSESW', '1'))
curses_defines.append(('_XOPEN_SOURCE_EXTENDED', '1'))
curses_enabled = True
if curses_library.startswith('ncurses'):
curses_libs = [curses_library]
self.add(Extension('_curses', ['_cursesmodule.c'],
include_dirs=curses_includes,
define_macros=curses_defines,
libraries=curses_libs))
elif curses_library == 'curses' and not MACOS:
# OSX has an old Berkeley curses, not good enough for
# the _curses module.
if (self.compiler.find_library_file(self.lib_dirs, 'terminfo')):
curses_libs = ['curses', 'terminfo']
elif (self.compiler.find_library_file(self.lib_dirs, 'termcap')):
curses_libs = ['curses', 'termcap']
else:
curses_libs = ['curses']
self.add(Extension('_curses', ['_cursesmodule.c'],
define_macros=curses_defines,
libraries=curses_libs))
else:
curses_enabled = False
self.missing.append('_curses')
# If the curses module is enabled, check for the panel module
# _curses_panel needs some form of ncurses
skip_curses_panel = True if AIX else False
if (curses_enabled and not skip_curses_panel and
self.compiler.find_library_file(self.lib_dirs, panel_library)):
self.add(Extension('_curses_panel', ['_curses_panel.c'],
include_dirs=curses_includes,
define_macros=curses_defines,
libraries=[panel_library, *curses_libs]))
elif not skip_curses_panel:
self.missing.append('_curses_panel')
self.addext(Extension('readline', ['readline.c']))
self.addext(Extension('_curses', ['_cursesmodule.c']))
self.addext(Extension('_curses_panel', ['_curses_panel.c']))
def detect_crypt(self):
self.addext(Extension('_crypt', ['_cryptmodule.c']))