Skip to content

Commit

Permalink
Remove Readline library integration
Browse files Browse the repository at this point in the history
This removes the GNU Readline library integration and relies on the
libedit library if present. Issue is that there are several ext/readline
libraries and GNU Readline license (GNU GPL 3) is not compatible with
the PHP license. There was a similar attempt to fix this (GH-3823) and
now fix continues here.

Changes:
- `--with-libedit` configure option removed (only `--with-readline`
  stays)
- readline extension tests fixed: those required by only readline
  library removed, added missing skip reasons, some functions are always
  available, etc.
- New PHP_SETUP_EDIT Autoconf macro that finds libedit

This also fixes the phpdbg readline integration on *nix systems (using
libedit library) for history (up/down keys and similar nice features) to
not produce compile errors:

    ./configure --enable-phpdbg-readline
    make

    undefined reference to 'readline'
    undefined reference to 'add_history'
  • Loading branch information
petk committed Sep 14, 2024
1 parent 888eb37 commit 308d4a1
Show file tree
Hide file tree
Showing 35 changed files with 69 additions and 510 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
libxml2-dev \
libxslt1-dev \
libpq-dev \
libreadline-dev \
libedit-dev \
libldap2-dev \
libsodium-dev \
libargon2-0-dev \
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/apk/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ runs:
libzip-dev \
oniguruma-dev \
openssl-dev \
readline-dev \
libedit-dev \
sqlite-dev \
tidyhtml-dev \
krb5-dev \
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/apt-x32/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ runs:
libonig-dev:i386 \
libpng-dev:i386 \
libpq-dev:i386 \
libreadline-dev:i386 \
libedit-dev:i386 \
libsasl2-dev:i386 \
libsodium-dev:i386 \
libsqlite3-dev:i386 \
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/configure-macos/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ runs:
--enable-sysvshm \
--enable-shmop \
--enable-pcntl \
--with-readline="$BREW_OPT"/readline \
--with-readline \
--enable-mbstring \
--with-curl \
--with-gettext="$BREW_OPT"/gettext \
Expand Down
2 changes: 1 addition & 1 deletion .github/actions/configure-x64/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ runs:
--enable-sysvshm \
--enable-shmop \
--enable-pcntl \
--without-readline --with-libedit \
--with-readline \
--enable-mbstring \
--with-curl \
--with-gettext \
Expand Down
19 changes: 19 additions & 0 deletions build/php.m4
Original file line number Diff line number Diff line change
Expand Up @@ -2002,6 +2002,25 @@ $2],
]))])])
])

dnl
dnl
dnl PHP_SETUP_EDIT([shared-add], [action-if-found], [action-if-not-found], [not-extension])
dnl
dnl Common setup macro for linking libedit library. If "not-extension" argument
dnl is passed, the found library is appended to the "shared-add" variable
dnl unconditionally (for SAPIs).
dnl
AC_DEFUN([PHP_SETUP_EDIT], [
PKG_CHECK_MODULES([EDIT], [libedit], [
PHP_EVAL_INCLINE([$EDIT_CFLAGS])
PHP_EVAL_LIBLINE([$EDIT_LIBS], [$1], [$4])
AC_DEFINE([HAVE_LIBEDIT], [1],
[Define to 1 if 'libedit' library is available.])
$2
],
[$3])
])

dnl ----------------------------------------------------------------------------
dnl Misc. macros
dnl ----------------------------------------------------------------------------
Expand Down
129 changes: 18 additions & 111 deletions ext/readline/config.m4
Original file line number Diff line number Diff line change
@@ -1,103 +1,17 @@
PHP_ARG_WITH([libedit],
[for libedit readline replacement],
[AS_HELP_STRING([--with-libedit],
[Include libedit readline replacement (CLI/CGI only)])])
PHP_ARG_WITH([readline],
[for readline support],
[AS_HELP_STRING([--with-readline],
[Include readline support using the libedit library (CLI/CGI only)])])

if test "$PHP_LIBEDIT" = "no"; then
PHP_ARG_WITH([readline],
[for readline support],
[AS_HELP_STRING([[--with-readline[=DIR]]],
[Include readline support (CLI/CGI only)])])
else
dnl "register" the --with-readline option to prevent invalid "unknown
dnl configure option" warning
php_with_readline=no
fi

if test "$PHP_READLINE" && test "$PHP_READLINE" != "no"; then
for i in $PHP_READLINE /usr/local /usr; do
AS_IF([test -f $i/include/readline/readline.h], [READLINE_DIR=$i; break;])
done

AS_VAR_IF([READLINE_DIR],,
[AC_MSG_ERROR([Please reinstall readline - I cannot find readline.h])])

PHP_ADD_INCLUDE([$READLINE_DIR/include])

PHP_READLINE_LIBS=""
AC_CHECK_LIB([ncurses], [tgetent], [
PHP_ADD_LIBRARY([ncurses],, [READLINE_SHARED_LIBADD])
PHP_READLINE_LIBS="$PHP_READLINE_LIBS -lncurses"
],
[AC_CHECK_LIB([termcap], [tgetent], [
PHP_ADD_LIBRARY([termcap],, [READLINE_SHARED_LIBADD])
PHP_READLINE_LIBS="$PHP_READLINE_LIBS -ltermcap"
])
])

PHP_CHECK_LIBRARY([readline], [readline],
[PHP_ADD_LIBRARY_WITH_PATH([readline],
[$READLINE_DIR/$PHP_LIBDIR],
[READLINE_SHARED_LIBADD])],
[AC_MSG_FAILURE([The readline library not found.])],
[-L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS])

PHP_CHECK_LIBRARY([readline], [rl_callback_read_char],
[AC_DEFINE([HAVE_RL_CALLBACK_READ_CHAR], [1])],
[],
[-L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS])

PHP_CHECK_LIBRARY([readline], [rl_on_new_line],
[AC_DEFINE([HAVE_RL_ON_NEW_LINE], [1])],
[],
[-L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS])

PHP_CHECK_LIBRARY([readline], [rl_completion_matches],
[AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1])],
[],
[-L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS])

CFLAGS_SAVE=$CFLAGS
LDFLAGS_SAVE=$LDFLAGS
LIBS_SAVE=$LIBS
CFLAGS="$CFLAGS $INCLUDES"
LDFLAGS="$LDFLAGS -L$READLINE_DIR/$PHP_LIBDIR"
LIBS="$LIBS -lreadline"

dnl Sanity and minimum version check if readline library has variable
dnl rl_pending_input.
AC_CHECK_DECL([rl_pending_input],, [AC_MSG_FAILURE([
Invalid readline installation detected. Try --with-libedit instead.
])], [
#include <stdio.h>
#include <readline/readline.h>
])

AC_CHECK_DECL([rl_erase_empty_line],
[AC_DEFINE([HAVE_ERASE_EMPTY_LINE], [1])],, [
#include <stdio.h>
#include <readline/readline.h>
])
CFLAGS=$CFLAGS_SAVE
LDFLAGS=$LDFLAGS_SAVE
LIBS=$LIBS_SAVE
if test "$PHP_READLINE" != "no"; then
AS_VAR_IF([PHP_READLINE], [yes],,
[AC_MSG_WARN([m4_text_wrap([
The directory argument is not supported anymore, rely on pkg-config.
Replace '--with-readline=$PHP_READLINE' with '--with-realine' and use
environment variables 'PKG_CONFIG_PATH', 'EDIT_LIBS', or 'EDIT_CFLAGS'.
])])])

AC_DEFINE([HAVE_HISTORY_LIST], [1])
AC_DEFINE([HAVE_LIBREADLINE], [1],
[Define to 1 if readline extension uses the 'readline' library.])

elif test "$PHP_LIBEDIT" != "no"; then
AS_VAR_IF([PHP_LIBEDIT], [yes],,
[AC_MSG_WARN(m4_text_wrap([
The libedit directory argument is not supported anymore, rely on
pkg-config. Replace '--with-libedit=$PHP_LIBEDIT' with '--with-libedit'
and use environment variables 'PKG_CONFIG_PATH', 'EDIT_LIBS', or
'EDIT_CFLAGS'.
]))])

PKG_CHECK_MODULES([EDIT], [libedit])
PHP_EVAL_LIBLINE([$EDIT_LIBS], [READLINE_SHARED_LIBADD])
PHP_EVAL_INCLINE([$EDIT_CFLAGS])
PHP_SETUP_EDIT([READLINE_SHARED_LIBADD])

AC_CHECK_LIB([ncurses], [tgetent],
[PHP_ADD_LIBRARY([ncurses],, [READLINE_SHARED_LIBADD])],
Expand All @@ -111,28 +25,26 @@ elif test "$PHP_LIBEDIT" != "no"; then

PHP_CHECK_LIBRARY([edit], [rl_callback_read_char],
[AC_DEFINE([HAVE_RL_CALLBACK_READ_CHAR], [1],
[Define to 1 if edit/readline library has the 'rl_callback_read_char'
function.])],
[Define to 1 if edit library has the 'rl_callback_read_char' function.])],
[],
[$READLINE_SHARED_LIBADD])

PHP_CHECK_LIBRARY([edit], [rl_on_new_line],
[AC_DEFINE([HAVE_RL_ON_NEW_LINE], [1],
[Define to 1 if edit/readline library has the 'rl_on_new_line'
function.])],
[Define to 1 if edit library has the 'rl_on_new_line' function.])],
[],
[$READLINE_SHARED_LIBADD])

PHP_CHECK_LIBRARY([edit], [rl_completion_matches],
[AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], [1],
[Define to 1 if edit/readline library has the 'rl_completion_matches'
[Define to 1 if edit library has the 'rl_completion_matches'
function.])],
[],
[$READLINE_SHARED_LIBADD])

PHP_CHECK_LIBRARY([edit], [history_list],
[AC_DEFINE([HAVE_HISTORY_LIST], [1],
[Define to 1 if edit/readline library has the 'history_list' function.])],
[Define to 1 if edit library has the 'history_list' function.])],
[],
[$READLINE_SHARED_LIBADD])

Expand All @@ -142,17 +54,12 @@ elif test "$PHP_LIBEDIT" != "no"; then
LIBS="$LIBS $EDIT_LIBS"
AC_CHECK_DECL([rl_erase_empty_line],
[AC_DEFINE([HAVE_ERASE_EMPTY_LINE], [1],
[Define to 1 if edit/readline library has the 'rl_erase_empty_line'
global variable.])],,
[Define to 1 if edit library has the 'rl_erase_empty_line' global
variable.])],,
[#include <editline/readline.h>])
CFLAGS=$CFLAGS_SAVE
LIBS=$LIBS_SAVE

AC_DEFINE([HAVE_LIBEDIT], [1],
[Define to 1 if readline extension uses the 'libedit' library.])
fi

if test "$PHP_READLINE" != "no" || test "$PHP_LIBEDIT" != "no"; then
dnl Add -Wno-strict-prototypes as depends on user libs
PHP_NEW_EXTENSION([readline],
[readline.c readline_cli.c],
Expand Down
6 changes: 3 additions & 3 deletions ext/readline/php_readline.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@
#ifdef HAVE_LIBEDIT
#define READLINE_LIB "libedit"
#else
#define READLINE_LIB "readline"
#define READLINE_LIB ""
#endif

#if defined(HAVE_LIBREADLINE) || defined(HAVE_LIBEDIT)
#ifdef HAVE_LIBEDIT

extern zend_module_entry readline_module_entry;
#define phpext_readline_ptr &readline_module_entry
Expand All @@ -35,6 +35,6 @@ extern zend_module_entry readline_module_entry;

#define phpext_readline_ptr NULL

#endif /* HAVE_LIBREADLINE */
#endif /* HAVE_LIBEDIT */

#endif /* PHP_READLINE_H */
Loading

0 comments on commit 308d4a1

Please sign in to comment.