From c05ac6085155b143359c87cd3d6da59d4885729f Mon Sep 17 00:00:00 2001 From: "Darryl L. Miles" Date: Thu, 23 Jul 2026 16:17:20 +0000 Subject: [PATCH] build: require system readline (or Tcl); drop the bundled fallback (Patch 1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit configure already preferred the system readline (AC_CHECK_LIB → -lreadline) and only fell back to the bundled readline/ copy. Remove that fallback: a non-Tcl interactive build now requires the *system* GNU readline -- both its header (AC_CHECK_HEADER readline/readline.h, so configure fails cleanly instead of deep in compilation) and the library -- and if neither Tcl nor readline is available configure errors with a clear explanation of the three ways forward (build with Tcl, install libreadline-dev, or --disable-readline). Also drop the now-meaningless --enable-readline-bundled, and substitute MAKE_READLINE=0 unconditionally so the Makefiles' bundled-readline path goes inert. readline/ and all Makefiles are left untouched here (cleaned up and removed in the following patches). --disable-readline stays as the escape hatch: it just tells configure to ignore the system readline and build the existing no-line-editing variant. Verified: Tcl build rc=0 (readline off, 375 files, readline/ not built); non-Tcl --disable-readline builds (serial); non-Tcl default with no readline dev package now errors with the guidance message. Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/canary-matrix.yml | 5 + scripts/configure | 148 +++++++--------------------- scripts/configure.in | 73 +++++--------- 3 files changed, 63 insertions(+), 163 deletions(-) diff --git a/.github/workflows/canary-matrix.yml b/.github/workflows/canary-matrix.yml index 65e89bad..e6263e6a 100644 --- a/.github/workflows/canary-matrix.yml +++ b/.github/workflows/canary-matrix.yml @@ -153,6 +153,11 @@ jobs: # _configure_args=() + # "none" installs no dev packages (no libreadline-dev among them). Since + # configure now requires system readline for a non-Tcl build (unless told + # otherwise), the minimal "none" build must pass --disable-readline. + if [ "${MATRIX_PKGS}" = "none" ]; then + _configure_args+=(--disable-readline); fi if echo -n "$MATRIX_PKGS" | grep -q "^no.*_zl"; then _configure_args+=(--disable-compression); fi if echo -n "$MATRIX_PKGS" | grep -q "^no.*_brl"; then diff --git a/scripts/configure b/scripts/configure index 3015e22e..f136d07e 100755 --- a/scripts/configure +++ b/scripts/configure @@ -793,7 +793,6 @@ enable_framebuffer_backing_store enable_plot enable_lef enable_readline -enable_readline_bundled enable_threads enable_route enable_rsim @@ -1447,8 +1446,8 @@ Optional Features: --disable-framebuffer-backing-store disable OpenGL framebuffer backing store --disable-plot disable plot package --disable-lef disable LEF package - --disable-readline disable readline package - --enable-readline-bundled enable readline bundled package + --disable-readline do not use the system readline library even if + it is present (build without command-line editing) --disable-threads disable threaded graphics --disable-route disable routing package --disable-rsim disable IRSIM tool @@ -8241,24 +8240,18 @@ else fi -use_system_readline=yes -use_bundled_readline=auto +if test "x$enable_readline" = "xyes" ; then + $as_echo "#define USE_READLINE 1" >>confdefs.h -# Check whether --enable-readline-bundled was given. -if test "${enable_readline_bundled+set}" = set; then : - enableval=$enable_readline_bundled; use_bundled_readline=yes + use_system_readline=yes + ac_fn_c_check_header_mongrel "$LINENO" "readline/readline.h" "ac_cv_header_readline_readline_h" "$ac_includes_default" +if test "x$ac_cv_header_readline_readline_h" = xyes; then : else - - use_bundled_readline=no - + use_system_readline=no fi -if test "x$enable_readline" = "xyes" ; then - $as_echo "#define USE_READLINE 1" >>confdefs.h - - if test $use_bundled_readline != yes ; then { $as_echo "$as_me:${as_lineno-$LINENO}: checking for rl_pre_input_hook in -lreadline" >&5 $as_echo_n "checking for rl_pre_input_hook in -lreadline... " >&6; } if ${ac_cv_lib_readline_rl_pre_input_hook+:} false; then : @@ -8296,7 +8289,11 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_pre_input_hook" >&5 $as_echo "$ac_cv_lib_readline_rl_pre_input_hook" >&6; } if test "x$ac_cv_lib_readline_rl_pre_input_hook" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBREADLINE 1 +_ACEOF + LIBS="-lreadline $LIBS" else use_system_readline=no @@ -8339,7 +8336,11 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_username_completion_function" >&5 $as_echo "$ac_cv_lib_readline_rl_username_completion_function" >&6; } if test "x$ac_cv_lib_readline_rl_username_completion_function" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBREADLINE 1 +_ACEOF + LIBS="-lreadline $LIBS" else use_system_readline=no @@ -8382,7 +8383,11 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_filename_completion_function" >&5 $as_echo "$ac_cv_lib_readline_rl_filename_completion_function" >&6; } if test "x$ac_cv_lib_readline_rl_filename_completion_function" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBREADLINE 1 +_ACEOF + LIBS="-lreadline $LIBS" else use_system_readline=no @@ -8425,115 +8430,30 @@ fi { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_rl_attempted_completion_over" >&5 $as_echo "$ac_cv_lib_readline_rl_attempted_completion_over" >&6; } if test "x$ac_cv_lib_readline_rl_attempted_completion_over" = xyes; then : + cat >>confdefs.h <<_ACEOF +#define HAVE_LIBREADLINE 1 +_ACEOF + LIBS="-lreadline $LIBS" else use_system_readline=no fi - fi - if test $use_system_readline = yes && test $use_bundled_readline != yes; then + if test $use_system_readline = yes ; then $as_echo "#define HAVE_READLINE 1" >>confdefs.h rl_libs="-lreadline" - use_bundled_readline= else - echo "Using bundled readline" - $as_echo "#define NEED_READLINE 1" >>confdefs.h + as_fn_error $? "no usable GNU readline library found. - # not readline/libhistory.a (seems subset of libreadline.a) - rl_libs="\${MAGICDIR}/readline/libreadline.a" - CPPFLAGS="$CPPFLAGS -I\${MAGICDIR}/readline" - use_bundled_readline=1 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -ltermcap" >&5 -$as_echo_n "checking for tgetent in -ltermcap... " >&6; } -if ${ac_cv_lib_termcap_tgetent+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ltermcap $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char tgetent (); -int -main () -{ -return tgetent (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_termcap_tgetent=yes -else - ac_cv_lib_termcap_tgetent=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_termcap_tgetent" >&5 -$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } -if test "x$ac_cv_lib_termcap_tgetent" = xyes; then : - - rl_libs="$rl_libs -ltermcap" - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tgetent in -lncurses" >&5 -$as_echo_n "checking for tgetent in -lncurses... " >&6; } -if ${ac_cv_lib_ncurses_tgetent+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lncurses $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char tgetent (); -int -main () -{ -return tgetent (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_ncurses_tgetent=yes -else - ac_cv_lib_ncurses_tgetent=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ncurses_tgetent" >&5 -$as_echo "$ac_cv_lib_ncurses_tgetent" >&6; } -if test "x$ac_cv_lib_ncurses_tgetent" = xyes; then : - - rl_libs="$rl_libs -lncurses" - -fi - - -fi - - modules="$modules readline" +magic needs either Tcl/Tk (recommended) or the system GNU readline development +package to build an interactive non-Tcl version. Please do one of: + * build with Tcl/Tk (the default when Tcl is installed); or + * install the readline development package (e.g. libreadline-dev on Debian/ + Ubuntu, readline-devel on Fedora/RHEL, or 'brew install readline'); or + * re-run configure with --disable-readline to build without command-line + editing." "$LINENO" 5 fi else unused="$unused readline" @@ -9582,7 +9502,7 @@ MAKE_GLU=$usingGLU MAKE_CAIRO=$usingCairo -MAKE_READLINE=$use_bundled_readline +MAKE_READLINE=0 ac_config_files="$ac_config_files Makefile:Makefile.in" diff --git a/scripts/configure.in b/scripts/configure.in index e275ba52..e2e78c23 100644 --- a/scripts/configure.in +++ b/scripts/configure.in @@ -1198,11 +1198,12 @@ else fi dnl The readline code is incompatible with Tcl/Tk, which has its own -dnl readline-like interface, so regardless of the setting of this -dnl option, if Tcl/Tk support is enabled, it will always be disabled. +dnl readline-like interface, so if Tcl/Tk support is enabled readline is always +dnl disabled regardless of this option. AC_ARG_ENABLE(readline, -[ --disable-readline disable readline package], +[ --disable-readline do not use the system readline library even if + it is present (build without command-line editing)], [ if test $usingTcl ; then enable_readline=no fi @@ -1214,56 +1215,30 @@ AC_ARG_ENABLE(readline, fi ]) -use_system_readline=yes -use_bundled_readline=auto - -AC_ARG_ENABLE(readline-bundled, -[ --enable-readline-bundled enable readline bundled package], -[ use_bundled_readline=yes -], [ - use_bundled_readline=no -]) - if test "x$enable_readline" = "xyes" ; then + dnl A non-Tcl interactive build uses the SYSTEM GNU readline library (the + dnl bundled copy has been removed). Require both its header and the library; + dnl if neither Tcl nor readline is available, fail with a clear explanation. AC_DEFINE(USE_READLINE) - if test $use_bundled_readline != yes ; then - AC_CHECK_LIB(readline, rl_pre_input_hook,[ - dnl noop, prevent default action LIBS+=-lreadline - ], - use_system_readline=no) - AC_CHECK_LIB(readline, rl_username_completion_function,[ - dnl noop, prevent default action LIBS+=-lreadline - ], - use_system_readline=no) - AC_CHECK_LIB(readline, rl_filename_completion_function,[ - dnl noop, prevent default action LIBS+=-lreadline - ], - use_system_readline=no) - AC_CHECK_LIB(readline, rl_attempted_completion_over,[ - dnl noop, prevent default action LIBS+=-lreadline - ], - use_system_readline=no) - fi - if test $use_system_readline = yes && test $use_bundled_readline != yes; then + use_system_readline=yes + AC_CHECK_HEADER([readline/readline.h], [], [use_system_readline=no]) + AC_CHECK_LIB(readline, rl_pre_input_hook, [], [use_system_readline=no]) + AC_CHECK_LIB(readline, rl_username_completion_function, [], [use_system_readline=no]) + AC_CHECK_LIB(readline, rl_filename_completion_function, [], [use_system_readline=no]) + AC_CHECK_LIB(readline, rl_attempted_completion_over, [], [use_system_readline=no]) + if test $use_system_readline = yes ; then AC_DEFINE(HAVE_READLINE) - rl_libs="-lreadline" - use_bundled_readline= + rl_libs="-lreadline" else - echo "Using bundled readline" - AC_DEFINE(NEED_READLINE) - # not readline/libhistory.a (seems subset of libreadline.a) - rl_libs="\${MAGICDIR}/readline/libreadline.a" - CPPFLAGS="$CPPFLAGS -I\${MAGICDIR}/readline" - use_bundled_readline=1 + AC_MSG_ERROR([no usable GNU readline library found. - AC_CHECK_LIB(termcap, tgetent, [ - rl_libs="$rl_libs -ltermcap" - ], [ - AC_CHECK_LIB(ncurses, tgetent, [ - rl_libs="$rl_libs -lncurses" - ], ) - ], ) - modules="$modules readline" +magic needs either Tcl/Tk (recommended) or the system GNU readline development +package to build an interactive non-Tcl version. Please do one of: + * build with Tcl/Tk (the default when Tcl is installed); or + * install the readline development package (e.g. libreadline-dev on Debian/ + Ubuntu, readline-devel on Fedora/RHEL, or 'brew install readline'); or + * re-run configure with --disable-readline to build without command-line + editing.]) fi else unused="$unused readline" @@ -2083,7 +2058,7 @@ AC_SUBST(MAKE_X11, [$usingX11]) AC_SUBST(MAKE_GL, [$usingOGL]) AC_SUBST(MAKE_GLU, [$usingGLU]) AC_SUBST(MAKE_CAIRO, [$usingCairo]) -AC_SUBST(MAKE_READLINE, [$use_bundled_readline]) +AC_SUBST(MAKE_READLINE, [0]) dnl Name the .in templates explicitly (relative to srcdir) so config.status can dnl find them when run from a separate build directory. Outputs land in the