Target a minimal terminfo library rather than necessarily a full curses

library for color support detection. This still will use a curses
library if that is all we have available on the system. This change
tries to use a smaller subset of the curses library, specifically the
subset that is on some systems split off into a separate library. For
example, if you install ncurses configured --with-tinfo, a 'libtinfo' is
install that provides just the terminfo querying functionality. That
library is now used instead of curses when it is available.

This happens to fix a build error on systems with that library because
when we tried to link ncurses into the binary, we didn't pull tinfo in
as well. =]

It should also provide an easy path for supporting the NetBSD
libterminfo library, but as I don't have access to a NetBSD system I'm
leaving adding that support to those folks.

llvm-svn: 188160
This commit is contained in:
Chandler Carruth 2013-08-12 09:49:17 +00:00
parent 707d68f082
commit f11f1e43de
9 changed files with 100 additions and 80 deletions

View File

@ -123,7 +123,7 @@ set(FFI_INCLUDE_DIR "" CACHE PATH "Additional directory, where CMake should sear
set(LLVM_TARGET_ARCH "host"
CACHE STRING "Set target to use for LLVM JIT or use \"host\" for automatic detection.")
option(LLVM_ENABLE_CURSES "Use curses to detect terminal info if available." ON)
option(LLVM_ENABLE_TERMINFO "Use terminfo database if available." ON)
option(LLVM_ENABLE_THREADS "Use threads if available." ON)

View File

@ -1072,16 +1072,16 @@ AC_ARG_WITH(bug-report-url,
AC_DEFINE_UNQUOTED(BUG_REPORT_URL,"$withval",
[Bug report URL.])
dnl --enable-curses: check whether the user wants to control use of curses:
AC_ARG_ENABLE(curses,AS_HELP_STRING(
[--enable-curses],
[Use curses for querying terminal infomation if available (default is YES)]),
dnl --enable-terminfo: check whether the user wants to control use of terminfo:
AC_ARG_ENABLE(terminfo,AS_HELP_STRING(
[--enable-terminfo],
[Query the terminfo database if available (default is YES)]),
[case "$enableval" in
yes) llvm_cv_enable_curses="yes" ;;
no) llvm_cv_enable_curses="no" ;;
*) AC_MSG_ERROR([Invalid setting for --enable-curses. Use "yes" or "no"]) ;;
yes) llvm_cv_enable_terminfo="yes" ;;
no) llvm_cv_enable_terminfo="no" ;;
*) AC_MSG_ERROR([Invalid setting for --enable-terminfo. Use "yes" or "no"]) ;;
esac],
llvm_cv_enable_curses="yes")
llvm_cv_enable_terminfo="yes")
dnl --enable-libffi : check whether the user wants to turn off libffi:
AC_ARG_ENABLE(libffi,AS_HELP_STRING(
@ -1390,11 +1390,11 @@ dnl right libraries to link with.
AC_SEARCH_LIBS(clock_gettime,rt)
dnl The curses library is optional; used for querying terminal info
if test "$llvm_cv_enable_curses" = "yes" ; then
if test "$llvm_cv_enable_terminfo" = "yes" ; then
dnl We need the has_color functionality in curses for it to be useful.
AC_SEARCH_LIBS(has_colors,curses ncurses ncursesw,
AC_DEFINE([HAVE_CURSES],[1],
[Define if curses provides the has_color() function on this platform.]))
AC_SEARCH_LIBS(setupterm,tinfo curses ncurses ncursesw,
AC_DEFINE([HAVE_TERMINFO],[1],
[Define if the setupterm() function is supported this platform.]))
fi
dnl libffi is optional; used to call external functions from the interpreter
@ -1574,8 +1574,8 @@ else
fi
dnl Try to find a suitable curses header.
if test "$llvm_cv_enable_curses" = "yes" ; then
AC_CHECK_HEADERS([curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h])
if test "$llvm_cv_enable_terminfo" = "yes" ; then
AC_CHECK_HEADERS([term.h curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h])
fi
dnl Try to find ffi.h.

View File

@ -74,6 +74,7 @@ check_symbol_exists(FE_INEXACT "fenv.h" HAVE_DECL_FE_INEXACT)
check_include_file(mach/mach.h HAVE_MACH_MACH_H)
check_include_file(mach-o/dyld.h HAVE_MACH_O_DYLD_H)
check_include_file(term.h HAVE_TERM_H)
check_include_file(curses.h HAVE_CURSES_H)
check_include_file(ncurses.h HAVE_NCURSES_H)
check_include_file(ncursesw.h HAVE_NCURSESW_H)
@ -103,18 +104,21 @@ if( NOT PURE_WINDOWS )
else()
set(HAVE_LIBZ 0)
endif()
if(LLVM_ENABLE_CURSES)
check_library_exists(curses has_colors "" HAVE_CURSES)
if(NOT HAVE_CURSES)
check_library_exists(ncurses has_colors "" HAVE_NCURSES)
set(HAVE_CURSES ${HAVE_NCURSES})
if(NOT HAVE_CURSES)
check_library_exists(ncursesw has_colors "" HAVE_NCURSESW)
set(HAVE_CURSES ${HAVE_NCURSESW})
if(LLVM_ENABLE_TERMINFO AND
(HAVE_TERM_H OR HAVE_CURSES_H OR HAVE_NCURSES_H OR HAVE_NCURSESW_H OR
HAVE_NCURSES_CURSES_H OR HAVE_NCURSESW_CURSES_H))
set(HAVE_TERMINFO 0)
foreach(library tinfo curses ncurses ncursesw)
string(TOUPPER ${library} library_suffix)
check_library_exists(${library} setupterm "" HAVE_TERMINFO_${library_suffix})
if(HAVE_TERMINFO_${library_suffix})
set(HAVE_TERMINFO 1)
set(TERMINFO_LIBS "${library}")
break()
endif()
endif()
endforeach()
else()
set(HAVE_CURSES 0)
set(HAVE_TERMINFO 0)
endif()
endif()

View File

@ -10,13 +10,9 @@ function(get_system_libs return_var)
if( HAVE_LIBDL )
set(system_libs ${system_libs} ${CMAKE_DL_LIBS})
endif()
if(LLVM_ENABLE_CURSES)
if(HAVE_NCURSESW)
set(system_libs ${system_libs} ncursesw)
elseif(HAVE_NCURSES)
set(system_libs ${system_libs} ncurses)
elseif(HAVE_CURSES)
set(system_libs ${system_libs} curses)
if(LLVM_ENABLE_TERMINFO)
if(HAVE_TERMINFO)
set(system_libs ${system_libs} ${TERMINFO_LIBS})
endif()
endif()
if( LLVM_ENABLE_THREADS AND HAVE_LIBPTHREAD )

View File

@ -20,7 +20,7 @@ set(TARGET_TRIPLE "@TARGET_TRIPLE@")
set(LLVM_TOOLS_BINARY_DIR @LLVM_TOOLS_BINARY_DIR@)
set(LLVM_ENABLE_CURSES @LLVM_ENABLE_CURSES@)
set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@)
set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)
@ -30,9 +30,8 @@ set(LLVM_NATIVE_ARCH @LLVM_NATIVE_ARCH@)
set(LLVM_ENABLE_PIC @LLVM_ENABLE_PIC@)
set(HAVE_CURSES @HAVE_CURSES@)
set(HAVE_NCURSES @HAVE_NCURSES@)
set(HAVE_NCURSESW @HAVE_NCURSESW@)
set(HAVE_TERMINFO @HAVE_TERMINFO@)
set(TERMINFO_LIBS @TERMINFO_LIBS@)
set(HAVE_LIBDL @HAVE_LIBDL@)
set(HAVE_LIBPTHREAD @HAVE_LIBPTHREAD@)
set(HAVE_LIBZ @HAVE_LIBZ@)

55
llvm/configure vendored
View File

@ -1453,8 +1453,8 @@ Optional Features:
target1,target2,... (default=disable)
--enable-bindings Build specific language bindings:
all,auto,none,{binding-name} (default=auto)
--enable-curses Use curses for querying terminal infomation if
available (default is YES)
--enable-terminfo Query the terminfo database if available (default is
YES)
--enable-libffi Check for the presence of libffi (default is NO)
--enable-ltdl-install install libltdl
@ -6006,17 +6006,17 @@ cat >>confdefs.h <<_ACEOF
_ACEOF
# Check whether --enable-curses was given.
if test "${enable_curses+set}" = set; then
enableval=$enable_curses; case "$enableval" in
yes) llvm_cv_enable_curses="yes" ;;
no) llvm_cv_enable_curses="no" ;;
*) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-curses. Use \"yes\" or \"no\"" >&5
echo "$as_me: error: Invalid setting for --enable-curses. Use \"yes\" or \"no\"" >&2;}
# Check whether --enable-terminfo was given.
if test "${enable_terminfo+set}" = set; then
enableval=$enable_terminfo; case "$enableval" in
yes) llvm_cv_enable_terminfo="yes" ;;
no) llvm_cv_enable_terminfo="no" ;;
*) { { echo "$as_me:$LINENO: error: Invalid setting for --enable-terminfo. Use \"yes\" or \"no\"" >&5
echo "$as_me: error: Invalid setting for --enable-terminfo. Use \"yes\" or \"no\"" >&2;}
{ (exit 1); exit 1; }; } ;;
esac
else
llvm_cv_enable_curses="yes"
llvm_cv_enable_terminfo="yes"
fi
@ -12268,10 +12268,10 @@ if test "$ac_res" != no; then
fi
if test "$llvm_cv_enable_curses" = "yes" ; then
{ echo "$as_me:$LINENO: checking for library containing has_colors" >&5
echo $ECHO_N "checking for library containing has_colors... $ECHO_C" >&6; }
if test "${ac_cv_search_has_colors+set}" = set; then
if test "$llvm_cv_enable_terminfo" = "yes" ; then
{ echo "$as_me:$LINENO: checking for library containing setupterm" >&5
echo $ECHO_N "checking for library containing setupterm... $ECHO_C" >&6; }
if test "${ac_cv_search_setupterm+set}" = set; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
ac_func_search_save_LIBS=$LIBS
@ -12288,16 +12288,16 @@ cat >>conftest.$ac_ext <<_ACEOF
#ifdef __cplusplus
extern "C"
#endif
char has_colors ();
char setupterm ();
int
main ()
{
return has_colors ();
return setupterm ();
;
return 0;
}
_ACEOF
for ac_lib in '' curses ncurses ncursesw; do
for ac_lib in '' tinfo curses ncurses ncursesw; do
if test -z "$ac_lib"; then
ac_res="none required"
else
@ -12338,7 +12338,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
ac_status=$?
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); }; }; then
ac_cv_search_has_colors=$ac_res
ac_cv_search_setupterm=$ac_res
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
@ -12348,26 +12348,26 @@ fi
rm -f core conftest.err conftest.$ac_objext \
conftest$ac_exeext
if test "${ac_cv_search_has_colors+set}" = set; then
if test "${ac_cv_search_setupterm+set}" = set; then
break
fi
done
if test "${ac_cv_search_has_colors+set}" = set; then
if test "${ac_cv_search_setupterm+set}" = set; then
:
else
ac_cv_search_has_colors=no
ac_cv_search_setupterm=no
fi
rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
{ echo "$as_me:$LINENO: result: $ac_cv_search_has_colors" >&5
echo "${ECHO_T}$ac_cv_search_has_colors" >&6; }
ac_res=$ac_cv_search_has_colors
{ echo "$as_me:$LINENO: result: $ac_cv_search_setupterm" >&5
echo "${ECHO_T}$ac_cv_search_setupterm" >&6; }
ac_res=$ac_cv_search_setupterm
if test "$ac_res" != no; then
test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
cat >>confdefs.h <<\_ACEOF
#define HAVE_CURSES 1
#define HAVE_TERMINFO 1
_ACEOF
fi
@ -16543,13 +16543,14 @@ else
fi
if test "$llvm_cv_enable_curses" = "yes" ; then
if test "$llvm_cv_enable_terminfo" = "yes" ; then
for ac_header in curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h
for ac_header in term.h curses.h ncurses.h ncursesw.h ncurses/curses.h ncursesw/curses.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then

View File

@ -48,9 +48,6 @@
/* Define to 1 if you have the `closedir' function. */
#cmakedefine HAVE_CLOSEDIR ${HAVE_CLOSEDIR}
/* Define if curses provides the has_color() function on this platform. */
#cmakedefine HAVE_CURSES
/* Define to 1 if you have the <curses.h> header file. */
#cmakedefine HAVE_CURSES_H
@ -420,9 +417,15 @@
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#cmakedefine HAVE_SYS_WAIT_H ${HAVE_SYS_WAIT_H}
/* Define if the setupterm() function is supported this platform. */
#cmakedefine HAVE_TERMINFO ${HAVE_TERMINFO}
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
/* Define to 1 if you have the <term.h> header file. */
#cmakedefine HAVE_TERM_H
/* Define if the neat program is available */
#cmakedefine HAVE_TWOPI ${HAVE_TWOPI}

View File

@ -69,9 +69,6 @@
/* can use __crashreporter_info__ */
#undef HAVE_CRASHREPORTER_INFO
/* Define if curses provides the has_color() function on this platform. */
#undef HAVE_CURSES
/* Define to 1 if you have the <curses.h> header file. */
#undef HAVE_CURSES_H
@ -455,9 +452,15 @@
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#undef HAVE_SYS_WAIT_H
/* Define if the setupterm() function is supported this platform. */
#undef HAVE_TERMINFO
/* Define to 1 if you have the <termios.h> header file. */
#undef HAVE_TERMIOS_H
/* Define to 1 if you have the <term.h> header file. */
#undef HAVE_TERM_H
/* Define if the neat program is available */
#undef HAVE_TWOPI

View File

@ -38,9 +38,12 @@
# include <termios.h>
#endif
// See if we can use curses to detect information about a terminal when
// connected to one.
#ifdef HAVE_CURSES
// Pull in the headers we found to go with the terminfo reading library (tinfo,
// curses, whatever it may be). We have to pull in the 'curses.h' header as the
// SysV spec only provides certain values and defines from that header even
// though we work hard to not link against all of the curses implementation
// when avoidable.
#ifdef HAVE_TERMINFO
# if defined(HAVE_CURSES_H)
# include <curses.h>
# elif defined(HAVE_NCURSES_H)
@ -51,10 +54,10 @@
# include <ncurses/curses.h>
# elif defined(HAVE_NCURSESW_CURSES_H)
# include <ncursesw/curses.h>
# else
# error Have a curses library but unable to find a curses header!
# endif
# include <term.h>
# if defined(HAVE_TERM_H)
# include <term.h>
# endif
#endif
//===----------------------------------------------------------------------===//
@ -267,9 +270,8 @@ unsigned Process::StandardErrColumns() {
}
static bool terminalHasColors(int fd) {
#ifdef HAVE_CURSES
// First, acquire a global lock because the curses C routines are thread
// hostile.
#ifdef HAVE_TERMINFO
// First, acquire a global lock because these C routines are thread hostile.
static sys::Mutex M;
MutexGuard G(M);
@ -279,8 +281,20 @@ static bool terminalHasColors(int fd) {
// colors.
return false;
// Test whether the terminal as set up supports color output.
if (has_colors() == TRUE)
// Test whether the terminal as set up supports color output. How to do this
// isn't entirely obvious. We can use the curses routine 'has_colors' but it
// would be nice to avoid a dependency on curses proper when we can make do
// with a minimal terminfo parsing library. Also, we don't really care whether
// the terminal supports the curses-specific color changing routines, merely
// if it will interpret ANSI color escape codes in a reasonable way. Thus, the
// strategy here is just to query the baseline colors capability and if it
// supports colors at all to assume it will translate the escape codes into
// whatever range of colors it does support. We can add more detailed tests
// here if users report them as necessary.
//
// The 'tigetnum' routine returns -2 or -1 on errors, and might return 0 if
// the terminfo says that no colors are supported.
if (tigetnum("colors") > 0)
return true;
#endif