aboutsummaryrefslogtreecommitdiff
path: root/llvm
diff options
context:
space:
mode:
Diffstat (limited to 'llvm')
-rw-r--r--llvm/CMakeLists.txt2
-rw-r--r--llvm/cmake/config-ix.cmake10
-rw-r--r--llvm/cmake/modules/FindTerminfo.cmake55
-rw-r--r--llvm/cmake/modules/LLVMConfig.cmake.in5
-rw-r--r--llvm/docs/ReleaseNotes.rst4
-rw-r--r--llvm/include/llvm/Config/config.h.cmake3
-rw-r--r--llvm/lib/Support/CMakeLists.txt11
-rw-r--r--llvm/lib/Support/Unix/Process.inc60
-rw-r--r--llvm/utils/gn/README.rst2
-rw-r--r--llvm/utils/gn/build/libs/terminfo/BUILD.gn12
-rw-r--r--llvm/utils/gn/build/libs/terminfo/enable.gni4
-rw-r--r--llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn7
-rw-r--r--llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn1
-rw-r--r--llvm/utils/gn/secondary/llvm/tools/llvm-config/BUILD.gn6
14 files changed, 172 insertions, 10 deletions
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index 64898ab..cbf4db6 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -539,6 +539,8 @@ 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_TERMINFO "Use terminfo database if available." ON)
+
set(LLVM_ENABLE_LIBXML2 "ON" CACHE STRING "Use libxml2 if available. Can be ON, OFF, or FORCE_ON")
option(LLVM_ENABLE_LIBEDIT "Use libedit if available." ON)
diff --git a/llvm/cmake/config-ix.cmake b/llvm/cmake/config-ix.cmake
index 0aae13e..7d2a4933 100644
--- a/llvm/cmake/config-ix.cmake
+++ b/llvm/cmake/config-ix.cmake
@@ -240,11 +240,21 @@ if(NOT LLVM_USE_SANITIZER MATCHES "Memory.*")
else()
set(HAVE_LIBEDIT 0)
endif()
+ if(LLVM_ENABLE_TERMINFO)
+ if(LLVM_ENABLE_TERMINFO STREQUAL FORCE_ON)
+ find_package(Terminfo REQUIRED)
+ else()
+ find_package(Terminfo)
+ endif()
+ set(LLVM_ENABLE_TERMINFO "${Terminfo_FOUND}")
+ endif()
else()
set(HAVE_LIBEDIT 0)
+ set(LLVM_ENABLE_TERMINFO 0)
endif()
else()
set(HAVE_LIBEDIT 0)
+ set(LLVM_ENABLE_TERMINFO 0)
endif()
if(LLVM_HAS_LOGF128)
diff --git a/llvm/cmake/modules/FindTerminfo.cmake b/llvm/cmake/modules/FindTerminfo.cmake
new file mode 100644
index 0000000..163af66
--- /dev/null
+++ b/llvm/cmake/modules/FindTerminfo.cmake
@@ -0,0 +1,55 @@
+# Attempts to discover terminfo library with a linkable setupterm function.
+#
+# Example usage:
+#
+# find_package(Terminfo)
+#
+# If successful, the following variables will be defined:
+# Terminfo_FOUND
+# Terminfo_LIBRARIES
+#
+# Additionally, the following import target will be defined:
+# Terminfo::terminfo
+
+find_library(Terminfo_LIBRARIES NAMES terminfo tinfo curses ncurses ncursesw)
+
+if(Terminfo_LIBRARIES)
+ include(CMakePushCheckState)
+ cmake_push_check_state()
+ list(APPEND CMAKE_REQUIRED_LIBRARIES ${Terminfo_LIBRARIES})
+ set(Terminfo_LINKABLE_SRC [=[
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+ int setupterm(char *term, int filedes, int *errret);
+ #ifdef __cplusplus
+ }
+ #endif
+ int main(void) { return setupterm(0, 0, 0); }
+ ]=])
+ if(DEFINED CMAKE_C_COMPILER)
+ include(CheckCSourceCompiles)
+ check_c_source_compiles("${Terminfo_LINKABLE_SRC}" Terminfo_LINKABLE)
+ else()
+ include(CheckCXXSourceCompiles)
+ check_cxx_source_compiles("${Terminfo_LINKABLE_SRC}" Terminfo_LINKABLE)
+ endif()
+ cmake_pop_check_state()
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Terminfo
+ FOUND_VAR
+ Terminfo_FOUND
+ REQUIRED_VARS
+ Terminfo_LIBRARIES
+ Terminfo_LINKABLE)
+mark_as_advanced(Terminfo_LIBRARIES
+ Terminfo_LINKABLE)
+
+if(Terminfo_FOUND)
+ if(NOT TARGET Terminfo::terminfo)
+ add_library(Terminfo::terminfo UNKNOWN IMPORTED)
+ set_target_properties(Terminfo::terminfo PROPERTIES IMPORTED_LOCATION "${Terminfo_LIBRARIES}")
+ endif()
+endif()
diff --git a/llvm/cmake/modules/LLVMConfig.cmake.in b/llvm/cmake/modules/LLVMConfig.cmake.in
index 7e1501a..397bd581 100644
--- a/llvm/cmake/modules/LLVMConfig.cmake.in
+++ b/llvm/cmake/modules/LLVMConfig.cmake.in
@@ -60,6 +60,11 @@ if(LLVM_ENABLE_LIBEDIT)
find_package(LibEdit)
endif()
+set(LLVM_ENABLE_TERMINFO @LLVM_ENABLE_TERMINFO@)
+if(LLVM_ENABLE_TERMINFO)
+ find_package(Terminfo)
+endif()
+
set(LLVM_ENABLE_THREADS @LLVM_ENABLE_THREADS@)
set(LLVM_ENABLE_UNWIND_TABLES @LLVM_ENABLE_UNWIND_TABLES@)
diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst
index c7c2c282..1e1ccb4 100644
--- a/llvm/docs/ReleaseNotes.rst
+++ b/llvm/docs/ReleaseNotes.rst
@@ -63,10 +63,6 @@ Changes to LLVM infrastructure
Changes to building LLVM
------------------------
-- The ``LLVM_ENABLE_TERMINFO`` flag has been removed. LLVM no longer depends on
- terminfo and now always uses the ``TERM`` environment variable for color
- support autodetection.
-
Changes to TableGen
-------------------
diff --git a/llvm/include/llvm/Config/config.h.cmake b/llvm/include/llvm/Config/config.h.cmake
index ff30741..977c182 100644
--- a/llvm/include/llvm/Config/config.h.cmake
+++ b/llvm/include/llvm/Config/config.h.cmake
@@ -209,6 +209,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#cmakedefine HAVE_SYS_TYPES_H ${HAVE_SYS_TYPES_H}
+/* Define if the setupterm() function is supported this platform. */
+#cmakedefine LLVM_ENABLE_TERMINFO ${LLVM_ENABLE_TERMINFO}
+
/* Define to 1 if you have the <termios.h> header file. */
#cmakedefine HAVE_TERMIOS_H ${HAVE_TERMIOS_H}
diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt
index be4badc..03e8889 100644
--- a/llvm/lib/Support/CMakeLists.txt
+++ b/llvm/lib/Support/CMakeLists.txt
@@ -56,6 +56,9 @@ elseif( CMAKE_HOST_UNIX )
STRING(REGEX REPLACE "^lib" "" Backtrace_LIBFILE ${Backtrace_LIBFILE})
set(system_libs ${system_libs} ${Backtrace_LIBFILE})
endif()
+ if( LLVM_ENABLE_TERMINFO )
+ set(imported_libs ${imported_libs} Terminfo::terminfo)
+ endif()
set(system_libs ${system_libs} ${LLVM_ATOMIC_LIB})
set(system_libs ${system_libs} ${LLVM_PTHREAD_LIB})
if( UNIX AND NOT (BEOS OR HAIKU) )
@@ -322,6 +325,14 @@ if(LLVM_ENABLE_ZSTD)
set(llvm_system_libs ${llvm_system_libs} "${zstd_library}")
endif()
+if(LLVM_ENABLE_TERMINFO)
+ if(NOT terminfo_library)
+ get_property(terminfo_library TARGET Terminfo::terminfo PROPERTY LOCATION)
+ endif()
+ get_library_name(${terminfo_library} terminfo_library)
+ set(llvm_system_libs ${llvm_system_libs} "${terminfo_library}")
+endif()
+
set_property(TARGET LLVMSupport PROPERTY LLVM_SYSTEM_LIBS "${llvm_system_libs}")
diff --git a/llvm/lib/Support/Unix/Process.inc b/llvm/lib/Support/Unix/Process.inc
index 84b10ff..ae90924 100644
--- a/llvm/lib/Support/Unix/Process.inc
+++ b/llvm/lib/Support/Unix/Process.inc
@@ -341,9 +341,17 @@ unsigned Process::StandardErrColumns() {
return getColumns();
}
-static bool terminalHasColors() {
- // Check if the current terminal is one of terminals that are known to support
- // ANSI color escape codes.
+#ifdef LLVM_ENABLE_TERMINFO
+// We manually declare these extern functions because finding the correct
+// headers from various terminfo, curses, or other sources is harder than
+// writing their specs down.
+extern "C" int setupterm(char *term, int filedes, int *errret);
+extern "C" struct term *set_curterm(struct term *termp);
+extern "C" int del_curterm(struct term *termp);
+extern "C" int tigetnum(char *capname);
+#endif
+
+bool checkTerminalEnvironmentForColors() {
if (const char *TermStr = std::getenv("TERM")) {
return StringSwitch<bool>(TermStr)
.Case("ansi", true)
@@ -360,10 +368,54 @@ static bool terminalHasColors() {
return false;
}
+static bool terminalHasColors(int fd) {
+#ifdef LLVM_ENABLE_TERMINFO
+ // First, acquire a global lock because these C routines are thread hostile.
+ static std::mutex TermColorMutex;
+ std::lock_guard<std::mutex> G(TermColorMutex);
+
+ struct term *previous_term = set_curterm(nullptr);
+ int errret = 0;
+ if (setupterm(nullptr, fd, &errret) != 0)
+ // Regardless of why, if we can't get terminfo, we shouldn't try to print
+ // colors.
+ return false;
+
+ // 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.
+ int colors_ti = tigetnum(const_cast<char *>("colors"));
+ bool HasColors =
+ colors_ti >= 0 ? colors_ti : checkTerminalEnvironmentForColors();
+
+ // Now extract the structure allocated by setupterm and free its memory
+ // through a really silly dance.
+ struct term *termp = set_curterm(previous_term);
+ (void)del_curterm(termp); // Drop any errors here.
+
+ // Return true if we found a color capabilities for the current terminal.
+ return HasColors;
+#else
+ // When the terminfo database is not available, check if the current terminal
+ // is one of terminals that are known to support ANSI color escape codes.
+ return checkTerminalEnvironmentForColors();
+#endif
+}
+
bool Process::FileDescriptorHasColors(int fd) {
// A file descriptor has colors if it is displayed and the terminal has
// colors.
- return FileDescriptorIsDisplayed(fd) && terminalHasColors();
+ return FileDescriptorIsDisplayed(fd) && terminalHasColors(fd);
}
bool Process::StandardOutHasColors() {
diff --git a/llvm/utils/gn/README.rst b/llvm/utils/gn/README.rst
index 52d03be..9ca5450 100644
--- a/llvm/utils/gn/README.rst
+++ b/llvm/utils/gn/README.rst
@@ -131,7 +131,7 @@ configure is used for three classes of feature checks:
For the last two points, it would be nice if LLVM didn't have a single
``config.h`` header, but one header per toggle. That way, when e.g.
-``llvm_enable_zlib`` is toggled, only the 3 files caring about that setting
+``llvm_enable_terminfo`` is toggled, only the 3 files caring about that setting
would need to be rebuilt, instead of everything including ``config.h``.
GN doesn't believe in users setting arbitrary cflags from an environment
diff --git a/llvm/utils/gn/build/libs/terminfo/BUILD.gn b/llvm/utils/gn/build/libs/terminfo/BUILD.gn
new file mode 100644
index 0000000..10003d6
--- /dev/null
+++ b/llvm/utils/gn/build/libs/terminfo/BUILD.gn
@@ -0,0 +1,12 @@
+import("//llvm/utils/gn/build/libs/terminfo/enable.gni")
+
+config("terminfo_config") {
+ visibility = [ ":terminfo" ]
+ libs = [ "ncurses" ]
+}
+
+group("terminfo") {
+ if (llvm_enable_terminfo) {
+ public_configs = [ ":terminfo_config" ]
+ }
+}
diff --git a/llvm/utils/gn/build/libs/terminfo/enable.gni b/llvm/utils/gn/build/libs/terminfo/enable.gni
new file mode 100644
index 0000000..79ea2b6
--- /dev/null
+++ b/llvm/utils/gn/build/libs/terminfo/enable.gni
@@ -0,0 +1,4 @@
+declare_args() {
+ # Whether to link against terminfo.
+ llvm_enable_terminfo = false
+}
diff --git a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
index d8266fe..2da26d1 100644
--- a/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/include/llvm/Config/BUILD.gn
@@ -10,6 +10,7 @@ import("//llvm/utils/gn/build/buildflags.gni")
import("//llvm/utils/gn/build/libs/curl/enable.gni")
import("//llvm/utils/gn/build/libs/edit/enable.gni")
import("//llvm/utils/gn/build/libs/pthread/enable.gni")
+import("//llvm/utils/gn/build/libs/terminfo/enable.gni")
import("//llvm/utils/gn/build/libs/xar/enable.gni")
import("//llvm/utils/gn/build/libs/xml/enable.gni")
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
@@ -293,6 +294,12 @@ write_cmake_config("config") {
values += [ "HAVE_LIBEDIT=" ]
}
+ if (llvm_enable_terminfo) {
+ values += [ "LLVM_ENABLE_TERMINFO=1" ]
+ } else {
+ values += [ "LLVM_ENABLE_TERMINFO=" ]
+ }
+
if (llvm_enable_libxml2) {
values += [ "LLVM_ENABLE_LIBXML2=1" ]
} else {
diff --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
index 7728455..941d448 100644
--- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn
@@ -6,6 +6,7 @@ static_library("Support") {
"//llvm/include/llvm/Support:write_vcsrevision",
"//llvm/lib/Demangle",
"//llvm/utils/gn/build/libs/pthread",
+ "//llvm/utils/gn/build/libs/terminfo",
"//llvm/utils/gn/build/libs/zlib",
]
diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-config/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-config/BUILD.gn
index 711e4e3..bf50cd0f 100644
--- a/llvm/utils/gn/secondary/llvm/tools/llvm-config/BUILD.gn
+++ b/llvm/utils/gn/secondary/llvm/tools/llvm-config/BUILD.gn
@@ -1,6 +1,7 @@
import("//llvm/lib/Target/targets_string.gni")
import("//llvm/utils/gn/build/buildflags.gni")
import("//llvm/utils/gn/build/libs/pthread/enable.gni")
+import("//llvm/utils/gn/build/libs/terminfo/enable.gni")
import("//llvm/utils/gn/build/libs/xml/enable.gni")
import("//llvm/utils/gn/build/libs/zlib/enable.gni")
import("//llvm/utils/gn/build/write_cmake_config.gni")
@@ -35,7 +36,7 @@ write_cmake_config("BuildVariables.inc") {
lib = ""
}
- # Windows doesn't use any of libxml2, zlib by default.
+ # Windows doesn't use any of libxml2, terminfo, zlib by default.
# Make GN not warn about these variables being unused.
not_needed([
"l",
@@ -62,6 +63,9 @@ write_cmake_config("BuildVariables.inc") {
if (llvm_enable_libxml2) {
system_libs += " ${l}xml2${lib}"
}
+ if (llvm_enable_terminfo) {
+ system_libs += " ${l}ncurses${lib}"
+ }
if (llvm_enable_zlib) {
system_libs += " ${l}z${lib}"
}