From a864a5f764199cb22f768d8679835e46e022bed6 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Sat, 26 Oct 2024 21:00:57 +0800 Subject: [PATCH 01/10] build: configure "--with-curses=yes" is now a no-op It makes no sense to error out if the builder runs "./configure --with-curses" and no option argument. "--with-curses" without an option argument now keeps using the default name list for detecting ncurses library. Signed-off-by: Kang-Che Sung --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 54f6e0e28..0dc476d98 100644 --- a/configure.ac +++ b/configure.ac @@ -412,10 +412,10 @@ AC_ARG_WITH([curses], [], [with_curses=check]) case $with_curses in -check) +check|yes) : # No-op. Use default list. ;; -yes|no) +no) AC_MSG_ERROR([bad value '$with_curses' for --with-curses option]) ;; *) From c3c810869c2cf28b074d8b58d8cbaae5835199a5 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Mon, 28 Oct 2024 17:04:21 +0800 Subject: [PATCH 02/10] build: Log the detected '*curses*.pc' file into config.log When "configure" suggests user to install pkg-config, output the '*curses*.pc' file detected in the config.log. This aids diagnosing the configure script. Signed-off-by: Kang-Che Sung --- configure.ac | 1 + 1 file changed, 1 insertion(+) diff --git a/configure.ac b/configure.ac index 0dc476d98..850676e00 100644 --- a/configure.ac +++ b/configure.ac @@ -607,6 +607,7 @@ none-*|nonwide-yes) for d in $list; do result=`find "$d" -name '*curses*.pc' 2>/dev/null | sed '1 q'` if test "x$result" != x; then + echo detected a .pc file: "$result" >&AS_MESSAGE_LOG_FD AC_MSG_WARN([your system supports pkg-config; installing pkg-config is recommended before configuring htop]) break fi From 58555925cf04b483602fc2c73b0ffd62d6dbb07c Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:57:54 +0800 Subject: [PATCH 03/10] build: Improve configure logic with pkg.m4 support It is slightly more robust to grep for the 'pkg_m4_included' token when running "make dist". Also, shorten the "make dist" warning message, and tell users if they need to regenerate configure when we recommend them to install pkg-config. Signed-off-by: Kang-Che Sung --- Makefile.am | 8 ++++---- configure.ac | 5 ++++- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/Makefile.am b/Makefile.am index 386506c92..65de4f922 100644 --- a/Makefile.am +++ b/Makefile.am @@ -508,11 +508,11 @@ cppcheck: cppcheck -q -v . --enable=all -DHAVE_OPENVZ dist-hook: $(top_distdir)/configure - @if test "x$$FORCE_MAKE_DIST" = x && \ - grep 'pkg_m4_absent' '$(top_distdir)/configure' >/dev/null; then \ - echo 'ERROR: This distribution would have incomplete pkg-config support. Rebuilding the configure script is advised. Set FORCE_MAKE_DIST=1 to ignore this warning.'>&2; \ + @if test "x$$FORCE_MAKE_DIST" != x || \ + grep 'pkg_m4_included' '$(top_distdir)/configure' >/dev/null; then :; \ + else \ + echo 'ERROR: The configure script has incomplete pkg-config support and regenerating it is advised. Set FORCE_MAKE_DIST=1 to ignore this warning.'>&2; \ (exit 1); \ - else :; \ fi @if grep 'PACKAGE_VERSION.*-g' '$(top_distdir)/configure'; then \ echo 'WARNING: You are building a dist from a git version. Better run make dist outside of a .git repo on a tagged release.'>&2; \ diff --git a/configure.ac b/configure.ac index 850676e00..fe078af99 100644 --- a/configure.ac +++ b/configure.ac @@ -384,8 +384,8 @@ dnl If the macro is not called, some pkg-config checks might be skipped dnl and $PKG_CONFIG might be unset. m4_ifdef([PKG_PROG_PKG_CONFIG], [ PKG_PROG_PKG_CONFIG() + pkg_m4_included=1 # Makefile might grep this keyword. Don't remove. ], [ - pkg_m4_absent=1 # Makefile might grep this keyword. Don't remove. m4_warn( [syntax], [pkg.m4 is absent or older than version 0.16; this 'configure' would have incomplete pkg-config support]) @@ -609,6 +609,9 @@ none-*|nonwide-yes) if test "x$result" != x; then echo detected a .pc file: "$result" >&AS_MESSAGE_LOG_FD AC_MSG_WARN([your system supports pkg-config; installing pkg-config is recommended before configuring htop]) + m4_ifdef([PKG_PROG_PKG_CONFIG], [], [ + AC_MSG_WARN([this configure script would also need to be regenerated]) + ]) break fi done From 05661cafc35bedb2b996b9827040ec458edfcbdc Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:08 +0800 Subject: [PATCH 04/10] build: Don't test "stdscr" with linking with libtinfo When ncurses is compiled with reentrant support, the "stdscr" may be only available as a macro and not a symbol for direct linking. We can check for "stdscr" only after the curses headers are included. For now we can remove the "stdscr" test when checking for keypad() function. Signed-off-by: Kang-Che Sung --- configure.ac | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/configure.ac b/configure.ac index fe078af99..0bcbd7075 100644 --- a/configure.ac +++ b/configure.ac @@ -450,18 +450,17 @@ htop_check_curses_capability () { # At this point we have not checked the name of curses header, so # use forward declaration for the linking tests below. - # htop uses keypad() and "stdscr", but for ncurses implementation, - # the symbols are in "-ltinfo" and not "-lncurses". + # htop uses keypad(), but for ncurses implementation, the symbol is + # in "-ltinfo" and not "-lncurses". # Check "-ltinfo" symbols first, as libncurses might require # explicit "-ltinfo" to link (for internal dependency). AC_MSG_CHECKING([for keypad in $htop_msg_linker_flags]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -/* extern WINDOW* stdscr; */ /* int keypad(WINDOW* win, bool enable); */ -extern void* stdscr; int keypad(void* win, int enable); ]], [[ -keypad(stdscr, 0); +static char dummy; +keypad((void*)&dummy, 0); ]])], [AC_MSG_RESULT(yes)], [AC_MSG_RESULT(no) From b1e0b326adc2e02c52ce9ef80fa016a036702127 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:14 +0800 Subject: [PATCH 05/10] build: check for wadd_wchnstr() rather than mvadd_wchnstr() According to ncurses man page, mvadd_wchnstr() may be implemented as a macro. Signed-off-by: Kang-Che Sung --- configure.ac | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 0bcbd7075..de089650b 100644 --- a/configure.ac +++ b/configure.ac @@ -482,13 +482,17 @@ doupdate(); htop_curses_status=1]) fi + # htop calls mvadd_wchnstr(), which might be implemented as a macro. + # It is more reliable to test linking with wadd_wchnstr(). if test "x$htop_curses_status$enable_unicode" = x0yes; then - AC_MSG_CHECKING([for mvadd_wchnstr in $htop_msg_linker_flags]) + AC_MSG_CHECKING([for wadd_wchnstr in $htop_msg_linker_flags]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -/* int mvadd_wchnstr(int y, int x, const cchar_t* wchstr, int n); */ -int mvadd_wchnstr(int y, int x, const void* wchstr, int n); +/* int wadd_wchnstr(WINDOW* win, const cchar_t* wchstr, int n); */ +int wadd_wchnstr(void* win, const void* wchstr, int n); ]], [[ -mvadd_wchnstr(0, 0, (void*)0, 0); +static char dummy1; +static char dummy2; +wadd_wchnstr((void*)&dummy1, (void*)&dummy2, 0); ]])], [AC_MSG_RESULT(yes) htop_curses_capability=wide], From 93f71c9419f373578996689b2bea84bbe44012b6 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:19 +0800 Subject: [PATCH 06/10] build: Move _XOPEN_SOURCE_EXTENDED define to config.h This allows configure tests to utilize the macro. Also explain the reasons that we define _XOPEN_SOURCE_EXTENDED and not _XOPEN_SOURCE. Signed-off-by: Kang-Che Sung --- Makefile.am | 2 +- configure.ac | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 65de4f922..f25c0f068 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,7 +24,7 @@ pixmap_DATA = htop.png appicondir = $(datadir)/icons/hicolor/scalable/apps appicon_DATA = htop.svg -AM_CFLAGS += -D_XOPEN_SOURCE_EXTENDED -DSYSCONFDIR="\"$(sysconfdir)\"" -I"$(top_srcdir)/$(my_htop_platform)" +AM_CFLAGS += -DSYSCONFDIR="\"$(sysconfdir)\"" -I"$(top_srcdir)/$(my_htop_platform)" AM_LDFLAGS = myhtopsources = \ diff --git a/configure.ac b/configure.ac index de089650b..2821474f5 100644 --- a/configure.ac +++ b/configure.ac @@ -68,6 +68,22 @@ esac # Enable extensions, required by hwloc scripts AC_USE_SYSTEM_EXTENSIONS +# The header of ncurses exposes wide-character interfaces only if +# _XOPEN_SOURCE_EXTENDED is defined or _XOPEN_SOURCE defined to be +# >= 500. In DragonFly BSD, FreeBSD and OpenBSD, defining +# _XOPEN_SOURCE to any value *hides* interfaces that would be useful +# for htop. +dnl +dnl Note: The "#undef" in AH_VERBATIM will be replaced with "#define" +dnl when config.h is generated. +AH_VERBATIM([_XOPEN_SOURCE_EXTENDED], +[/* Enables XPG4v2 (SUSv1) interfaces if they are not enabled already with _XOPEN_SOURCE */ +#ifndef _XOPEN_SOURCE_EXTENDED +#undef _XOPEN_SOURCE_EXTENDED +#endif +]) +AC_DEFINE([_XOPEN_SOURCE_EXTENDED], 1) + # Activate some more of the missing global defines AC_SYS_LARGEFILE From 7dfd4dd732dbbaa8fe19a7da15214a9c1578e715 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:23 +0800 Subject: [PATCH 07/10] build: Add a test for whether curses.h works. The main thing I intended to test is "stdscr", but it is also useful to test ncurses functions that might be implemented as macros, such as refresh() and mvadd_wchnstr(). Signed-off-by: Kang-Che Sung --- ProvideCurses.h | 4 ++++ configure.ac | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/ProvideCurses.h b/ProvideCurses.h index 7ae99e620..4594e3baf 100644 --- a/ProvideCurses.h +++ b/ProvideCurses.h @@ -8,7 +8,11 @@ in the source distribution for its full text. */ +// This header is also used in tests by configure, thus conditionally +// including "config.h". +#if defined(HAVE_CONFIG_H) #include "config.h" // IWYU pragma: keep +#endif // IWYU pragma: begin_exports diff --git a/configure.ac b/configure.ac index 2821474f5..a2130a152 100644 --- a/configure.ac +++ b/configure.ac @@ -666,6 +666,7 @@ esac htop_save_CFLAGS=$CFLAGS CFLAGS="$AM_CFLAGS $CFLAGS" + if test "x$enable_unicode" = xyes; then AC_CHECK_HEADERS([ncursesw/curses.h], [], [AC_CHECK_HEADERS([ncurses/ncurses.h], [], @@ -688,6 +689,31 @@ else [AC_CHECK_HEADERS([term.h], [], [AC_MSG_ERROR([can not find required term header file])])]) fi + +CFLAGS="-I$srcdir $CFLAGS" + +# Check for things that might be macros. +# "stdscr" is a macro in ncursest (reentrant version of ncurses). +AC_MSG_CHECKING([whether the curses header works]) +AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include "ProvideCurses.h" + ]], [[ +keypad(stdscr, 0); + +refresh(); + +#if defined(HAVE_LIBNCURSESW) +{ + static cchar_t dummy; + mvadd_wchnstr(0, 0, &dummy, 0); +} +#endif + ]])], + [AC_MSG_RESULT(yes)], + [AC_MSG_RESULT(no) + AC_MSG_FAILURE([there are problems with the curses header])] +) + CFLAGS=$htop_save_CFLAGS if test "$enable_static" = yes; then From a1f21759c0c9911af3bc1ccd5a1c894a2b266dea Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:30 +0800 Subject: [PATCH 08/10] build: Check curses "bool" type compatibility curses.h may define its own "bool" type, because the X/Open Curses standard defines "bool" that predates C99 "bool". If curses.h "bool" is not compatible with ISO C, fail at configure time. (The C23 standard now makes "bool" a keyword so that a "typedef /*whatever*/ bool;" is no longer portable. This is a bug that curses implementations should fix.) Solaris 11 is known to ship with a broken curses.h header (the default curses, not ncurses). Signed-off-by: Kang-Che Sung --- configure.ac | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index a2130a152..b20ff18fa 100644 --- a/configure.ac +++ b/configure.ac @@ -696,9 +696,12 @@ CFLAGS="-I$srcdir $CFLAGS" # "stdscr" is a macro in ncursest (reentrant version of ncurses). AC_MSG_CHECKING([whether the curses header works]) AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +/* Checks if the "bool" definition in curses is ISO C compatible */ +#include + #include "ProvideCurses.h" ]], [[ -keypad(stdscr, 0); +keypad(stdscr, false); refresh(); From 174c87d52b8a0fb13b4926ef1d06fae69fb87074 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:30 +0800 Subject: [PATCH 09/10] build: Improve "tinfo" library detection in configure Now it can guess the terminfo library name based on the ncurses library file name. E.g. "-ltinfow" for the corresponding"-lncursesw". If the guessed library name doesn't link, try the "-ltinfo" name then. Signed-off-by: Kang-Che Sung --- configure.ac | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/configure.ac b/configure.ac index b20ff18fa..42bb8a4e4 100644 --- a/configure.ac +++ b/configure.ac @@ -642,12 +642,20 @@ none-*|nonwide-yes) if htop_check_curses_capability "" "-l$curses_name"; then break fi - # For ncurses implementation, an extra "-ltinfo" or "-ltinfow" - # flag might be needed to link. - if test "x$enable_unicode" = xyes && - htop_check_curses_capability "" "-l$curses_name -ltinfow"; then - break - fi + # For ncurses implementation, an extra terminfo library might be + # needed. Guess the terminfo library name based on the ncurses + # library file name (e.g. "-ltinfow" for "-lncursesw"), before + # trying the "-ltinfo" name. + tinfo_name=`echo x$curses_name | sed 's/^xncurses/tinfo/p; d'` + case x$tinfo_name in + x|xtinfo) + ;; + *) + if htop_check_curses_capability "" "-l$curses_name -l$tinfo_name"; then + break + fi + ;; + esac if htop_check_curses_capability "" "-l$curses_name -ltinfo"; then break fi From 917eb579ee923c775215691f88c2a8bccd30e721 Mon Sep 17 00:00:00 2001 From: Explorer09 Date: Tue, 29 Oct 2024 07:59:30 +0800 Subject: [PATCH 10/10] build: Add "ncurses{t,tw}" to possible ncurses names "ncursest" and "ncursestw" are multi-threaded variants of the ncurses library. The "t" library names are only used in operating systems that do not support weak symbols (so you won't see such names in Linux), but the names are documented in ncurses anyway. Adding them to the list of names to check won't hurt. * See the curs_threads(3X) man page, and the INSTALL file from ncurses package. Notably the "--enable-reentrant", "--with-pthread" and "--enable-weak-symbols" options in ncurses. Signed-off-by: Kang-Che Sung --- configure.ac | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 42bb8a4e4..f4b48d0a4 100644 --- a/configure.ac +++ b/configure.ac @@ -416,10 +416,12 @@ AC_ARG_ENABLE([unicode], AC_ARG_VAR([CURSES_CFLAGS], [C compiler flags for curses; this overrides auto detected values]) AC_ARG_VAR([CURSES_LIBS], [linker flags for curses; this overrides auto detected values]) -curses_pkg_names="ncurses6 ncurses5 ncurses curses" +curses_pkg_names="ncurses6 ncurses5 ncurses ncursest6 ncursest5 \ + ncursest curses" if test "x$enable_unicode" = xyes; then - curses_pkg_names="ncursesw6 ncursesw5 ncursesw $curses_pkg_names" + curses_pkg_names="ncursesw6 ncursesw5 ncursesw ncursestw6 ncursestw5 \ + ncursestw $curses_pkg_names" fi AC_ARG_WITH([curses],