Readline Maintainers, Summary: I think I found a (minor) bug in readline 8.2; details follow, and "config.h" is attached. Things build fine, and I can use the library, but some of the header files that are installed with "make && make install" have some issues in them which I will describe in more detail below. One of the issues I describe below appears to be a genuine bug you probably care about. The problems manifests by including the readline library header file "readline.h" and using "-Werror -Wstrict-prototypes" with GCC when building a user program, which causes the build to fail.
I found the following readline page: https://tiswww.case.edu/php/chet/readline/rltop.html I downloaded readline from the following link: http://git.savannah.gnu.org/cgit/readline.git/snapshot/readline-master.tar.gz I then extracted the tarball (readline 8.2) and ran the following commands to build the library: export CC=/dept/Boston/avose/riscv/tools/install/riscv-gnu/bin/riscv64-unknown-linux-gnu-gcc ./configure --prefix /dept/Boston/avose/riscv/tools/install/riscv-readline --disable-shared --host=riscv64-unknown-linux-gnu --with-curses I know the above is a cross-compile to RISCV, but I don't think this problem is specific to the ISA, as I've seen the exact same issues with ARM installs of readline 8.2 as well. The issue comes from two places in the header files. One (1) is, I think, an actual issue you want to know about and probably want to fix, the other (2) is probably a more minor thing, but you might still want to know about it, and may want to think about a fix for it. (1) This first issue may actually be a problem you care about. What happens is that "readline.h" contains the following code, which in and of itself isn't the issue, this is just where the compiler warning / error initially comes from: #if defined (USE_VARARGS) && defined (PREFER_STDARG) extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2))); #else extern int rl_message (); #endif The configure process did find "stdarg.h" as can be seen in the attached "config.h" file: /* Define if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 However, the "readline.h" file in the install location uses the second prototype: "extern int rl_message ();". It should instead be using the first one: "extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));". This is caused by an issue in a file included by "readline.h" called "rlstdc.h". The problematic code in "rlstdc.h" follows: #if defined (__STDC__) && defined (HAVE_STDARG_H) # define PREFER_STDARG # define USE_VARARGS #else # if defined (HAVE_VARARGS_H) # define PREFER_VARARGS # define USE_VARARGS # endif #endif During the build process, this is fine because "HAVE_STDARG_H" is defined. This then causes "PREFER_STDARG" and "USE_VARARGS" to be defined. So, in the build process, the correct prototype for "rl_message" is used: "extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));". However, when user programs include "readline.h" and try to build, "HAVE_STDARG_H" is not defined, and the wrong prototype for "message" is used: "extern int rl_message ();". This is because the check for "HAVE_STDARG_H" has been "leaked" out of the build environment into the standard installed readline header files. I don't think the installed header files should have a check for "HAVE_STDARG_H" in them. This seems like an actual bug, and it should probably be fixed. My solution here was a hack. I did the following to resolve the error: //!!avose: HAVE_STDARG_H was defined during configure, but this macro is not //!!avose: included anywhere in the include files for users of readline. //!!avose: Thus, this edit includes it below. This is needed to avoid issues //!!avose: from "-Werror=strict-prototypes" #ifndef HAVE_STDARG_H #define HAVE_STDARG_H #define AVOSE_FIX_HAVE_STDARG_H #endif #if defined (__STDC__) && defined (HAVE_STDARG_H) # define PREFER_STDARG # define USE_VARARGS #else # if defined (HAVE_VARARGS_H) # define PREFER_VARARGS # define USE_VARARGS # endif #endif #ifdef AVOSE_FIX_HAVE_STDARG_H #undef HAVE_STDARG_H #undef AVOSE_FIX_HAVE_STDARG_H #endif (2) This second issue is something you may not care about as much. The second issue is another place where compiling a user program that includes "readline.h" is an issue combined with "-Werror -Wstrict-prototypes". In this second issue, the problem is in the header file "rltypedefs.h". The section containing the issue is as follows: #if defined(__GNUC__) || defined(__clang__) typedef int Function () __attribute__((deprecated)); typedef void VFunction () __attribute__((deprecated)); typedef char *CPFunction () __attribute__((deprecated)); typedef char **CPPFunction () __attribute__((deprecated)); #else typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); typedef char **CPPFunction (); #endif These prototypes don't actually appear to be used anywhere by user programs compiling and linking with readline, and they are an error with "-Werror -Wstrict-prototypes". My solution here was to just disable this whole block of code with "#if 0" as shown below. You may not care too much about this, I suppose, just mentioning it. //!!avose: The following types aren't needed anywhere I can see //!!avose: and they cause warnings from -Werror=strict-prototypes #if 0 #if defined(__GNUC__) || defined(__clang__) typedef int Function () __attribute__((deprecated)); typedef void VFunction () __attribute__((deprecated)); typedef char *CPFunction () __attribute__((deprecated)); typedef char **CPPFunction () __attribute__((deprecated)); #else typedef int Function (); typedef void VFunction (); typedef char *CPFunction (); typedef char **CPPFunction (); #endif #endif It would be wonderful if someone could take a look at these issues, and possible fix them upstream so that others might avoid the problems that I've been hitting here. Thanks so much for your time. Thanks much, ~Aaron Vose
/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Maintained by hand. */ /* Template definitions for autoconf */ /* These are set by AC_USE_SYSTEM_EXTENSIONS */ #define __EXTENSIONS__ 1 #define _ALL_SOURCE 1 #define _GNU_SOURCE 1 /* #undef _POSIX_SOURCE */ /* #undef _POSIX_1_SOURCE */ #define _POSIX_PTHREAD_SEMANTICS 1 #define _TANDEM_SOURCE 1 /* #undef _MINIX */ /* Define NO_MULTIBYTE_SUPPORT to not compile in support for multibyte characters, even if the OS supports them. */ /* #undef NO_MULTIBYTE_SUPPORT */ /* #undef _FILE_OFFSET_BITS */ /* Characteristics of the compiler. */ /* #undef inline */ /* #undef sig_atomic_t */ /* #undef size_t */ /* #undef ssize_t */ /* #undef const */ /* #undef volatile */ #define PROTOTYPES 1 #define __PROTOTYPES 1 #define __CHAR_UNSIGNED__ 1 /* Define if the `S_IS*' macros in <sys/stat.h> do not work properly. */ /* #undef STAT_MACROS_BROKEN */ /* Define if you have the chown function. */ #define HAVE_CHOWN 1 /* Define if you have the fcntl function. */ #define HAVE_FCNTL 1 /* Define if you have the fnmatch function. */ #define HAVE_FNMATCH 1 /* Define if you have the getpwent function. */ #define HAVE_GETPWENT 1 /* Define if you have the getpwnam function. */ #define HAVE_GETPWNAM 1 /* Define if you have the getpwuid function. */ #define HAVE_GETPWUID 1 /* Define if you have the gettimeofday function. */ #define HAVE_GETTIMEOFDAY 1 /* Define if you have the isascii function. */ #define HAVE_ISASCII 1 /* Define if you have the iswctype function. */ #define HAVE_ISWCTYPE 1 /* Define if you have the iswlower function. */ #define HAVE_ISWLOWER 1 /* Define if you have the iswupper function. */ #define HAVE_ISWUPPER 1 /* Define if you have the isxdigit function. */ #define HAVE_ISXDIGIT 1 /* Define if you have the kill function. */ #define HAVE_KILL 1 /* Define if you have the lstat function. */ #define HAVE_LSTAT 1 /* Define if you have the mbrlen function. */ #define HAVE_MBRLEN 1 /* Define if you have the mbrtowc function. */ #define HAVE_MBRTOWC 1 /* Define if you have the mbsrtowcs function. */ #define HAVE_MBSRTOWCS 1 /* Define if you have the memmove function. */ #define HAVE_MEMMOVE 1 /* Define if you have the pselect function. */ #define HAVE_PSELECT 1 /* Define if you have the putenv function. */ #define HAVE_PUTENV 1 /* Define if you have the readlink function. */ #define HAVE_READLINK 1 /* Define if you have the select function. */ #define HAVE_SELECT 1 /* Define if you have the setenv function. */ #define HAVE_SETENV 1 /* Define if you have the setitimer function. */ #define HAVE_SETITIMER 1 /* Define if you have the setlocale function. */ #define HAVE_SETLOCALE 1 /* Define if you have the strcasecmp function. */ #define HAVE_STRCASECMP 1 /* Define if you have the strcoll function. */ #define HAVE_STRCOLL 1 /* #undef STRCOLL_BROKEN */ /* Define if you have the strpbrk function. */ #define HAVE_STRPBRK 1 /* Define if you have the sysconf function. */ #define HAVE_SYSCONF 1 /* Define if you have the tcgetattr function. */ #define HAVE_TCGETATTR 1 /* Define if you have the towlower function. */ #define HAVE_TOWLOWER 1 /* Define if you have the towupper function. */ #define HAVE_TOWUPPER 1 /* Define if you have the vsnprintf function. */ #define HAVE_VSNPRINTF 1 /* Define if you have the wcrtomb function. */ #define HAVE_WCRTOMB 1 /* Define if you have the wcscoll function. */ #define HAVE_WCSCOLL 1 /* Define if you have the wctype function. */ #define HAVE_WCTYPE 1 /* Define if you have the wcwidth function. */ #define HAVE_WCWIDTH 1 /* and whether it works */ /* #undef WCWIDTH_BROKEN */ /* Define if you have the <dirent.h> header file. */ #define HAVE_DIRENT_H 1 /* Define if you have the <fcntl.h> header file. */ #define HAVE_FCNTL_H 1 /* Define if you have the <langinfo.h> header file. */ #define HAVE_LANGINFO_H 1 /* Define if you have the <libaudit.h> header file. */ /* #undef HAVE_LIBAUDIT_H */ /* Define if you have the <limits.h> header file. */ #define HAVE_LIMITS_H 1 /* Define if you have the <locale.h> header file. */ #define HAVE_LOCALE_H 1 /* Define if you have the <memory.h> header file. */ #define HAVE_MEMORY_H 1 /* Define if you have the <ndir.h> header file. */ /* #undef HAVE_NDIR_H */ /* Define if you have the <ncurses/termcap.h> header file. */ /* #undef HAVE_NCURSES_TERMCAP_H */ /* Define if you have the <pwd.h> header file. */ #define HAVE_PWD_H 1 /* Define if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 /* Define if you have the <stdbool.h> header file. */ #define HAVE_STDBOOL_H 1 /* Define if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 /* Define if you have the <string.h> header file. */ #define HAVE_STRING_H 1 /* Define if you have the <strings.h> header file. */ #define HAVE_STRINGS_H 1 /* Define if you have the <sys/dir.h> header file. */ /* #undef HAVE_SYS_DIR_H */ /* Define if you have the <sys/file.h> header file. */ #define HAVE_SYS_FILE_H 1 /* Define if you have the <sys/ioctl.h> header file. */ #define HAVE_SYS_IOCTL_H 1 /* Define if you have the <sys/ndir.h> header file. */ /* #undef HAVE_SYS_NDIR_H */ /* Define if you have the <sys/pte.h> header file. */ /* #undef HAVE_SYS_PTE_H */ /* Define if you have the <sys/ptem.h> header file. */ /* #undef HAVE_SYS_PTEM_H */ /* Define if you have the <sys/select.h> header file. */ #define HAVE_SYS_SELECT_H 1 /* Define if you have the <sys/stream.h> header file. */ /* #undef HAVE_SYS_STREAM_H */ /* Define if you have the <sys/time.h> header file. */ #define HAVE_SYS_TIME_H 1 /* Define if you have the <termcap.h> header file. */ /* #undef HAVE_TERMCAP_H */ /* Define if you have the <termio.h> header file. */ #define HAVE_TERMIO_H 1 /* Define if you have the <termios.h> header file. */ #define HAVE_TERMIOS_H 1 /* Define if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 /* Define if you have the <varargs.h> header file. */ /* #undef HAVE_VARARGS_H */ /* Define if you have the <wchar.h> header file. */ #define HAVE_WCHAR_H 1 /* Define if you have the <wctype.h> header file. */ #define HAVE_WCTYPE_H 1 #define HAVE_MBSTATE_T 1 /* Define if you have wchar_t in <wctype.h>. */ #define HAVE_WCHAR_T 1 /* Define if you have wctype_t in <wctype.h>. */ #define HAVE_WCTYPE_T 1 /* Define if you have wint_t in <wctype.h>. */ #define HAVE_WINT_T 1 /* Define if you have <langinfo.h> and nl_langinfo(CODESET). */ #define HAVE_LANGINFO_CODESET 1 /* Define if you have <linux/audit.h> and it defines AUDIT_USER_TTY */ #define HAVE_DECL_AUDIT_USER_TTY 1 /* Definitions pulled in from aclocal.m4. */ #define GWINSZ_IN_SYS_IOCTL 1 #define STRUCT_WINSIZE_IN_SYS_IOCTL 1 /* #undef STRUCT_WINSIZE_IN_TERMIOS */ /* #undef TIOCSTAT_IN_SYS_IOCTL */ #define FIONREAD_IN_SYS_IOCTL 1 /* #undef SPEED_T_IN_SYS_TYPES */ #define HAVE_GETPW_DECLS 1 #define HAVE_STRUCT_DIRENT_D_INO 1 #define HAVE_STRUCT_DIRENT_D_FILENO 1 /* #undef HAVE_STRUCT_DIRENT_D_NAMLEN */ #define HAVE_TIMEVAL 1 /* #undef HAVE_BSD_SIGNALS */ #define HAVE_POSIX_SIGNALS 1 /* #undef HAVE_USG_SIGHOLD */ /* #undef MUST_REINSTALL_SIGHANDLERS */ #define HAVE_POSIX_SIGSETJMP 1 /* #undef CTYPE_NON_ASCII */ /* modify settings or make new ones based on what autoconf tells us. */ /* Ultrix botches type-ahead when switching from canonical to non-canonical mode, at least through version 4.3 */ #if !defined (HAVE_TERMIOS_H) || !defined (HAVE_TCGETATTR) || defined (ultrix) # define TERMIOS_MISSING #endif /* VARARGS defines moved to rlstdc.h */
